/rosout logging without a node?
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 805
- Forks
- 564
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 27
Description
I'm trying to get /rosout working for MoveIt 2. At the last TSC meeting, I remember it being said that there might be a way to get /rosout logging working without a node. I'm here asking about that and providing the context of what I've tried to get logging working in ROS 1 as it did in ROS 2 for us. Here are my goals.
- logs publish to
/rosout - namespaced loggers that can have different log levels configured
- no large API changes (like adding a Node or Logger parameter to every constructor or free function)
- working on humble, iron, and rolling with a source build of our main branch
Just the root node logger
To get around changing the API everywhere to take a Node I started with the idea that the logger could be stored in a static variable in a function and accessed through the return value of that function. Something like this is where I started:
rclcpp::Logger& moveit::get_logger() {
static auto logger = rclcpp::make_logger("moveit");
return logger;
}
Then wherever (usually in a main) a Node was created someone would then set the global logger:
auto node = std::make_shared<rclcpp::Node>("move_group");
moveit::get_logger() = node->get_logger();
Then everyone who wants to use it can just use that logger in their macro calls:
RCLCPP_WARN(moveit::get_logger(), "something went wrong, please help");
This works, but is short of the goal of namespaces.
Try 1: Child loggers (member variables?)
To support child loggers I started with the idea that classes could create child loggers for themselves. I'd put something like this in the initializer list of the class:
, logger_(moveit::get_logger().get_child("fanuc_kdl_singular"))
This leads to the first problem:
[test_kinematics_plugin-1] [WARN] [1698723864.357328121] [rcl.logging_rosout]: Publisher
already registered for node name: 'test_kinematics_plugin.fanuc_kdl_singular'. If this is
due to multiple nodes with the same name, then all logs for the logger named
'test_kinematics_plugin.fanuc_kdl_singular' will go out over the existing publisher. As soon
as any node with that name is destructed, it will unregister the publisher, preventing any
further logs for that name from being published on the rosout topic.
Note that this is on rolling, I know that using
get_childon humble does not make a logger that publishes to/rosout. That is a sacrifice I'm willing to make.
This means that I can only have one of each child logger name in my program. So then we come to my second solution.
Try 2: Child loggers as more function statics (works with free functions?)
As a result of the above warning and the need to log from inside free functions, I came up with another pattern.
// in moveit_utils library
rclcpp::Logger& get_logger() {
static auto logger = rclcpp::get_logger("moveit");
return logger;
}
// anonymous namespace at top of single cpp file
// delay creating the child until the first time some code in this file tries to log
rclcpp::Logger get_logger()
{
static auto logger = moveit::get_logger().get_child("fanuc_kdl_singular");
return logger;
}
This delays the creation of the child logger until the first time get_child_logger is called. But it results in a new problem. My tests crash after main in the clean-up of this new logger.
I created an issue here with an example and stack trace: https://robotics.stackexchange.com/questions/105110/exception-thrown-in-rcl-logging-rosout-remove-sublogger-on-destruction-with-a-ch/105114#105114
@jrutgeer kindly responded with an explanation about what is happening and a fix to make the node itself have a static lifetime. Is this what people who use /rosout logging and child loggers are doing normally?
Am I crazy?
Am I off with what I'm trying to do here, and there is some better way I'm just not seeing?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the rclcpp::Logger APIs shown in the issue, especially make_logger, get_logger, get_child, and the rosout publisher behavior. Review the linked crash report and the reported cleanup failure before deciding whether node-independent logging and child logger lifetimes are supported. Done would require an agreed design and documented behavior across Humble, Iron, and Rolling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100