Formats
The default format used for logs is:
Predefined formats
Different formats can be chosen from by defining LOG_FORMAT
and LOG_FORMAT_ARGS
.
The following predefined formats are available:
- JSON:
{"level":"info", "ts":"yyyy-mm-dd hh:mm:dd", "component":"main", "caller":"main.c:10", "msg":"Hello World!"}
- Key/Values:
Usage
Use a predefined format by defining LOG_FORMAT
and LOG_FORMAT_ARGS
at the project level:
# CMakeFiles.txt
target_compile_definitions(${your_app} PUBLIC "-DLOG_FORMAT=LOG_FORMAT_JSON -DLOG_FORMAT_ARGS=LOG_FORMAT_JSON_ARGS")
Or at the file level before including logger.h
:
Timestamp format
Datetime
The timestamp format used is defined by LOG_TIMESTAMP_FORMAT
and defaults to %Y-%m-%d %H:%M:%S
.
It is internally generated by a call to strftime()
and can be overriden with a valid strftime format string.
# CMakeFiles.txt
target_compile_definitions(${your_app} PUBLIC LOG_TIMESTAMP_FORMAT="%Y-%m-%d %H:%M:%S")
NOTE:
The
LOG_TIMESTAMP_FORMAT
can be overriden independantly ofLOG_FORMAT
.
Sub-seconds addition
Sub-seconds formats are not supported by strftime
but can additionally be appended to the generated timestamp string.
This can be done by defining one of the following:
Definition | Description |
---|---|
LOG_TIMESTAMP_MILLISECONDS |
Add milliseconds string to timestamp. |
LOG_TIMESTAMP_MICROSECONDS |
Add microseconds string to timestamp. |
LOG_TIMESTAMP_NANOSECONDS |
Add nanoseconds string to timestamp (Not supported on every platform). |
Custom format
A custom format can be created by defining two macros with the same "signature" as these:
#define LOG_FORMAT(msg) "%s [%s] %s (%s:%ld): " msg "\n"
#define LOG_FORMAT_ARGS(level, level_short, tag, time, file, line, ...) level, (time), tag, file, line, ##__VA_ARGS__
The first one is the format of the message using the printf
formatted output syntax.
The second one is the list of arguments for the formatted syntax.
These macros can be thought as wrappers of the user defined log()
call to printf()
.
// With the following custom format
#define LOG_FORMAT(msg) "%s [%s] %s (%s:%ld): " msg "\n"
#define LOG_FORMAT_ARGS(level, level_short, tag, time, file, line, ...) level, (time), tag, file, line, ##__VA_ARGS__
// Calling a log macro ...
log_i("tag", "%s", "Hello World!");
// ... would be equivalent to:
printf(LOG_FORMAT("%s"), LOG_FORMAT_ARGS(<predefined args>, "Hello World!"));
// ... which would be compiled to:
printf("%s [%s] %s (%s:%ld): %s\n",
"info", "yyyy-mm-dd hh:mm::dd", "tag", "main.c", 10, "Hello World!");
You can look at logger.h
source code for examples on how the Default, JSON and Key/Value formats are defined using this system.
Macro arguments
The main idea behind this macro system is that all the available parameters are provided and they can be used, formatted and/or reordered as wanted.
LOG_FORMAT(msg)
Argument | Type | Description |
---|---|---|
msg | string "%s" | The first argument from the log macro. |
LOG_FORMAT_ARGS(level, level_short, tag, time, file, line, ...)
Argument | Type | Description |
---|---|---|
level | string "%s" | The level string (ie: "error", "warning", "info", "debug" or "verbose"). |
level_short | char "%c" | A single character for the level ('E', 'W', 'I', 'D' or 'V'). |
tag | string "%s" | The tag name. |
time | string "%s" | The timestamp string. NOTE: This argument needs to be rewritten with parentheses. |
file | string "%s" | The filename where the log was called. |
line | long "%ld" | The line where the log was called. |
... | variable args | The rest of the arguments from the log macro. NOTE: Rewrite these as ##__VA_ARGS__. |
NOTE:
- It is not mandatory to use all the available arguments in the macros.
- Ensure that all the formatted '%' in the
LOG_FORMAT
macro have a corresponding in-order parameter in theLOG_FORMAT_ARGS
macro.