moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
logger.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2023, PickNik Robotics Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Tyler Weaver */
36
37#include <rclcpp/rclcpp.hpp>
39#include <string>
40#include <rsl/random.hpp>
41#include <fmt/format.h>
42#include "logger_detail.hpp"
43
44namespace moveit
45{
46
47// This is the function that stores the global logger used by moveit.
48// As it returns a reference to the static logger it can be changed through the
49// `setNodeLoggerName` function.
50rclcpp::Logger& getGlobalRootLogger()
51{
52 static rclcpp::Logger logger = [&] {
53 // A random number is appended to the name used for the node to make it unique.
54 // This unique node and logger name is only used if a user does not set a logger
55 // through the `setNodeLoggerName` method to their node's logger.
56 auto name = fmt::format("moveit_{}", rsl::rng()());
57 try
58 {
59 static rclcpp::Node::SharedPtr moveit_node = rclcpp::Node::make_shared(name);
60 static std::shared_ptr<std::mutex> s_mutex = detail::registerNodeResetOnPreShutdown(moveit_node);
61
62 // The pre-shutdown callback registered above can run concurrently on
63 // another thread as soon as it's registered (e.g. if rclcpp::shutdown()
64 // races with this, the very first, call to getGlobalRootLogger()), and
65 // may reset moveit_node to null. Lock the same mutex the callback locks
66 // before reading moveit_node, so the read and the reset can't race.
67 std::lock_guard<std::mutex> lock(*s_mutex);
68 if (moveit_node)
69 {
70 return moveit_node->get_logger();
71 }
72 // Shutdown's pre-shutdown callback already reset the node: fall back to
73 // a plain, non-node logger instead of dereferencing a destroyed node.
74 return rclcpp::get_logger(name);
75 }
76 catch (const std::exception& ex)
77 {
78 // rclcpp::init was not called so rcl context is null, return non-node logger
79 auto logger = rclcpp::get_logger(name);
80 RCLCPP_WARN_STREAM(logger, "exception thrown while creating node for logging: " << ex.what());
81 RCLCPP_WARN(logger, "if rclcpp::init was not called, messages from this logger may be missing from /rosout");
82 return logger;
83 }
84 }();
85 return logger;
86}
87
88void setNodeLoggerName(const std::string& name)
89{
90 static rclcpp::Node::SharedPtr s_node = std::make_shared<rclcpp::Node>("moveit", name);
91 static std::shared_ptr<std::mutex> s_mutex = detail::registerNodeResetOnPreShutdown(s_node);
92
93 std::lock_guard<std::mutex> lock(*s_mutex);
94 if (s_node)
95 {
96 getGlobalRootLogger() = s_node->get_logger();
97 }
98 // If the node has already been reset by a pre-shutdown callback from an
99 // earlier rclcpp::shutdown(), leave the global logger untouched rather
100 // than dereferencing a destroyed node. The previously assigned Logger
101 // remains valid: rclcpp::Logger owns its logger-name state independently
102 // and does not retain a reference to the Node, so destroying the Node
103 // does not invalidate the Logger.
104}
105
106rclcpp::Logger getLogger(const std::string& name)
107{
108 return getGlobalRootLogger().get_child(name);
109}
110
111} // namespace moveit
std::shared_ptr< std::mutex > registerNodeResetOnPreShutdown(rclcpp::Node::SharedPtr &node)
Main namespace for MoveIt.
void setNodeLoggerName(const std::string &name)
Call once after creating a node to initialize logging namespaces.
Definition logger.cpp:88
rclcpp::Logger & getGlobalRootLogger()
Definition logger.cpp:50