ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
ROS 2 C++ Client Library with ROS Client Library
logger.cpp
1 // Copyright 2017 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <filesystem>
16 #include <memory>
17 #include <string>
18 #include <utility>
19 
20 #include "rcl_logging_interface/rcl_logging_interface.h"
21 #include "rcl/error_handling.h"
22 #include "rcl/logging_rosout.h"
23 
24 #include "rclcpp/exceptions.hpp"
25 #include "rclcpp/logger.hpp"
26 #include "rclcpp/logging.hpp"
27 
28 #include "./logging_mutex.hpp"
29 
30 namespace rclcpp
31 {
32 
33 Logger
34 get_logger(const std::string & name)
35 {
36 #if RCLCPP_LOGGING_ENABLED
37  return rclcpp::Logger(name);
38 #else
39  (void)name;
40  return rclcpp::Logger();
41 #endif
42 }
43 
44 Logger
46 {
47  const char * logger_name = rcl_node_get_logger_name(node);
48  if (nullptr == logger_name) {
49  auto logger = rclcpp::get_logger("rclcpp");
50  RCLCPP_ERROR(
51  logger, "failed to get logger name from node at address %p",
52  static_cast<void *>(const_cast<rcl_node_t *>(node)));
53  return logger;
54  }
55  return rclcpp::get_logger(logger_name);
56 }
57 
58 std::filesystem::path
60 {
61  char * log_dir = NULL;
62  auto allocator = rcutils_get_default_allocator();
63  rcl_logging_ret_t ret = rcl_logging_get_logging_directory(allocator, &log_dir);
64  if (RCL_LOGGING_RET_OK != ret) {
65  rclcpp::exceptions::throw_from_rcl_error(ret);
66  }
67  std::string path{log_dir};
68  allocator.deallocate(log_dir, allocator.state);
69  return path;
70 }
71 
72 Logger
73 Logger::get_child(const std::string & suffix)
74 {
75  if (!name_) {
76  return Logger();
77  }
78 
79  rcl_ret_t rcl_ret = RCL_RET_OK;
80  std::shared_ptr<std::recursive_mutex> logging_mutex;
81  logging_mutex = get_global_logging_mutex();
82  {
83  std::lock_guard<std::recursive_mutex> guard(*logging_mutex);
84  rcl_ret = rcl_logging_rosout_add_sublogger((*name_).c_str(), suffix.c_str());
85  if (RCL_RET_NOT_FOUND == rcl_ret) {
86  rcl_reset_error();
87  } else if (RCL_RET_OK != rcl_ret) {
88  exceptions::throw_from_rcl_error(
89  rcl_ret, "failed to call rcl_logging_rosout_add_sublogger",
90  rcl_get_error_state(), rcl_reset_error);
91  }
92  }
93 
94  Logger logger(*name_ + RCUTILS_LOGGING_SEPARATOR_STRING + suffix);
95  if (RCL_RET_OK == rcl_ret) {
96  logger.logger_sublogger_pairname_.reset(
97  new std::pair<std::string, std::string>({*name_, suffix}),
98  [logging_mutex](std::pair<std::string, std::string> * logger_sublogger_pairname_ptr) {
99  std::lock_guard<std::recursive_mutex> guard(*logging_mutex);
101  logger_sublogger_pairname_ptr->first.c_str(),
102  logger_sublogger_pairname_ptr->second.c_str());
103  delete logger_sublogger_pairname_ptr;
104  if (RCL_RET_OK != rcl_ret) {
105  rcl_reset_error();
106  }
107  });
108  }
109  return logger;
110 }
111 
112 void
114 {
115  rcutils_ret_t rcutils_ret = rcutils_logging_set_logger_level(
116  get_name(),
117  static_cast<RCUTILS_LOG_SEVERITY>(level));
118  if (rcutils_ret != RCUTILS_RET_OK) {
119  if (rcutils_ret == RCUTILS_RET_INVALID_ARGUMENT) {
120  exceptions::throw_from_rcl_error(
121  RCL_RET_INVALID_ARGUMENT, "Invalid parameter",
122  rcutils_get_error_state(), rcutils_reset_error);
123  }
124  exceptions::throw_from_rcl_error(
125  RCL_RET_ERROR, "Couldn't set logger level",
126  rcutils_get_error_state(), rcutils_reset_error);
127  }
128 }
129 
132 {
133  int logger_level = rcutils_logging_get_logger_effective_level(get_name());
134 
135  if (logger_level < 0) {
136  exceptions::throw_from_rcl_error(
137  RCL_RET_ERROR, "Couldn't get logger level",
138  rcutils_get_error_state(), rcutils_reset_error);
139  }
140 
141  return static_cast<Level>(logger_level);
142 }
143 
144 } // namespace rclcpp
RCLCPP_PUBLIC void set_level(Level level)
Set level for current logger.
Definition: logger.cpp:113
RCLCPP_PUBLIC Logger get_child(const std::string &suffix)
Return a logger that is a descendant of this logger.
Definition: logger.cpp:73
RCLCPP_PUBLIC const char * get_name() const
Get the name of this logger.
Definition: logger.hpp:138
RCLCPP_PUBLIC Level get_effective_level() const
Get effective level for current logger.
Definition: logger.cpp:131
Level
An enum for the type of logger level.
Definition: logger.hpp:98
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_logging_rosout_add_sublogger(const char *logger_name, const char *sublogger_name)
Add a subordinate logger based on a logger.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_logging_rosout_remove_sublogger(const char *logger_name, const char *sublogger_name)
Remove a subordinate logger and cleans up allocated resources.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_node_logger(const rcl_node_t *node)
Return a named logger using an rcl_node_t.
Definition: logger.cpp:45
RCLCPP_PUBLIC std::filesystem::path get_log_directory()
Get the current logging directory.
Definition: logger.cpp:59
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:34
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_node_get_logger_name(const rcl_node_t *node)
Return the logger name of the node.
Definition: node.c:485
Structure which encapsulates a ROS Node.
Definition: node.h:45
#define RCL_RET_NOT_FOUND
Resource not found.
Definition: types.h:55
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:35
#define RCL_RET_ERROR
Unspecified error return code.
Definition: types.h:29
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24