Skip to content

Commit 0575342

Browse files
authored
Add {short_file_name} as log format option (#541)
* Add short_file_name Signed-off-by: Tony Najjar <tony.najjar@dexory.com> * PR comments Signed-off-by: Tony Najjar <tony.najjar@dexory.com> * fix windows set_env Signed-off-by: Tony Najjar <tony.najjar@dexory.com> --------- Signed-off-by: Tony Najjar <tony.najjar@dexory.com>
1 parent f322436 commit 0575342

5 files changed

Lines changed: 140 additions & 2 deletions

File tree

include/rcutils/logging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ rcutils_ret_t rcutils_logging_allocator_initialize(
8585
* the output format of messages logged to the console.
8686
* Available tokens are:
8787
* - `file_name`, the full file name of the caller including the path
88+
* - `short_file_name`, the file name of the caller without the path (basename only)
8889
* - `function_name`, the function name of the caller
8990
* - `line_number`, the line number of the caller
9091
* - `message`, the message string after it has been formatted

src/logging.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ static const char * expand_function_name(
343343
(void)start_offset;
344344
(void)end_offset;
345345

346-
if (logging_input->location) {
346+
if (logging_input->location && logging_input->location->function_name) {
347347
if (rcutils_char_array_strcat(
348348
logging_output,
349349
logging_input->location->function_name) != RCUTILS_RET_OK)
@@ -366,7 +366,7 @@ static const char * expand_file_name(
366366
(void)start_offset;
367367
(void)end_offset;
368368

369-
if (logging_input->location) {
369+
if (logging_input->location && logging_input->location->file_name) {
370370
if (rcutils_char_array_strcat(
371371
logging_output,
372372
logging_input->location->file_name) != RCUTILS_RET_OK)
@@ -381,6 +381,41 @@ static const char * expand_file_name(
381381
return logging_output->buffer;
382382
}
383383

384+
static const char * expand_short_file_name(
385+
const logging_input_t * logging_input,
386+
rcutils_char_array_t * logging_output,
387+
size_t start_offset, size_t end_offset)
388+
{
389+
(void)start_offset;
390+
(void)end_offset;
391+
392+
if (logging_input->location && logging_input->location->file_name) {
393+
const char * file_name = logging_input->location->file_name;
394+
const char * basename = file_name;
395+
const char * last_sep = strrchr(file_name, '/');
396+
if (last_sep != NULL) {
397+
basename = last_sep + 1;
398+
}
399+
#ifdef _WIN32
400+
const char * last_backslash = strrchr(file_name, '\\');
401+
if (last_backslash != NULL && (last_sep == NULL || last_backslash > last_sep)) {
402+
basename = last_backslash + 1;
403+
}
404+
#endif
405+
if (rcutils_char_array_strcat(
406+
logging_output,
407+
basename) != RCUTILS_RET_OK)
408+
{
409+
RCUTILS_SAFE_FWRITE_TO_STDERR(rcutils_get_error_string().str);
410+
rcutils_reset_error();
411+
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
412+
return NULL;
413+
}
414+
}
415+
416+
return logging_output->buffer;
417+
}
418+
384419
typedef struct token_map_entry_s
385420
{
386421
const char * token;
@@ -392,6 +427,7 @@ static const token_map_entry_t tokens[] = {
392427
{.token = "name", .handler = expand_name},
393428
{.token = "message", .handler = expand_message},
394429
{.token = "function_name", .handler = expand_function_name},
430+
{.token = "short_file_name", .handler = expand_short_file_name},
395431
{.token = "file_name", .handler = expand_file_name},
396432
{.token = "time", .handler = expand_time_as_seconds},
397433
{.token = "date_time_with_ms", .handler = expand_time_as_date},

test/test_logging_console_output_handler.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,21 @@
1414

1515
#include <gtest/gtest.h>
1616

17+
#include <cstdlib>
1718
#include <string>
1819
#include <vector>
1920

2021
#include "osrf_testing_tools_cpp/scope_exit.hpp"
2122
#include "rcutils/logging.h"
23+
#include "rcutils/types/char_array.h"
24+
25+
#ifdef _WIN32
26+
#define test_setenv(name, value) _putenv_s(name, value)
27+
#define test_unsetenv(name) _putenv_s(name, "")
28+
#else
29+
#define test_setenv(name, value) setenv(name, value, 1)
30+
#define test_unsetenv(name) unsetenv(name)
31+
#endif
2232

2333
static void call_handler(
2434
const rcutils_log_location_t * location,
@@ -95,3 +105,82 @@ TEST(TestLoggingConsoleOutputHandler, bad_inputs) {
95105
call_handler(
96106
&log_location, RCUTILS_LOG_SEVERITY_INFO, log_name, timestamp, "bad format", "part1", "part2");
97107
}
108+
109+
TEST(TestLoggingConsoleOutputHandler, short_file_name_extracts_basename) {
110+
// Set the output format to use {short_file_name} before initializing
111+
test_setenv("RCUTILS_CONSOLE_OUTPUT_FORMAT", "{short_file_name}");
112+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
113+
{
114+
test_unsetenv("RCUTILS_CONSOLE_OUTPUT_FORMAT");
115+
});
116+
117+
ASSERT_EQ(RCUTILS_RET_OK, rcutils_logging_initialize());
118+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
119+
{
120+
EXPECT_EQ(RCUTILS_RET_OK, rcutils_logging_shutdown());
121+
});
122+
123+
rcutils_allocator_t allocator = rcutils_get_default_allocator();
124+
rcutils_char_array_t output_buf;
125+
ASSERT_EQ(RCUTILS_RET_OK, rcutils_char_array_init(&output_buf, 1024, &allocator));
126+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
127+
{
128+
EXPECT_EQ(RCUTILS_RET_OK, rcutils_char_array_fini(&output_buf));
129+
});
130+
131+
rcutils_log_location_t location = {
132+
"test_function",
133+
"/some/long/path/to/my_source_file.cpp",
134+
42,
135+
};
136+
137+
ASSERT_EQ(
138+
RCUTILS_RET_OK,
139+
rcutils_logging_format_message(
140+
&location, RCUTILS_LOG_SEVERITY_INFO, "test_logger", 0,
141+
"hello", &output_buf));
142+
143+
std::string output(output_buf.buffer);
144+
EXPECT_NE(std::string::npos, output.find("my_source_file.cpp"))
145+
<< "Expected basename in output: " << output;
146+
EXPECT_EQ(std::string::npos, output.find("/some/long/path/to/"))
147+
<< "Full path should not appear in output: " << output;
148+
}
149+
150+
TEST(TestLoggingConsoleOutputHandler, short_file_name_without_path_unchanged) {
151+
test_setenv("RCUTILS_CONSOLE_OUTPUT_FORMAT", "{short_file_name}");
152+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
153+
{
154+
test_unsetenv("RCUTILS_CONSOLE_OUTPUT_FORMAT");
155+
});
156+
157+
ASSERT_EQ(RCUTILS_RET_OK, rcutils_logging_initialize());
158+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
159+
{
160+
EXPECT_EQ(RCUTILS_RET_OK, rcutils_logging_shutdown());
161+
});
162+
163+
rcutils_allocator_t allocator = rcutils_get_default_allocator();
164+
rcutils_char_array_t output_buf;
165+
ASSERT_EQ(RCUTILS_RET_OK, rcutils_char_array_init(&output_buf, 1024, &allocator));
166+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
167+
{
168+
EXPECT_EQ(RCUTILS_RET_OK, rcutils_char_array_fini(&output_buf));
169+
});
170+
171+
rcutils_log_location_t location = {
172+
"test_function",
173+
"bare_file.cpp",
174+
10,
175+
};
176+
177+
ASSERT_EQ(
178+
RCUTILS_RET_OK,
179+
rcutils_logging_format_message(
180+
&location, RCUTILS_LOG_SEVERITY_INFO, "test_logger", 0,
181+
"test", &output_buf));
182+
183+
std::string output(output_buf.buffer);
184+
EXPECT_NE(std::string::npos, output.find("bare_file.cpp"))
185+
<< "Expected bare filename in output: " << output;
186+
}

test/test_logging_output_format.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ def generate_test_description():
101101
))
102102
processes_to_test.append(name)
103103

104+
env_short_file_name = dict(os.environ)
105+
# This custom output is to check that {short_file_name} outputs the basename of the file.
106+
env_short_file_name['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = '{short_file_name}:{line_number}'
107+
env_short_file_name['RCUTILS_COLORIZED_OUTPUT'] = '0'
108+
name = 'test_logging_output_format_short_file_name'
109+
launch_description.add_action(ExecuteProcess(
110+
cmd=[executable], env=env_short_file_name, name=name, output='screen'
111+
))
112+
processes_to_test.append(name)
113+
104114
launch_description.add_action(
105115
launch_testing.actions.ReadyToTest()
106116
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
file:42
2+
file:42

0 commit comments

Comments
 (0)