Skip to content

Commit

Permalink
support --log-file-name to ros args. (#1127)
Browse files Browse the repository at this point in the history
Signed-off-by: Tomoya Fujita <[email protected]>
  • Loading branch information
fujitatomoya committed Jan 2, 2024
1 parent 133de0e commit f8af11f
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
3 changes: 3 additions & 0 deletions rcl/include/rcl/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ typedef struct rcl_arguments_s
/// The ROS flag that precedes the ROS logging level to set.
#define RCL_LOG_LEVEL_FLAG "--log-level"

/// The ROS log file name prefix to configure external logging.
#define RCL_EXTERNAL_LOG_FILE_NAME_PREFIX "--log-file-name"

/// The ROS flag that precedes the name of a configuration file to configure logging.
#define RCL_EXTERNAL_LOG_CONFIG_FLAG "--log-config-file"

Expand Down
81 changes: 79 additions & 2 deletions rcl/src/rcl/arguments.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,22 @@ _rcl_parse_log_level(
const char * arg,
rcl_log_levels_t * log_levels);

/// Parse an argument that may or may not be a log file name prefix.
/**
* \param[in] arg the argument to parse
* \param[in] allocator an allocator to use
* \param[in,out] external log name file prefix
* \return RCL_RET_OK if a valid log file name prefix was parsed, or
* \return RCL_RET_BAD_ALLOC if an allocation failed, or
* \return RLC_RET_ERROR if an unspecified error occurred.
*/
RCL_LOCAL
rcl_ret_t
_rcl_parse_external_log_file_name(
const char * arg,
rcl_allocator_t allocator,
char ** log_file_name_prefix);

/// Parse an argument that may or may not be a log configuration file.
/**
* \param[in] arg the argument to parse
Expand Down Expand Up @@ -436,6 +452,41 @@ rcl_parse_arguments(
ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.",
i, argv[i], RCL_LOG_LEVEL_FLAG);

// Attempt to parse argument as external log file name prefix
if (strcmp(RCL_EXTERNAL_LOG_FILE_NAME_PREFIX, argv[i]) == 0) {
if (i + 1 < argc) {
if (NULL != args_impl->external_log_file_name_prefix) {
RCUTILS_LOG_DEBUG_NAMED(
ROS_PACKAGE_NAME, "Overriding log file name : %s\n",
args_impl->external_log_file_name_prefix);
allocator.deallocate(args_impl->external_log_file_name_prefix, allocator.state);
args_impl->external_log_file_name_prefix = NULL;
}
if (RCL_RET_OK == _rcl_parse_external_log_file_name(
argv[i + 1], allocator, &args_impl->external_log_file_name_prefix))
{
RCUTILS_LOG_DEBUG_NAMED(
ROS_PACKAGE_NAME, "Got log file name prefix : %s\n",
args_impl->external_log_file_name_prefix);
++i; // Skip flag here, for loop will skip value.
continue;
}
rcl_error_string_t prev_error_string = rcl_get_error_string();
rcl_reset_error();
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
"Couldn't parse log file name prefix: '%s %s'. Error: %s", argv[i], argv[i + 1],
prev_error_string.str);
} else {
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
"Couldn't parse trailing %s flag. No string prefix provided.", argv[i]);
}
ret = RCL_RET_INVALID_ROS_ARGS;
goto fail;
}
RCUTILS_LOG_DEBUG_NAMED(
ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.",
i, argv[i], RCL_EXTERNAL_LOG_FILE_NAME_PREFIX);

// Attempt to parse argument as log configuration file
if (strcmp(RCL_EXTERNAL_LOG_CONFIG_FLAG, argv[i]) == 0) {
if (i + 1 < argc) {
Expand Down Expand Up @@ -467,6 +518,9 @@ rcl_parse_arguments(
ret = RCL_RET_INVALID_ROS_ARGS;
goto fail;
}
RCUTILS_LOG_DEBUG_NAMED(
ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.",
i, argv[i], RCL_EXTERNAL_LOG_CONFIG_FLAG);

// Attempt to parse argument as a security enclave
if (strcmp(RCL_ENCLAVE_FLAG, argv[i]) == 0 || strcmp(RCL_SHORT_ENCLAVE_FLAG, argv[i]) == 0) {
Expand Down Expand Up @@ -499,10 +553,9 @@ rcl_parse_arguments(
ret = RCL_RET_INVALID_ROS_ARGS;
goto fail;
}

RCUTILS_LOG_DEBUG_NAMED(
ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.",
i, argv[i], RCL_EXTERNAL_LOG_CONFIG_FLAG);
i, argv[i], RCL_ENCLAVE_FLAG);

// Attempt to parse --enable/disable-stdout-logs flag
ret = _rcl_parse_disabling_flag(
Expand Down Expand Up @@ -975,6 +1028,12 @@ rcl_arguments_fini(
}
args->impl->allocator.deallocate(args->impl->enclave, args->impl->allocator.state);

if (NULL != args->impl->external_log_file_name_prefix) {
args->impl->allocator.deallocate(
args->impl->external_log_file_name_prefix, args->impl->allocator.state);
args->impl->external_log_file_name_prefix = NULL;
}

if (NULL != args->impl->external_log_config_file) {
args->impl->allocator.deallocate(
args->impl->external_log_config_file, args->impl->allocator.state);
Expand Down Expand Up @@ -1966,6 +2025,23 @@ _rcl_parse_param_file(
return RCL_RET_OK;
}

rcl_ret_t
_rcl_parse_external_log_file_name(
const char * arg,
rcl_allocator_t allocator,
char ** log_file_name_prefix)
{
RCL_CHECK_ARGUMENT_FOR_NULL(arg, RCL_RET_INVALID_ARGUMENT);
RCL_CHECK_ARGUMENT_FOR_NULL(log_file_name_prefix, RCL_RET_INVALID_ARGUMENT);

*log_file_name_prefix = rcutils_strdup(arg, allocator);
if (NULL == *log_file_name_prefix) {
RCL_SET_ERROR_MSG("Failed to allocate memory for external log file name prefix");
return RCL_RET_BAD_ALLOC;
}
return RCL_RET_OK;
}

rcl_ret_t
_rcl_parse_external_log_config_file(
const char * arg,
Expand Down Expand Up @@ -2048,6 +2124,7 @@ _rcl_allocate_initialized_arguments_impl(rcl_arguments_t * args, rcl_allocator_t
args_impl->num_remap_rules = 0;
args_impl->remap_rules = NULL;
args_impl->log_levels = rcl_get_zero_initialized_log_levels();
args_impl->external_log_file_name_prefix = NULL;
args_impl->external_log_config_file = NULL;
args_impl->unparsed_args = NULL;
args_impl->num_unparsed_args = 0;
Expand Down
2 changes: 2 additions & 0 deletions rcl/src/rcl/arguments_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ struct rcl_arguments_impl_s

/// Log levels parsed from arguments.
rcl_log_levels_t log_levels;
/// A prefix used to external log file name
char * external_log_file_name_prefix;
/// A file used to configure the external logging library
char * external_log_config_file;
/// A boolean value indicating if the standard out handler should be used for log output
Expand Down
4 changes: 3 additions & 1 deletion rcl/src/rcl/logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ rcl_logging_configure_with_output_handler(
g_logging_allocator = *allocator;
int default_level = -1;
rcl_log_levels_t * log_levels = &global_args->impl->log_levels;
const char * file_name_prefix = global_args->impl->external_log_file_name_prefix;
const char * config_file = global_args->impl->external_log_config_file;
g_rcl_logging_stdout_enabled = !global_args->impl->log_stdout_disabled;
g_rcl_logging_rosout_enabled = !global_args->impl->log_rosout_disabled;
Expand Down Expand Up @@ -100,7 +101,8 @@ rcl_logging_configure_with_output_handler(
}
}
if (g_rcl_logging_ext_lib_enabled) {
status = rcl_logging_external_initialize(config_file, g_logging_allocator);
status = rcl_logging_external_initialize(
file_name_prefix, config_file, g_logging_allocator);
if (RCL_RET_OK == status) {
rcl_logging_ret_t logging_status = rcl_logging_external_set_logger_level(
NULL, default_level);
Expand Down

0 comments on commit f8af11f

Please sign in to comment.