-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Added the ability to redirect logging to a callable. #6244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
a544354 to
9eb28fc
Compare
|
@mvieth do you have any idea to why there is linker errors with pcl::octree:OctreeKey::maxDepth ? |
Must have something to do with the usage of |
|
Ahh, its in that print statement it fails... hmm, still odd though. |
6d1d0a4 to
44320b0
Compare
|
Maybe pcl::console::LogRecorder should be a member of the Logger, to avoid creating a stringstream for each stream command - would that make sense? |
05b6bfa to
a376418
Compare
|
Nice for me, even if I not like too much the following: pcl::console::Logger::getInstance().setCallback(...)because of the Moreover, I think that the previous callback needs to be returned from the |
Somehow the callback needs to be saved - and having just a static global variable to a std::function, didn't seem right either. At least it was the best solution I found, also browsing other logging frameworks. |
| return instance; | ||
| } | ||
|
|
||
| //////////////////////////////////////////////////////////////////////////////// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
template <typename Functor>
void pcl::console::Logger::setCallback(Functor&& callback){
getInstance().setCallback(std::move(callback));
}DISCLAIMER: draft, untested code.
@larshg wouldn't this work? Would the template be a problem there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want a free function like:
template <typename Functor>
void
setCallback(Functor&& callback)
{
Logger::getInstance().setCallback(std::move(callback));
}
so you can call:
pcl::console::setCallback(...);
Yes, thats possible.
|
Moreover, why generic template "functor" instead of |
|
Else I couldn't get it to work with lambdas - but maybe I did it wrong 😄 |
|
To restore normal logging again, you can just set the callback to a nullptr. |
|
I had a quick look and it looks promising to me, thanks for your work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we are targeting PCL 1.16.0, due to likely ABI changes?
Is there a way to easily reset to the default behaviour, after calling setCallback? Edit: I just read your other comment: set callback to a nullptr. Please document this in the code somewhere.
448c188 to
746959d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds the ability to redirect PCL logging to a callable function, which addresses the need for programmatic access to logging output rather than just console printing. This change allows users to capture and handle log messages in custom ways.
- Introduces a callback-based logging system with LogRecord structure
- Refactors existing print functions to use templates and std::string instead of C-style variadic arguments
- Replaces deprecated static member variables with static getter functions
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| common/include/pcl/console/print.h | Adds Logger class with callback support and converts print functions to templates |
| common/src/print.cpp | Implements Logger singleton and callback-based printing logic |
| test/common/test_console.cpp | New test file for validating logging functionality and callback behavior |
| test/common/CMakeLists.txt | Adds test registration for console testing |
| sample_consensus/include/pcl/sample_consensus/sac_model.h | Replaces deprecated static member with getter function |
| octree/include/pcl/octree/octree_key.h | Replaces deprecated static member with getter function |
| octree/include/pcl/octree/impl/octree_pointcloud.hpp | Updates to use new getter function |
| octree/include/pcl/octree/impl/octree_base.hpp | Updates to use new getter function and adds missing includes |
| octree/include/pcl/octree/impl/octree2buf_base.hpp | Updates to use new getter function |
| octree/src/octree_inst.cpp | Adds missing include for octree_key.h |
| octree/include/pcl/octree/octree_impl.h | Removes redundant include |
| tools/train_linemod_template.cpp | Updates print calls to use std::string instead of .c_str() |
| examples/segmentation/example_lccp_segmentation.cpp | Simplifies logging by removing stringstream usage |
| examples/segmentation/example_cpc_segmentation.cpp | Simplifies logging by removing stringstream usage |
…t logging to console
3169df7 to
1f224bc
Compare
1f224bc to
1186310
Compare
mvieth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay, here is another round of review comments. I will try to further analyze, where string copying and allocations happen, as soon as I can.
| std::string message; | ||
| }; | ||
|
|
||
| class LogRecorder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add some documentation to this class? E.g. what is the purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, is there any benefit in having the LogRecorder class? Why not use std::stringstream directly?
|
|
||
| class LogRecorder { | ||
| public: | ||
| LogRecorder(std::string& string) : strstream(string) { } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps it makes sense to have a default value (""), or add an additional constructor without any parameter?
| PCL_EXPORTS void | ||
| print_color (FILE *stream, int attr, int fg, const char *format, ...); | ||
|
|
||
| class PCL_EXPORTS Logger { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation, e.g. what is the purpose of this class?
| L_VERBOSE | ||
| }; | ||
|
|
||
| struct LogRecord { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it makes sense to add a constructor where one can move a string in? Something like LogRecord(VERBOSITY_LEVEL lvl, std::string&& str)? Could be useful in the other methods to avoid copying
| void | ||
| print(VERBOSITY_LEVEL level, const std::string format, Args&&... args) | ||
| { | ||
| const auto str = to_string(format, std::forward<Args>(args)...); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it make sense to test isVerbosityLevelEnabled before calling the potentially expensive to_string?
| if(pcl::console::isVerbosityLevelEnabled(pcl::console::LEVEL)) \ | ||
| { \ | ||
| pcl::console::LogRecord entry{pcl::console::LEVEL, ""}; \ | ||
| pcl::console::LogRecorder rec(entry.message); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not work currently, changes to rec do not modify entry
I'm in deep water here, but it seems to work :)
Please come with suggestions, before spent too much time in the wrong way.
Could close #5589