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