Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a generic way to change logging levels #664

Merged
merged 30 commits into from
Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
12cd013
Implement a generic way to change logging levels
May 28, 2020
87014ef
Add comment and fix for some bad code style
Jun 8, 2020
896037d
Add more check and test cases.
Jun 18, 2020
00b2b62
Update test code with c++ style and remove unnecessary code
Jun 23, 2020
4d28958
Get rid of test fixture.
clalancette Jun 25, 2020
7c5e458
Replace macro with function.
clalancette Jun 25, 2020
e2ecd3e
seperator -> separator
clalancette Jun 25, 2020
3d77ef4
Make sure to deallocate item on all error paths.
clalancette Jun 25, 2020
f7f60ff
Make sure to deallocate logger_log_level->name on error.
clalancette Jun 25, 2020
352b12d
Make sure to deallocate value on all error paths.
clalancette Jun 25, 2020
bd2413f
Make sure to call rcutils_logging_shutdown().
clalancette Jun 25, 2020
141aa0b
Use := as separator and remove multiple logger settings in one argument
Jun 30, 2020
bee60a2
Update for some comments
Jul 1, 2020
eb6138d
Remove empty newline
Jul 1, 2020
0e3a42a
Remove a redundant check
Jul 1, 2020
79d36aa
Add in some more error checks.
clalancette Jul 1, 2020
07ef7fd
update for comments
Jul 2, 2020
ce94ba0
Update for testing the command-line precedence order with two same lo…
Jul 3, 2020
95c4a21
Update for removing init before copy
Jul 3, 2020
a2b87f5
Fixed for uncrustify checking
Jul 3, 2020
b4393a4
Use rcl_reset_error instead of rcutils_reset_error.
Jul 3, 2020
66113e0
Update for review comments
Jul 7, 2020
abbac3c
Use stack variable instead of pointer for log levels in arguments
Jul 8, 2020
dc5c2b8
Adjust setting log level value
Jul 8, 2020
3ec0c30
Fixed for uncrustify checking
Jul 8, 2020
0d1d799
Avoid memory leak
ivanpauno Jul 8, 2020
165fff5
Dont use static
ivanpauno Jul 8, 2020
7ebf60c
Make finishing zero initialized log levels structure safe
ivanpauno Jul 8, 2020
b600a43
Clarify API contract
ivanpauno Jul 8, 2020
9ee1d9a
Completely initialize allocator for clang-tidy.
clalancette Jul 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rcl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ set(${PROJECT_NAME}_sources
src/rcl/localhost.c
src/rcl/logging_rosout.c
src/rcl/logging.c
src/rcl/log_level.c
src/rcl/node.c
src/rcl/node_options.c
src/rcl/publisher.c
Expand Down
33 changes: 30 additions & 3 deletions rcl/include/rcl/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define RCL__ARGUMENTS_H_

#include "rcl/allocator.h"
#include "rcl/log_level.h"
#include "rcl/macros.h"
#include "rcl/types.h"
#include "rcl/visibility_control.h"
Expand Down Expand Up @@ -77,9 +78,9 @@ rcl_get_zero_initialized_arguments(void);
* Parameter override rule parsing is supported via `-p/--param` flags e.g. `--param name:=value`
* or `-p name:=value`.
*
* The default log level will be parsed as `--log-level level`, where `level` is a name
* representing one of the log levels in the `RCUTILS_LOG_SEVERITY` enum, e.g. `info`, `debug`,
* `warn`, not case sensitive.
* The default log level will be parsed as `--log-level level` and logger levels will be parsed as
* multiple `--log-level name:=level`, where `level` is a name representing one of the log levels
* in the `RCUTILS_LOG_SEVERITY` enum, e.g. `info`, `debug`, `warn`, not case sensitive.
* If multiple of these rules are found, the last one parsed will be used.
*
* If an argument does not appear to be a valid ROS argument e.g. a `-r/--remap` flag followed by
Expand Down Expand Up @@ -343,6 +344,32 @@ rcl_remove_ros_arguments(
int * nonros_argc,
const char ** nonros_argv[]);

/// Return log levels parsed from the command line.
/**
* Log levels are parsed directly from command line arguments.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] arguments An arguments structure that has been parsed.
* \param[out] log_levels Log levels as parsed from command line arguments.
* The output must be finished by the caller if the function successes.
* \return `RCL_RET_OK` if everything goes correctly, or
* \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_arguments_get_log_levels(
const rcl_arguments_t * arguments,
rcl_log_levels_t * log_levels);

/// Copy one arguments structure into another.
/**
* <hr>
Expand Down
191 changes: 191 additions & 0 deletions rcl/include/rcl/log_level.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// Copyright 2020 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef RCL__LOG_LEVEL_H_
#define RCL__LOG_LEVEL_H_

#include "rcl/allocator.h"
#include "rcl/macros.h"
#include "rcl/types.h"
#include "rcl/visibility_control.h"

#ifdef __cplusplus
extern "C"
{
#endif

/// typedef for RCUTILS_LOG_SEVERITY;
typedef enum RCUTILS_LOG_SEVERITY rcl_log_severity_t;

/// A logger item to specify a name and a log level.
typedef struct rcl_logger_setting_t
{
/// Name for the logger.
const char * name;
/// Minimum log level severity of the logger.
rcl_log_severity_t level;
} rcl_logger_setting_t;

/// Hold default logger level and other logger setting.
typedef struct rcl_log_levels_t
{
/// Minimum default logger level severity.
rcl_log_severity_t default_logger_level;
/// Array of logger setting.
struct rcl_logger_setting_t * logger_settings;
/// Number of logger settings.
size_t num_logger_settings;
/// Capacity of logger settings.
size_t capacity_logger_settings;
/// Allocator used to allocate objects in this struct.
rcl_allocator_t allocator;
} rcl_log_levels_t;

/// Return a rcl_log_levels_t struct with members initialized to zero value.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | Yes
* Uses Atomics | No
* Lock-Free | Yes
*
* \return a rcl_log_levels_t struct with members initialized to zero value.
*/
RCL_PUBLIC
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
RCL_WARN_UNUSED
rcl_log_levels_t
rcl_get_zero_initialized_log_levels();

/// Initialize a log levels structure.
/**
* <hr>
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
* Uses Atomics | No
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
* Lock-Free | Yes
*
* \param[in] log_levels The structure to be initialized.
* \param[in] allocator Memory allocator to be used and assigned into log_levels.
* \param[in] logger_count Number of logger settings to be allocated.
* This reserves memory for logger_settings, but doesn't initialize it.
* \return `RCL_RET_OK` if the structure was initialized successfully, or
* \return `RCL_RET_INVALID_ARGUMENT` if log_levels is NULL, or
* log_levels contains initialized memory, or
* allocator is invalid, or
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed.
*/
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);

/// Copy one log levels structure into another.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] src The structure to be copied.
* Its allocator is used to copy memory into the new structure.
* \param[out] dst A log levels structure to be copied into.
* \return `RCL_RET_OK` if the structure was copied successfully, or
* \return `RCL_RET_INVALID_ARGUMENT` if src is NULL, or
* if src allocator is invalid, or
* if dst is NULL, or
* if dst contains already allocated memory, or
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed.
*/
RCL_PUBLIC
RCL_WARN_UNUSED
rcl_ret_t
rcl_log_levels_copy(const rcl_log_levels_t * src, rcl_log_levels_t * dst);

/// Reclaim resources held inside rcl_log_levels_t structure.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | No
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] log_levels The structure which its resources have to be deallocated.
* \return `RCL_RET_OK` if the memory was successfully freed, or
* \return `RCL_RET_INVALID_ARGUMENT` if log_levels is NULL, or
* if ist allocator is invalid and the structure contains initialized memory.
*/
RCL_PUBLIC
rcl_ret_t
rcl_log_levels_fini(rcl_log_levels_t * log_levels);

/// Shrink log levels structure.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
* \param[in] log_levels The structure to be shrunk.
* \return `RCL_RET_OK` if the memory was successfully shrunk, or
* \return `RCL_RET_INVALID_ARGUMENT` if log_levels is NULL or if its allocator is invalid, or
* \return `RCL_RET_BAD_ALLOC` if reallocating memory failed.
*/
RCL_PUBLIC
rcl_ret_t
rcl_log_levels_shrink_to_size(rcl_log_levels_t * log_levels);

/// Add logger setting with a name and a level.
/**
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*
* \param[in] log_levels The structure where to set the logger log level.
* \param[in] logger_name Name for the logger, a copy of it will be stored in the structure.
* \param[in] log_level Minimum log level severity to be set for logger_name.
* \return `RCL_RET_OK` if add logger setting successfully, or
* \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
* \return `RCL_RET_INVALID_ARGUMENT` if log_levels is NULL, or
* if log_levels was not initialized, or
* if log_levels allocator is invalid, or
* if logger_name is NULL, or
* \return `RCL_RET_ERROR` if the log_levels structure is already full.
*/
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);

#ifdef __cplusplus
}
#endif

#endif // RCL__LOG_LEVEL_H_
Loading