logging: support custom timestamp formatting

This feature adds support for using a custom function to format
the timestamp used for all logging backends. When the kconfig
option LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP is set the custom
formatting function will always be used.

Signed-off-by: Hein Wessels <heinwessels93@gmail.com>
This commit is contained in:
Hein Wessels 2023-03-27 21:07:51 +02:00 committed by Carles Cufí
parent 6dface9947
commit 8735d0f653
5 changed files with 93 additions and 4 deletions

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2021 Converge * Copyright (c) 2021 Converge
* Copyright (c) 2023 Nobleo Technology
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -36,6 +37,63 @@ void log_custom_output_msg_process(const struct log_output *log_output,
*/ */
void log_custom_output_msg_set(log_format_func_t format); void log_custom_output_msg_set(log_format_func_t format);
/**
* @brief Prototype of a printer function that can print the given timestamp
* into a specific logger instance.
*
* Example usage:
* @code{.c}
* log_timestamp_printer_t *printer = ...;
* printer(log_instance, "%02u:%02u", hours, minutes);
* @endcode
*
* @param output The logger instance to write to
* @param fmt The format string
* @param ... optional arguments for the format string
*/
typedef int (*log_timestamp_printer_t)(const struct log_output *output, const char *fmt, ...);
/**
* @brief Prototype of the function that will apply custom formatting
* to a timestamp when LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP
*
* Example function:
* @code{.c}
* int custom_timestamp_formatter(const struct log_output* output,
* const log_timestamp_t timestamp,
* const log_timestamp_printer_t printer) {
* return printer(output, "%d ", timestamp);
* }
* @endcode
*
* @param output The logger instance to write to
* @param timestamp
* @param printer The printing function to use when formatting the timestamp.
*/
typedef int (*log_timestamp_format_func_t)(const struct log_output *output,
const log_timestamp_t timestamp,
const log_timestamp_printer_t printer);
/** @brief Format the timestamp with a external function.
*
* Function is using provided context with the buffer and output function to
* process formatted string and output the data.
*
* @param output Pointer to the log output instance.
* @param timestamp
* @param printer The printing function to use when formatting the timestamp.
*/
int log_custom_timestamp_print(const struct log_output *output, const log_timestamp_t timestamp,
const log_timestamp_printer_t printer);
/** @brief Set the timestamp formatting function that will be applied
* when LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP
*
* @param format Pointer to the external formatter function
*/
void log_custom_timestamp_set(log_timestamp_format_func_t format);
/** /**
* @} * @}
*/ */

View file

@ -61,7 +61,7 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
log_output_syst.c log_output_syst.c
) )
if(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT) if(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT OR CONFIG_LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP)
zephyr_sources(log_output_custom.c) zephyr_sources(log_output_custom.c)
endif() endif()

View file

@ -168,4 +168,10 @@ config LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP
which timestamps are printed as fixed point values with seconds on the which timestamps are printed as fixed point values with seconds on the
left side of the point and microseconds on the right side. left side of the point and microseconds on the right side.
config LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP
bool "Custom timestamp format support"
help
Enable support for custom formatter for the timestamp.
It will be applied to all backends.
endmenu endmenu

View file

@ -6,6 +6,7 @@
#include <zephyr/logging/log_output.h> #include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_ctrl.h> #include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log_output_custom.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <zephyr/sys/__assert.h> #include <zephyr/sys/__assert.h>
#include <zephyr/sys/cbprintf.h> #include <zephyr/sys/cbprintf.h>
@ -215,7 +216,8 @@ static int timestamp_print(const struct log_output *output,
bool format = bool format =
(flags & LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP) | (flags & LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP) |
(flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) | (flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) |
IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP); IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP) |
IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP);
if (!format) { if (!format) {
@ -249,8 +251,10 @@ static int timestamp_print(const struct log_output *output,
ms = (remainder * 1000U) / freq; ms = (remainder * 1000U) / freq;
us = (1000 * (remainder * 1000U - (ms * freq))) / freq; us = (1000 * (remainder * 1000U - (ms * freq))) / freq;
if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) && if (IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP)) {
flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) { length = log_custom_timestamp_print(output, timestamp, print_formatted);
} else if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) {
#if defined(CONFIG_NEWLIB_LIBC) #if defined(CONFIG_NEWLIB_LIBC)
char time_str[sizeof("1970-01-01T00:00:00")]; char time_str[sizeof("1970-01-01T00:00:00")];
struct tm *tm; struct tm *tm;

View file

@ -1,10 +1,12 @@
/* /*
* Copyright (c) 2022 Converge * Copyright (c) 2022 Converge
* Copyright (c) 2023 Nobleo Technology
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <zephyr/logging/log_output.h> #include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_output_custom.h>
static log_format_func_t log_custom_format_func; static log_format_func_t log_custom_format_func;
@ -20,3 +22,22 @@ void log_custom_output_msg_set(log_format_func_t format)
{ {
log_custom_format_func = format; log_custom_format_func = format;
} }
static log_timestamp_format_func_t log_timestamp_format_func;
int log_custom_timestamp_print(const struct log_output *output, const log_timestamp_t timestamp,
const log_timestamp_printer_t printer)
{
__ASSERT(log_timestamp_format_func != NULL, "custom timestamp format function not set");
if (log_timestamp_format_func) {
return log_timestamp_format_func(output, timestamp, printer);
}
return 0;
}
void log_custom_timestamp_set(log_timestamp_format_func_t format)
{
log_timestamp_format_func = format;
}