-
Notifications
You must be signed in to change notification settings - Fork 100
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
Logging #127
Merged
Merged
Logging #127
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
c35774e
refactoring so code for console sink can be reused
yyu 454e5a4
Creating a logging configure function that can be used to select whic…
nburek 56f9d74
Moving the external logging library and rosout functions out to rcl. …
nburek 602094e
Switching back to va_list for output handlers.
nburek 744ee84
PR fixup
nburek 8694fd3
use strncat_s on Windows
wjwwood 9a15eaa
derp
wjwwood File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,13 +63,6 @@ int g_rcutils_logging_default_logger_level = 0; | |
bool g_force_stdout_line_buffered = false; | ||
bool g_stdout_flush_failure_reported = false; | ||
|
||
/** | ||
* Handles formatting the log data into a common string format for every logger | ||
*/ | ||
static void format_log( | ||
const rcutils_log_location_t * location, | ||
int severity, const char * name, rcutils_time_point_value_t timestamp, | ||
const char * format, va_list * args, rcutils_char_array_t * logging_output); | ||
|
||
rcutils_ret_t rcutils_logging_initialize(void) | ||
{ | ||
|
@@ -386,7 +379,7 @@ bool rcutils_logging_logger_is_enabled_for(const char * name, int severity) | |
|
||
#define OK_OR_RETURN_EARLY(op) \ | ||
if (op != RCUTILS_RET_OK) { \ | ||
SAFE_FWRITE_TO_STDERR_AND(return ); \ | ||
return op; \ | ||
} | ||
|
||
#define APPEND_AND_RETURN_LOG_OUTPUT(s) \ | ||
|
@@ -409,34 +402,18 @@ void rcutils_log( | |
} | ||
rcutils_logging_output_handler_t output_handler = g_rcutils_logging_output_handler; | ||
if (output_handler != NULL) { | ||
char buf[1024] = ""; | ||
rcutils_char_array_t logging_output = { | ||
.buffer = buf, | ||
.owns_buffer = false, | ||
.buffer_length = 0u, | ||
.buffer_capacity = sizeof(buf), | ||
.allocator = g_rcutils_logging_allocator | ||
}; | ||
|
||
va_list args; | ||
va_start(args, format); | ||
format_log(location, severity, name, now, format, &args, &logging_output); | ||
(*output_handler)(location, severity, name ? name : "", now, format, &args); | ||
va_end(args); | ||
|
||
(*output_handler)(location, severity, name ? name : "", now, logging_output.buffer); | ||
|
||
if (rcutils_char_array_fini(&logging_output) != RCUTILS_RET_OK) { | ||
SAFE_FWRITE_TO_STDERR_AND(fprintf(stderr, "Error: failed to clean up rcutils char array.\n")); | ||
} | ||
} | ||
} | ||
|
||
typedef struct logging_input | ||
{ | ||
const char * name; | ||
const rcutils_log_location_t * location; | ||
const char * format; | ||
va_list * args; | ||
const char * msg; | ||
int severity; | ||
rcutils_time_point_value_t timestamp; | ||
} logging_input; | ||
|
@@ -524,28 +501,8 @@ const char * expand_message( | |
const logging_input * logging_input, | ||
rcutils_char_array_t * logging_output) | ||
{ | ||
char buf[1024] = ""; | ||
|
||
rcutils_char_array_t message_buffer = { | ||
.buffer = buf, | ||
.owns_buffer = false, | ||
.buffer_length = 0u, | ||
.buffer_capacity = sizeof(buf), | ||
.allocator = g_rcutils_logging_allocator | ||
}; | ||
|
||
char * ret = NULL; | ||
if (rcutils_char_array_vsprintf(&message_buffer, logging_input->format, | ||
*(logging_input->args)) == RCUTILS_RET_OK) | ||
{ | ||
if (rcutils_char_array_strcat(logging_output, message_buffer.buffer) == RCUTILS_RET_OK) { | ||
ret = logging_output->buffer; | ||
} | ||
} | ||
|
||
OK_OR_RETURN_NULL(rcutils_char_array_fini(&message_buffer)); | ||
|
||
return ret; | ||
OK_OR_RETURN_NULL(rcutils_char_array_strcat(logging_output, logging_input->msg)); | ||
return logging_output->buffer; | ||
} | ||
|
||
const char * expand_function_name( | ||
|
@@ -590,11 +547,12 @@ token_handler find_token_handler(const char * token) | |
return NULL; | ||
} | ||
|
||
static void format_log( | ||
rcutils_ret_t rcutils_logging_format_message( | ||
const rcutils_log_location_t * location, | ||
int severity, const char * name, rcutils_time_point_value_t timestamp, | ||
const char * format, va_list * args, rcutils_char_array_t * logging_output) | ||
const char * msg, rcutils_char_array_t * logging_output) | ||
{ | ||
rcutils_ret_t status = RCUTILS_RET_OK; | ||
// Process the format string looking for known tokens. | ||
const char token_start_delimiter = '{'; | ||
const char token_end_delimiter = '}'; | ||
|
@@ -607,8 +565,7 @@ static void format_log( | |
.severity = severity, | ||
.name = name, | ||
.timestamp = timestamp, | ||
.format = format, | ||
.args = args | ||
.msg = msg | ||
}; | ||
|
||
// Walk through the format string and expand tokens when they're encountered. | ||
|
@@ -621,7 +578,8 @@ static void format_log( | |
if (chars_to_start_delim > 0) { // there are stuff before a token start delimiter | ||
size_t chars_to_copy = chars_to_start_delim > | ||
remaining_chars ? remaining_chars : chars_to_start_delim; | ||
OK_OR_RETURN_EARLY(rcutils_char_array_strncat(logging_output, str + i, chars_to_copy)); | ||
status = rcutils_char_array_strncat(logging_output, str + i, chars_to_copy); | ||
OK_OR_RETURN_EARLY(status); | ||
i += chars_to_copy; | ||
if (i >= size) { // perhaps no start delimiter was found | ||
break; | ||
|
@@ -639,7 +597,8 @@ static void format_log( | |
if (chars_to_end_delim > remaining_chars) { | ||
// No end delimiters found in the remainder of the format string; | ||
// there won't be any more tokens so shortcut the rest of the checking. | ||
OK_OR_RETURN_EARLY(rcutils_char_array_strncat(logging_output, str + i, remaining_chars)); | ||
status = rcutils_char_array_strncat(logging_output, str + i, remaining_chars); | ||
OK_OR_RETURN_EARLY(status); | ||
break; | ||
} | ||
|
||
|
@@ -653,27 +612,29 @@ static void format_log( | |
if (!expand_token) { | ||
// This wasn't a token; print the start delimiter and continue the search as usual | ||
// (the substring might contain more start delimiters). | ||
OK_OR_RETURN_EARLY(rcutils_char_array_strncat(logging_output, str + i, 1)); | ||
status = rcutils_char_array_strncat(logging_output, str + i, 1); | ||
OK_OR_RETURN_EARLY(status); | ||
i++; | ||
continue; | ||
} | ||
|
||
if (!expand_token(&logging_input, logging_output)) { | ||
return; | ||
return RCUTILS_RET_ERROR; | ||
} | ||
// Skip ahead to avoid re-processing the token characters (including the 2 delimiters). | ||
i += token_len + 2; | ||
} | ||
|
||
return status; | ||
} | ||
|
||
void rcutils_logging_console_output_handler( | ||
const rcutils_log_location_t * location, | ||
int severity, const char * name, rcutils_time_point_value_t timestamp, | ||
const char * log_str) | ||
const char * format, va_list * args) | ||
{ | ||
RCUTILS_UNUSED(location); | ||
RCUTILS_UNUSED(name); | ||
RCUTILS_UNUSED(timestamp); | ||
rcutils_ret_t status = RCUTILS_RET_OK; | ||
|
||
if (!g_rcutils_logging_initialized) { | ||
fprintf( | ||
stderr, | ||
|
@@ -697,16 +658,56 @@ void rcutils_logging_console_output_handler( | |
return; | ||
} | ||
|
||
fprintf(stream, "%s\n", log_str); | ||
char msg_buf[1024] = ""; | ||
rcutils_char_array_t msg_array = { | ||
.buffer = msg_buf, | ||
.owns_buffer = false, | ||
.buffer_length = 0u, | ||
.buffer_capacity = sizeof(msg_buf), | ||
.allocator = g_rcutils_logging_allocator | ||
}; | ||
|
||
char output_buf[1024] = ""; | ||
rcutils_char_array_t output_array = { | ||
.buffer = output_buf, | ||
.owns_buffer = false, | ||
.buffer_length = 0u, | ||
.buffer_capacity = sizeof(output_buf), | ||
.allocator = g_rcutils_logging_allocator | ||
}; | ||
|
||
va_list args_clone; | ||
va_copy(args_clone, *args); | ||
status = rcutils_char_array_vsprintf(&msg_array, format, args_clone); | ||
va_end(args_clone); | ||
|
||
if (RCUTILS_RET_OK == status) { | ||
status = rcutils_logging_format_message( | ||
location, severity, name, timestamp, msg_array.buffer, &output_array); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need an else case here where we at least either set the error state or use the |
||
|
||
|
||
if (g_force_stdout_line_buffered && stream == stdout) { | ||
int flush_result = fflush(stream); | ||
if (flush_result != 0 && !g_stdout_flush_failure_reported) { | ||
g_stdout_flush_failure_reported = true; | ||
fprintf(stderr, "Error: failed to perform fflush on stdout, fflush return code is: %d\n", | ||
flush_result); | ||
if (RCUTILS_RET_OK == status) { | ||
fprintf(stream, "%s\n", output_array.buffer); | ||
|
||
if (g_force_stdout_line_buffered && stream == stdout) { | ||
int flush_result = fflush(stream); | ||
if (flush_result != 0 && !g_stdout_flush_failure_reported) { | ||
g_stdout_flush_failure_reported = true; | ||
fprintf(stderr, "Error: failed to perform fflush on stdout, fflush return code is: %d\n", | ||
flush_result); | ||
} | ||
} | ||
} | ||
|
||
status = rcutils_char_array_fini(&msg_array); | ||
if (RCUTILS_RET_OK != status) { | ||
fprintf(stderr, "Failed to fini array.\n"); | ||
} | ||
status = rcutils_char_array_fini(&output_array); | ||
if (RCUTILS_RET_OK != status) { | ||
fprintf(stderr, "Failed to fini array.\n"); | ||
} | ||
} | ||
|
||
#ifdef __cplusplus | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, we should check status and notify someone somehow if status is no OK.