diff --git a/include/zephyr/logging/log_output.h b/include/zephyr/logging/log_output.h index e650d3e7432..4aede76c6ad 100644 --- a/include/zephyr/logging/log_output.h +++ b/include/zephyr/logging/log_output.h @@ -22,6 +22,10 @@ extern "C" { * @{ */ +/**@defgroup LOG_OUTPUT_FLAGS Log output formatting flags. + * @{ + */ + /** @brief Flag forcing ANSI escape code colors, red (errors), yellow * (warnings). */ @@ -46,6 +50,8 @@ extern "C" { */ #define LOG_OUTPUT_FLAG_FORMAT_SYSLOG BIT(6) +/**@} */ + /** @brief Supported backend logging format types for use * with log_format_set() API to switch log format at runtime. */ @@ -125,10 +131,32 @@ log_format_func_t log_format_func_t_get(uint32_t log_type); * * @param log_output Pointer to the log output instance. * @param msg Log message. - * @param flags Optional flags. + * @param flags Optional flags. See @ref LOG_OUTPUT_FLAGS. */ void log_output_msg_process(const struct log_output *log_output, - struct log_msg *msg, uint32_t flags); + struct log_msg *msg, uint32_t flags); + +/** @brief Process input data to a readable string. + * + * @param log_output Pointer to the log output instance. + * @param timestamp Timestamp. + * @param domain Domain name string. Can be NULL. + * @param source Source name string. Can be NULL. + * @param level Criticality level. + * @param package Cbprintf package with a logging message string. + * @param data Data passed to hexdump API. Can bu NULL. + * @param data_len Data length. + * @param flags Formatting flags. See @ref LOG_OUTPUT_FLAGS. + */ +void log_output_process(const struct log_output *log_output, + log_timestamp_t timestamp, + const char *domain, + const char *source, + uint8_t level, + const uint8_t *package, + const uint8_t *data, + size_t data_len, + uint32_t flags); /** @brief Process log messages v2 to SYS-T format. * @@ -137,10 +165,10 @@ void log_output_msg_process(const struct log_output *log_output, * * @param log_output Pointer to the log output instance. * @param msg Log message. - * @param flag Optional flags. + * @param flags Optional flags. See @ref LOG_OUTPUT_FLAGS. */ void log_output_msg_syst_process(const struct log_output *log_output, - struct log_msg *msg, uint32_t flag); + struct log_msg *msg, uint32_t flags); /** @brief Process dropped messages indication. * diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index 4dfc2c9e45e..f22473e4836 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -314,8 +314,11 @@ static void color_postfix(const struct log_output *output, } -static int ids_print(const struct log_output *output, bool level_on, - bool func_on, uint32_t domain_id, int16_t source_id, +static int ids_print(const struct log_output *output, + bool level_on, + bool func_on, + const char *domain, + const char *source, uint32_t level) { int total = 0; @@ -324,12 +327,16 @@ static int ids_print(const struct log_output *output, bool level_on, total += print_formatted(output, "<%s> ", severity[level]); } - if (source_id >= 0) { + if (domain) { + total += print_formatted(output, "%s/", domain); + } + + if (source) { total += print_formatted(output, (func_on && ((1 << level) & LOG_FUNCTION_PREFIX_MASK)) ? "%s." : "%s: ", - log_source_name_get(domain_id, source_id)); + source); } return total; @@ -394,8 +401,8 @@ static void hexdump_line_print(const struct log_output *output, } static void log_msg_hexdump(const struct log_output *output, - uint8_t *data, uint32_t len, - int prefix_offset, uint32_t flags) + uint8_t *data, uint32_t len, + int prefix_offset, uint32_t flags) { size_t length; @@ -410,8 +417,12 @@ static void log_msg_hexdump(const struct log_output *output, } static uint32_t prefix_print(const struct log_output *output, - uint32_t flags, bool func_on, log_timestamp_t timestamp, uint8_t level, - uint8_t domain_id, int16_t source_id) + uint32_t flags, + bool func_on, + log_timestamp_t timestamp, + const char *domain, + const char *source, + uint8_t level) { uint32_t length = 0U; @@ -455,9 +466,7 @@ static uint32_t prefix_print(const struct log_output *output, color_prefix(output, colors_on, level); } - length += ids_print(output, level_on, func_on, - domain_id, source_id, level); - + length += ids_print(output, level_on, func_on, domain, source, level); return length; } @@ -470,43 +479,35 @@ static void postfix_print(const struct log_output *output, newline_print(output, flags); } -void log_output_msg_process(const struct log_output *output, - struct log_msg *msg, uint32_t flags) +void log_output_process(const struct log_output *output, + log_timestamp_t timestamp, + const char *domain, + const char *source, + uint8_t level, + const uint8_t *package, + const uint8_t *data, + size_t data_len, + uint32_t flags) { - log_timestamp_t timestamp = log_msg_get_timestamp(msg); - uint8_t level = log_msg_get_level(msg); bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING); uint32_t prefix_offset; if (!raw_string) { - void *source = (void *)log_msg_get_source(msg); - uint8_t domain_id = log_msg_get_domain(msg); - int16_t source_id = source ? - (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? - log_dynamic_source_id(source) : - log_const_source_id(source)) : - -1; - - prefix_offset = prefix_print(output, flags, 0, timestamp, - level, domain_id, source_id); + prefix_offset = prefix_print(output, flags, 0, timestamp, domain, source, level); } else { prefix_offset = 0; } - size_t len; - uint8_t *data = log_msg_get_package(msg, &len); - - if (len) { + if (package) { int err = cbpprintf(raw_string ? cr_out_func : out_func, - (void *)output, data); + (void *)output, (void *)package); (void)err; __ASSERT_NO_MSG(err >= 0); } - data = log_msg_get_data(msg, &len); - if (len) { - log_msg_hexdump(output, data, len, prefix_offset, flags); + if (data_len) { + log_msg_hexdump(output, (uint8_t *)data, data_len, prefix_offset, flags); } if (!raw_string) { @@ -516,6 +517,27 @@ void log_output_msg_process(const struct log_output *output, log_output_flush(output); } +void log_output_msg_process(const struct log_output *output, + struct log_msg *msg, uint32_t flags) +{ + log_timestamp_t timestamp = log_msg_get_timestamp(msg); + uint8_t level = log_msg_get_level(msg); + void *source = (void *)log_msg_get_source(msg); + uint8_t domain_id = log_msg_get_domain(msg); + int16_t source_id = source ? + (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? + log_dynamic_source_id(source) : + log_const_source_id(source)) : + -1; + const char *sname = source_id >= 0 ? log_source_name_get(domain_id, source_id) : NULL; + size_t plen, dlen; + uint8_t *package = log_msg_get_package(msg, &plen); + uint8_t *data = log_msg_get_data(msg, &dlen); + + log_output_process(output, timestamp, NULL, sname, level, + plen > 0 ? package : NULL, data, dlen, flags); +} + void log_output_dropped_process(const struct log_output *output, uint32_t cnt) { char buf[5];