logging: enable setting custom logging output func

To enable custom formatting of the log output while still using existing
backend, this commit adds the `log_output_custom` feature.
To use, register a commit with `log_custom_output_msg_set` then set the
log backend format set using `log_backend_format_set` with
`LOG_OUTPUT_CUSTOM`

Signed-off-by: Lucas Denefle <lucas.denefle@converge.io>
This commit is contained in:
Lucas Denefle 2022-09-01 13:49:35 +01:00 committed by Christopher Friedt
commit 2efc9cc847
10 changed files with 178 additions and 13 deletions

View file

@ -61,6 +61,8 @@ extern "C" {
#define LOG_OUTPUT_DICT 2
#define LOG_OUTPUT_CUSTOM 3
/**
* @brief Prototype of the function processing output data.
*

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Converge
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_CUSTOM_H_
#define ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_CUSTOM_H_
#include <zephyr/logging/log_output.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Custom logging output formatting.
* @ingroup log_output
* @{
*/
/** @brief Process log messages from an external output function set with
* log_custom_output_msg_set
*
* Function is using provided context with the buffer and output function to
* process formatted string and output the data.
*
* @param log_output Pointer to the log output instance.
* @param msg Log message.
* @param flags Optional flags.
*/
void log_custom_output_msg_process(const struct log_output *log_output,
struct log_msg *msg, uint32_t flags);
/** @brief Set the formatting log function that will be applied with LOG_OUTPUT_CUSTOM
*
* @param format Pointer to the external formatter function
*/
void log_custom_output_msg_set(log_format_func_t format);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_CUSTOM_H_ */

View file

@ -54,6 +54,10 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
add_subdirectory(backends)
if(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT)
zephyr_sources(log_output_custom.c)
endif()
else()
zephyr_sources(log_minimal.c)
endif()

View file

@ -104,6 +104,13 @@ config LOG_DICTIONARY_SUPPORT
This should be selected by the backend automatically.
config LOG_CUSTOM_FORMAT_SUPPORT
bool "Custom format support"
default n
help
Enable support for custom formatter.
Allows custom format callbacks registering for logging backend.
config LOG_IMMEDIATE_CLEAN_OUTPUT
bool "Clean log output"
depends on LOG_MODE_IMMEDIATE

View file

@ -22,6 +22,11 @@ config LOG_BACKEND_$(backend)_OUTPUT_DICTIONARY
help
Backend is in dictionary-based logging output mode.
config LOG_BACKEND_$(backend)_OUTPUT_CUSTOM
bool "Extern"
help
Custom formatting function can be set externally.
endchoice
# The numbering of the format types should be consistent across
@ -34,3 +39,4 @@ config LOG_BACKEND_$(backend)_OUTPUT_DEFAULT
default 0 if LOG_BACKEND_$(backend)_OUTPUT_TEXT
default 1 if LOG_BACKEND_$(backend)_OUTPUT_SYST
default 2 if LOG_BACKEND_$(backend)_OUTPUT_DICTIONARY
default 3 if LOG_BACKEND_$(backend)_OUTPUT_CUSTOM

View file

@ -18,6 +18,7 @@
#include <zephyr/logging/log_frontend.h>
#include <zephyr/syscall_handler.h>
#include <zephyr/logging/log_output_dict.h>
#include <zephyr/logging/log_output_custom.h>
#include <zephyr/linker/utils.h>
LOG_MODULE_REGISTER(log);
@ -65,7 +66,9 @@ static const log_format_func_t format_table[] = {
[LOG_OUTPUT_SYST] = IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) ?
log_output_msg_syst_process : NULL,
[LOG_OUTPUT_DICT] = IS_ENABLED(CONFIG_LOG_DICTIONARY_SUPPORT) ?
log_dict_output_msg_process : NULL
log_dict_output_msg_process : NULL,
[LOG_OUTPUT_CUSTOM] = IS_ENABLED(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT) ?
log_custom_output_msg_process : NULL,
};
log_format_func_t log_format_func_t_get(uint32_t log_type)

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2022 Converge
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_output.h>
static log_format_func_t log_custom_format_func;
void log_custom_output_msg_process(const struct log_output *output, struct log_msg *msg,
uint32_t flags)
{
if (log_custom_format_func) {
log_custom_format_func(output, msg, flags);
}
}
void log_custom_output_msg_set(log_format_func_t format)
{
log_custom_format_func = format;
}

View file

@ -0,0 +1 @@
CONFIG_LOG_CUSTOM_FORMAT_SUPPORT=y

View file

@ -8,9 +8,11 @@
#include <zephyr/logging/log.h>
#include "mock_backend.h"
#include <zephyr/sys/printk.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_output_dict.h>
#include <zephyr/logging/log_output_custom.h>
#include <zephyr/ztest.h>
#define LOG_MODULE_NAME log_switch_format
@ -24,7 +26,7 @@ void log_msgs(void)
/* standard print */
LOG_ERR("Error message example.");
#if CONFIG_LOG_MODE_DEFERRED
#if CONFIG_LOG_MODE_DEFERRED && !(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT)
/*
* When deferred logging is enabled, the work is being performed by
* another thread. The semaphore my_sem gives that thread time to process
@ -76,7 +78,6 @@ void test_log_switch_format_success_case(void)
log_msgs();
validate_log_type(raw_data_str, log_type);
}
void test_log_switch_format_set(void)
@ -105,7 +106,6 @@ void test_log_switch_format_set(void)
ret = log_backend_format_set(backend, log_type);
zassert_equal(ret, -EINVAL, "Log type not supported, Invalid value returned");
}
void test_log_switch_format_set_all_active_backends(void)
@ -127,12 +127,16 @@ void test_log_switch_format_set_all_active_backends(void)
void test_log_switch_format_func_t_get(void)
{
const log_format_func_t expected_values[] = {
[LOG_OUTPUT_TEXT] = IS_ENABLED(CONFIG_LOG_OUTPUT) ?
log_output_msg_process : NULL,
[LOG_OUTPUT_SYST] = IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) ?
log_output_msg_syst_process : NULL,
[LOG_OUTPUT_DICT] = IS_ENABLED(CONFIG_LOG_DICTIONARY_SUPPORT) ?
log_dict_output_msg_process : NULL
[LOG_OUTPUT_TEXT] = IS_ENABLED(CONFIG_LOG_OUTPUT) ? log_output_msg_process : NULL,
[LOG_OUTPUT_SYST] = IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE)
? log_output_msg_syst_process
: NULL,
[LOG_OUTPUT_DICT] = IS_ENABLED(CONFIG_LOG_DICTIONARY_SUPPORT)
? log_dict_output_msg_process
: NULL,
[LOG_OUTPUT_CUSTOM] = IS_ENABLED(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT)
? log_custom_output_msg_process
: NULL,
};
zassert_equal(log_format_table_size(), ARRAY_SIZE(expected_values),
@ -142,7 +146,6 @@ void test_log_switch_format_func_t_get(void)
zassert_equal(log_format_func_t_get(i), expected_values[i],
"Log Format Not supported");
}
}
ZTEST(log_switch_format, test_log_switch_format)
@ -153,4 +156,67 @@ ZTEST(log_switch_format, test_log_switch_format)
test_log_switch_format_func_t_get();
}
#if CONFIG_LOG_CUSTOM_FORMAT_SUPPORT
void custom_formatting(const struct log_output *output, struct log_msg *msg, uint32_t flags)
{
uint8_t buffer[] = "Hello world";
output->func((uint8_t *)buffer, sizeof(buffer), (void *)output);
}
ZTEST(log_switch_format, test_log_switch_format_custom_output_handles_null)
{
const char *backend_name;
const struct log_backend *backend;
backend_name = CONFIG_LOG_BACKEND_DEFAULT;
backend = log_backend_get_by_name(backend_name);
log_backend_format_set(backend, LOG_OUTPUT_CUSTOM);
log_custom_output_msg_set(NULL);
log_msgs();
validate_log_type("", LOG_OUTPUT_CUSTOM);
}
ZTEST(log_switch_format, test_log_switch_format_custom_output_called_when_set)
{
uint32_t log_type;
const char *backend_name;
const char *raw_data_str;
const char *text_custom_data_str = "Hello world";
const struct log_backend *backend;
backend_name = CONFIG_LOG_BACKEND_DEFAULT;
backend = log_backend_get_by_name(backend_name);
log_backend_format_set(backend, LOG_OUTPUT_CUSTOM);
log_custom_output_msg_set(custom_formatting);
log_msgs();
log_type = LOG_OUTPUT_CUSTOM;
raw_data_str = text_custom_data_str;
validate_log_type(raw_data_str, log_type);
}
ZTEST(log_switch_format, test_log_switch_format_does_not_log_when_uninit)
{
const char *backend_name;
const struct log_backend *backend;
backend_name = CONFIG_LOG_BACKEND_DEFAULT;
backend = log_backend_get_by_name(backend_name);
log_backend_format_set(backend, LOG_OUTPUT_CUSTOM);
log_msgs();
validate_log_type("", LOG_OUTPUT_CUSTOM);
}
#endif
ZTEST_SUITE(log_switch_format, NULL, NULL, NULL, NULL, NULL);

View file

@ -19,3 +19,10 @@ tests:
- qemu_x86
- sam_e70_xplained
- qemu_cortex_a53
logging.log_switch_format.custom_output:
extra_args: OVERLAY_CONFIG=overlay_custom_output.conf
integration_platforms:
- mps2_an385
- qemu_x86
- sam_e70_xplained
- qemu_cortex_a53