diff --git a/include/logging/log_ctrl.h b/include/logging/log_ctrl.h index ef61fa06398..6a5bf9ed6c2 100644 --- a/include/logging/log_ctrl.h +++ b/include/logging/log_ctrl.h @@ -210,6 +210,17 @@ static inline bool log_data_pending(void) return false; } +/** + * @brief Configure tag used to prefix each message. + * + * @param tag Tag. + * + * @retval 0 on successful operation. + * @retval -ENOTSUP if feature is disabled. + * @retval -ENOMEM if string is longer than the buffer capacity. Tag will be trimmed. + */ +int log_set_tag(const char *tag); + #if defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_MINIMAL) #define LOG_CORE_INIT() log_core_init() #define LOG_INIT() log_init() diff --git a/include/logging/log_internal.h b/include/logging/log_internal.h index 163fa879365..c9453edd9cd 100644 --- a/include/logging/log_internal.h +++ b/include/logging/log_internal.h @@ -95,6 +95,12 @@ void z_log_msg2_free(union log_msg2_generic *msg); */ bool z_log_msg2_pending(void); +/** @brief Get tag. + * + * @return Tag. Null if feature is disabled. + */ +const char *z_log_get_tag(void); + #ifdef __cplusplus } #endif diff --git a/subsys/logging/Kconfig.formatting b/subsys/logging/Kconfig.formatting index 3000b4b4236..04cd5542533 100644 --- a/subsys/logging/Kconfig.formatting +++ b/subsys/logging/Kconfig.formatting @@ -63,7 +63,22 @@ if LOG_BACKEND_SHOW_COLOR config LOG_INFO_COLOR_GREEN bool "Use green color for info level logs" -endif +endif # LOG_BACKEND_SHOW_COLOR + +config LOG_TAG_MAX_LEN + int "Tag max length" + default 0 + range 0 64 + help + Setting non-zero value enables option to specify a tag which is + prepended to each log message. Tag can be changed at runtime. + +config LOG_TAG_DEFAULT + string "Default tag" + depends on LOG_TAG_MAX_LEN > 0 + default "" + help + Initial tag. config LOG_BACKEND_FORMAT_TIMESTAMP bool "Enable timestamp formatting in the backend" diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index c60ac487153..38308157afd 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -109,6 +109,14 @@ static const struct mpsc_pbuf_buffer_config mpsc_config = { MPSC_PBUF_MODE_OVERWRITE : 0 }; +/* Check that default tag can fit in tag buffer. */ +COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, (), + (BUILD_ASSERT(sizeof(CONFIG_LOG_TAG_DEFAULT) <= CONFIG_LOG_TAG_MAX_LEN + 1, + "Default string longer than tag capacity"))); + +static char tag[CONFIG_LOG_TAG_MAX_LEN + 1] = + COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, ({}), (CONFIG_LOG_TAG_DEFAULT)); + bool log_is_strdup(const void *buf); static void msg_process(union log_msgs msg, bool bypass); @@ -1215,6 +1223,35 @@ bool z_log_msg2_pending(void) return mpsc_pbuf_is_pending(&log_buffer); } +const char *z_log_get_tag(void) +{ + return CONFIG_LOG_TAG_MAX_LEN > 0 ? tag : NULL; +} + +int log_set_tag(const char *str) +{ + if (CONFIG_LOG_TAG_MAX_LEN == 0) { + return -ENOTSUP; + } + + if (str == NULL) { + return -EINVAL; + } + + size_t len = strlen(str); + size_t cpy_len = MIN(len, CONFIG_LOG_TAG_MAX_LEN); + + memcpy(tag, str, cpy_len); + tag[cpy_len] = '\0'; + + if (cpy_len < len) { + tag[cpy_len - 1] = '~'; + return -ENOMEM; + } + + return 0; +} + static void log_process_thread_timer_expiry_fn(struct k_timer *timer) { k_sem_give(&log_process_thread_sem); diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index 9d0b0ee11a4..e6442bf0e7c 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -495,6 +495,7 @@ static uint32_t prefix_print(const struct log_output *output, bool stamp = flags & LOG_OUTPUT_FLAG_TIMESTAMP; bool colors_on = flags & LOG_OUTPUT_FLAG_COLORS; bool level_on = flags & LOG_OUTPUT_FLAG_LEVEL; + const char *tag = z_log_get_tag(); if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) && flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) { @@ -512,6 +513,10 @@ static uint32_t prefix_print(const struct log_output *output, level_to_rfc5424_severity(level)); } + if (tag) { + length += print_formatted(output, "%s ", tag); + } + if (stamp) { length += timestamp_print(output, flags, timestamp); }