ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
ROS 2 C++ Client Library with ROS Client Library
log_level.c
1 // Copyright 2020 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 "rcl/log_level.h"
16 
17 #include "rcl/error_handling.h"
18 #include "rcutils/allocator.h"
19 #include "rcutils/logging_macros.h"
20 #include "rcutils/strdup.h"
21 
24 {
25  const rcl_log_levels_t log_levels = {
26  .default_logger_level = RCUTILS_LOG_SEVERITY_UNSET,
27  .logger_settings = NULL,
28  .num_logger_settings = 0,
29  .capacity_logger_settings = 0,
30  .allocator = {NULL, NULL, NULL, NULL, NULL},
31  };
32  return log_levels;
33 }
34 
37  rcl_log_levels_t * log_levels, const rcl_allocator_t * allocator, size_t logger_count)
38 {
39  RCL_CHECK_ARGUMENT_FOR_NULL(log_levels, RCL_RET_INVALID_ARGUMENT);
40  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
41  if (log_levels->logger_settings != NULL) {
42  RCL_SET_ERROR_MSG("invalid logger settings");
44  }
45 
46  log_levels->default_logger_level = RCUTILS_LOG_SEVERITY_UNSET;
47  log_levels->logger_settings = NULL;
48  log_levels->num_logger_settings = 0;
49  log_levels->capacity_logger_settings = logger_count;
50  log_levels->allocator = *allocator;
51 
52  if (logger_count > 0) {
53  log_levels->logger_settings = allocator->allocate(
54  sizeof(rcl_logger_setting_t) * logger_count, allocator->state);
55  if (NULL == log_levels->logger_settings) {
56  RCL_SET_ERROR_MSG("Error allocating memory");
57  return RCL_RET_BAD_ALLOC;
58  }
59  }
60  return RCL_RET_OK;
61 }
62 
65 {
66  RCL_CHECK_ARGUMENT_FOR_NULL(src, RCL_RET_INVALID_ARGUMENT);
67  RCL_CHECK_ARGUMENT_FOR_NULL(dst, RCL_RET_INVALID_ARGUMENT);
68  const rcl_allocator_t * allocator = &src->allocator;
69  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
70  if (dst->logger_settings != NULL) {
71  RCL_SET_ERROR_MSG("invalid logger settings");
73  }
74 
75  dst->logger_settings = allocator->allocate(
76  sizeof(rcl_logger_setting_t) * (src->num_logger_settings), allocator->state);
77  if (NULL == dst->logger_settings) {
78  RCL_SET_ERROR_MSG("Error allocating memory");
79  return RCL_RET_BAD_ALLOC;
80  }
81 
84  dst->allocator = src->allocator;
85  for (size_t i = 0; i < src->num_logger_settings; ++i) {
86  dst->logger_settings[i].name =
87  rcutils_strdup(src->logger_settings[i].name, *allocator);
88  if (NULL == dst->logger_settings[i].name) {
89  dst->num_logger_settings = i;
90  if (RCL_RET_OK != rcl_log_levels_fini(dst)) {
91  RCL_SET_ERROR_MSG("Error while finalizing log levels due to another error");
92  }
93  return RCL_RET_BAD_ALLOC;
94  }
95  dst->logger_settings[i].level = src->logger_settings[i].level;
96  }
98  return RCL_RET_OK;
99 }
100 
101 rcl_ret_t
103 {
104  RCL_CHECK_ARGUMENT_FOR_NULL(log_levels, RCL_RET_INVALID_ARGUMENT);
105  const rcl_allocator_t * allocator = &log_levels->allocator;
106  if (log_levels->logger_settings) {
107  // check allocator here, so it's safe to finish a zero initialized rcl_log_levels_t
108  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
109  for (size_t i = 0; i < log_levels->num_logger_settings; ++i) {
110  allocator->deallocate((void *)log_levels->logger_settings[i].name, allocator->state);
111  }
112  log_levels->num_logger_settings = 0;
113 
114  allocator->deallocate(log_levels->logger_settings, allocator->state);
115  log_levels->logger_settings = NULL;
116  }
117  return RCL_RET_OK;
118 }
119 
120 rcl_ret_t
122 {
123  RCL_CHECK_ARGUMENT_FOR_NULL(log_levels, RCL_RET_INVALID_ARGUMENT);
124  rcl_allocator_t * allocator = &log_levels->allocator;
125  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
126  if (0U == log_levels->num_logger_settings) {
127  allocator->deallocate(log_levels->logger_settings, allocator->state);
128  log_levels->logger_settings = NULL;
129  log_levels->capacity_logger_settings = 0;
130  } else if (log_levels->num_logger_settings < log_levels->capacity_logger_settings) {
131  rcl_logger_setting_t * new_logger_settings = allocator->reallocate(
132  log_levels->logger_settings,
133  sizeof(rcl_logger_setting_t) * log_levels->num_logger_settings,
134  allocator->state);
135  if (NULL == new_logger_settings) {
136  return RCL_RET_BAD_ALLOC;
137  }
138  log_levels->logger_settings = new_logger_settings;
139  log_levels->capacity_logger_settings = log_levels->num_logger_settings;
140  }
141  return RCL_RET_OK;
142 }
143 
144 rcl_ret_t
146  rcl_log_levels_t * log_levels, const char * logger_name, rcl_log_severity_t log_level)
147 {
148  RCL_CHECK_ARGUMENT_FOR_NULL(log_levels, RCL_RET_INVALID_ARGUMENT);
149  RCL_CHECK_ARGUMENT_FOR_NULL(log_levels->logger_settings, RCL_RET_INVALID_ARGUMENT);
150  RCL_CHECK_ARGUMENT_FOR_NULL(logger_name, RCL_RET_INVALID_ARGUMENT);
151  rcl_allocator_t * allocator = &log_levels->allocator;
152  RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, "invalid allocator", return RCL_RET_INVALID_ARGUMENT);
153 
154  // check if there exists a logger with the same name
155  rcl_logger_setting_t * logger_setting = NULL;
156  for (size_t i = 0; i < log_levels->num_logger_settings; ++i) {
157  if (strcmp(log_levels->logger_settings[i].name, logger_name) == 0) {
158  logger_setting = &log_levels->logger_settings[i];
159  if (logger_setting->level != log_level) {
160  RCUTILS_LOG_DEBUG_NAMED(
161  ROS_PACKAGE_NAME, "Minimum log level of logger [%s] will be replaced from %d to %d",
162  logger_name, logger_setting->level, log_level);
163  logger_setting->level = log_level;
164  }
165  return RCL_RET_OK;
166  }
167  }
168 
169  if (log_levels->num_logger_settings >= log_levels->capacity_logger_settings) {
170  RCL_SET_ERROR_MSG("No capacity to store a logger setting");
171  return RCL_RET_ERROR;
172  }
173 
174  char * name = rcutils_strdup(logger_name, *allocator);
175  if (NULL == name) {
176  RCL_SET_ERROR_MSG("failed to copy logger name");
177  return RCL_RET_BAD_ALLOC;
178  }
179 
180  logger_setting = &log_levels->logger_settings[log_levels->num_logger_settings];
181  logger_setting->name = name;
182  logger_setting->level = log_level;
183  log_levels->num_logger_settings += 1;
184  return RCL_RET_OK;
185 }
#define RCL_CHECK_ALLOCATOR_WITH_MSG(allocator, msg, fail_statement)
Check that the given allocator is initialized, or fail with a message.
Definition: allocator.h:56
rcutils_allocator_t rcl_allocator_t
Encapsulation of an allocator.
Definition: allocator.h:31
RCL_PUBLIC rcl_ret_t rcl_log_levels_fini(rcl_log_levels_t *log_levels)
Reclaim resources held inside rcl_log_levels_t structure.
Definition: log_level.c:102
enum RCUTILS_LOG_SEVERITY rcl_log_severity_t
typedef for RCUTILS_LOG_SEVERITY;
Definition: log_level.h:31
RCL_PUBLIC rcl_ret_t rcl_log_levels_add_logger_setting(rcl_log_levels_t *log_levels, const char *logger_name, rcl_log_severity_t log_level)
Add logger setting with a name and a level.
Definition: log_level.c:145
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_log_levels_init(rcl_log_levels_t *log_levels, const rcl_allocator_t *allocator, size_t logger_count)
Initialize a log levels structure.
Definition: log_level.c:36
RCL_PUBLIC rcl_ret_t rcl_log_levels_shrink_to_size(rcl_log_levels_t *log_levels)
Shrink log levels structure.
Definition: log_level.c:121
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_log_levels_copy(const rcl_log_levels_t *src, rcl_log_levels_t *dst)
Copy one log levels structure into another.
Definition: log_level.c:64
RCL_PUBLIC RCL_WARN_UNUSED rcl_log_levels_t rcl_get_zero_initialized_log_levels(void)
Return a rcl_log_levels_t struct with members initialized to zero value.
Definition: log_level.c:23
Hold default logger level and other logger setting.
Definition: log_level.h:44
rcl_allocator_t allocator
Allocator used to allocate objects in this struct.
Definition: log_level.h:54
size_t capacity_logger_settings
Capacity of logger settings.
Definition: log_level.h:52
rcl_logger_setting_t * logger_settings
Array of logger setting.
Definition: log_level.h:48
rcl_log_severity_t default_logger_level
Minimum default logger level severity.
Definition: log_level.h:46
size_t num_logger_settings
Number of logger settings.
Definition: log_level.h:50
A logger item to specify a name and a log level.
Definition: log_level.h:35
rcl_log_severity_t level
Minimum log level severity of the logger.
Definition: log_level.h:39
const char * name
Name for the logger.
Definition: log_level.h:37
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:33
#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