diff --git a/include/zephyr/logging/log_output_custom.h b/include/zephyr/logging/log_output_custom.h index 117d69caf21..cda8b23be0a 100644 --- a/include/zephyr/logging/log_output_custom.h +++ b/include/zephyr/logging/log_output_custom.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Converge + * Copyright (c) 2023 Nobleo Technology * * 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); + +/** + * @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); + /** * @} */ diff --git a/subsys/logging/CMakeLists.txt b/subsys/logging/CMakeLists.txt index a188c191c1d..4497058e285 100644 --- a/subsys/logging/CMakeLists.txt +++ b/subsys/logging/CMakeLists.txt @@ -61,7 +61,7 @@ if(NOT CONFIG_LOG_MODE_MINIMAL) 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) endif() diff --git a/subsys/logging/Kconfig.formatting b/subsys/logging/Kconfig.formatting index f36368d1c1b..96bfe881b7f 100644 --- a/subsys/logging/Kconfig.formatting +++ b/subsys/logging/Kconfig.formatting @@ -168,4 +168,10 @@ config LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP which timestamps are printed as fixed point values with seconds on the 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 diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index b92d553920b..f2566f0bc8c 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -215,7 +216,8 @@ static int timestamp_print(const struct log_output *output, bool format = (flags & LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP) | (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) { @@ -249,8 +251,10 @@ static int timestamp_print(const struct log_output *output, ms = (remainder * 1000U) / freq; us = (1000 * (remainder * 1000U - (ms * freq))) / freq; - if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) && - flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) { + if (IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_CUSTOM_TIMESTAMP)) { + 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) char time_str[sizeof("1970-01-01T00:00:00")]; struct tm *tm; diff --git a/subsys/logging/log_output_custom.c b/subsys/logging/log_output_custom.c index 3cecadcbd52..5aa9df8d06c 100644 --- a/subsys/logging/log_output_custom.c +++ b/subsys/logging/log_output_custom.c @@ -1,10 +1,12 @@ /* * Copyright (c) 2022 Converge + * Copyright (c) 2023 Nobleo Technology * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include 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; } + +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; +}