logging: Add support for runtime filtering in frontend
So far frontend supported only compile time filtering. Adding support for runtime filtering. From runtime filtering perspective frontend is treated similar to any other backend but since it is a singleton it has fixed ID. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
68d1a52417
commit
b819b51fe7
5 changed files with 113 additions and 24 deletions
|
|
@ -378,6 +378,13 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
/** @brief Number of slots in one word. */
|
||||
#define LOG_FILTERS_NUM_OF_SLOTS (32 / LOG_FILTER_SLOT_SIZE)
|
||||
|
||||
/** @brief Maximum number of backends supported when runtime filtering is enabled. */
|
||||
#define LOG_FILTERS_MAX_BACKENDS \
|
||||
(LOG_FILTERS_NUM_OF_SLOTS - (1 + IS_ENABLED(CONFIG_LOG_FRONTEND)))
|
||||
|
||||
/** @brief Slot reserved for the frontend. Last slot is used. */
|
||||
#define LOG_FRONTEND_SLOT_ID (LOG_FILTERS_NUM_OF_SLOTS - 1)
|
||||
|
||||
/** @brief Slot mask. */
|
||||
#define LOG_FILTER_SLOT_MASK (BIT(LOG_FILTER_SLOT_SIZE) - 1U)
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ uint32_t log_filter_get(struct log_backend const *const backend,
|
|||
/**
|
||||
* @brief Set filter on given source for the provided backend.
|
||||
*
|
||||
* @param backend Backend instance. NULL for all backends.
|
||||
* @param backend Backend instance. NULL for all backends (and frontend).
|
||||
* @param domain_id ID of the domain.
|
||||
* @param source_id Source (module or instance) ID.
|
||||
* @param level Severity level.
|
||||
|
|
@ -168,6 +168,26 @@ __syscall uint32_t log_filter_set(struct log_backend const *const backend,
|
|||
uint32_t domain_id, int16_t source_id,
|
||||
uint32_t level);
|
||||
|
||||
/**
|
||||
* @brief Get source filter for the frontend.
|
||||
*
|
||||
* @param source_id Source (module or instance) ID.
|
||||
* @param runtime True for runtime filter or false for compiled in.
|
||||
*
|
||||
* @return Severity level.
|
||||
*/
|
||||
uint32_t log_frontend_filter_get(int16_t source_id, bool runtime);
|
||||
|
||||
/**
|
||||
* @brief Set filter on given source for the frontend.
|
||||
*
|
||||
* @param source_id Source (module or instance) ID.
|
||||
* @param level Severity level.
|
||||
*
|
||||
* @return Actual level set which may be limited by compiled level.
|
||||
*/
|
||||
__syscall uint32_t log_frontend_filter_set(int16_t source_id, uint32_t level);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Enable backend with initial maximum filtering level.
|
||||
|
|
|
|||
|
|
@ -241,6 +241,11 @@ void log_core_init(void)
|
|||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
log_frontend_init();
|
||||
|
||||
for (uint16_t s = 0; s < log_src_cnt_get(0); s++) {
|
||||
log_frontend_filter_set(s, CONFIG_LOG_MAX_LEVEL);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -292,7 +297,7 @@ static uint32_t z_log_init(bool blocking, bool can_sleep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
__ASSERT_NO_MSG(log_backend_count_get() < LOG_FILTERS_NUM_OF_SLOTS);
|
||||
__ASSERT_NO_MSG(log_backend_count_get() < LOG_FILTERS_MAX_BACKENDS);
|
||||
|
||||
if (atomic_inc(&initialized) != 0) {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -412,9 +412,23 @@ static void set_runtime_filter(uint8_t backend_id, uint8_t domain_id,
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t z_impl_log_filter_set(struct log_backend const *const backend,
|
||||
uint32_t domain_id, int16_t source_id,
|
||||
uint32_t level)
|
||||
static uint32_t filter_get(uint8_t id, uint32_t domain_id, int16_t source_id, bool runtime)
|
||||
{
|
||||
__ASSERT_NO_MSG(source_id < log_src_cnt_get(domain_id));
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && runtime) {
|
||||
if (source_id < 0) {
|
||||
return LOG_LEVEL_DBG;
|
||||
}
|
||||
|
||||
return LOG_FILTER_SLOT_GET(get_dynamic_filter(domain_id, source_id), id);
|
||||
}
|
||||
|
||||
return log_compiled_level_get(domain_id, source_id);
|
||||
}
|
||||
|
||||
|
||||
uint32_t filter_set(int id, uint32_t domain_id, int16_t source_id, uint32_t level)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
|
||||
return log_compiled_level_get(domain_id, source_id);
|
||||
|
|
@ -423,12 +437,20 @@ uint32_t z_impl_log_filter_set(struct log_backend const *const backend,
|
|||
__ASSERT_NO_MSG(source_id < log_src_cnt_get(domain_id));
|
||||
|
||||
|
||||
if (backend == NULL) {
|
||||
if (id < 0) {
|
||||
uint32_t max = 0U;
|
||||
size_t backend_cnt;
|
||||
|
||||
STRUCT_SECTION_FOREACH(log_backend, iter_backend) {
|
||||
uint32_t current = log_filter_set(iter_backend,
|
||||
domain_id, source_id, level);
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
max = filter_set(LOG_FRONTEND_SLOT_ID, domain_id, source_id, level);
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
STRUCT_SECTION_COUNT(log_backend, &backend_cnt);
|
||||
for (size_t i = 0; i < backend_cnt; i++) {
|
||||
uint32_t current = filter_set(i, domain_id, source_id, level);
|
||||
|
||||
max = MAX(current, max);
|
||||
}
|
||||
|
|
@ -436,13 +458,27 @@ uint32_t z_impl_log_filter_set(struct log_backend const *const backend,
|
|||
return max;
|
||||
}
|
||||
|
||||
level = MIN(level, MAX(log_filter_get(backend, domain_id, source_id, false),
|
||||
level = MIN(level, MAX(filter_get(id, domain_id, source_id, false),
|
||||
CONFIG_LOG_OVERRIDE_LEVEL));
|
||||
set_runtime_filter(log_backend_id_get(backend), domain_id, source_id, level);
|
||||
set_runtime_filter(id, domain_id, source_id, level);
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
uint32_t z_impl_log_filter_set(struct log_backend const *const backend,
|
||||
uint32_t domain_id, int16_t source_id,
|
||||
uint32_t level)
|
||||
{
|
||||
int id = (backend == NULL) ? -1 : log_backend_id_get(backend);
|
||||
|
||||
return filter_set(id, domain_id, source_id, level);
|
||||
}
|
||||
|
||||
uint32_t z_impl_log_frontend_filter_set(int16_t source_id, uint32_t level)
|
||||
{
|
||||
return filter_set(LOG_FRONTEND_SLOT_ID, Z_LOG_LOCAL_DOMAIN_ID, source_id, level);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
uint32_t z_vrfy_log_filter_set(struct log_backend const *const backend,
|
||||
uint32_t domain_id,
|
||||
|
|
@ -541,18 +577,18 @@ void log_backend_disable(struct log_backend const *const backend)
|
|||
uint32_t log_filter_get(struct log_backend const *const backend,
|
||||
uint32_t domain_id, int16_t source_id, bool runtime)
|
||||
{
|
||||
__ASSERT_NO_MSG(source_id < log_src_cnt_get(domain_id));
|
||||
int id = (backend == NULL) ? -1 : log_backend_id_get(backend);
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && runtime) {
|
||||
if (source_id < 0) {
|
||||
return LOG_LEVEL_DBG;
|
||||
}
|
||||
return filter_get(id, domain_id, source_id, runtime);
|
||||
}
|
||||
|
||||
return LOG_FILTER_SLOT_GET(get_dynamic_filter(domain_id, source_id),
|
||||
log_backend_id_get(backend));
|
||||
uint32_t log_frontend_filter_get(int16_t source_id, bool runtime)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
return LOG_LEVEL_NONE;
|
||||
}
|
||||
|
||||
return log_compiled_level_get(domain_id, source_id);
|
||||
return filter_get(LOG_FRONTEND_SLOT_ID, Z_LOG_LOCAL_DOMAIN_ID, source_id, runtime);
|
||||
}
|
||||
|
||||
void z_log_links_initiate(void)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,27 @@ void z_log_msg_finalize(struct log_msg *msg, const void *source,
|
|||
z_log_msg_commit(msg);
|
||||
}
|
||||
|
||||
static bool frontend_runtime_filtering(const void *source, uint32_t level)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If only frontend is used and log got here it means that it was accepted. */
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (level == LOG_LEVEL_NONE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct log_source_dynamic_data *dynamic = (struct log_source_dynamic_data *)source;
|
||||
uint32_t f_level = LOG_FILTER_SLOT_GET(&dynamic->filters, LOG_FRONTEND_SLOT_ID);
|
||||
|
||||
return level <= f_level;
|
||||
}
|
||||
|
||||
/** @brief Create a log message using simplified method.
|
||||
*
|
||||
* Simple log message has 0-2 32 bit word arguments so creating cbprintf package
|
||||
|
|
@ -102,7 +123,7 @@ static void z_log_msg_simple_create(const void *source, uint32_t level, uint32_t
|
|||
void z_impl_z_log_msg_simple_create_0(const void *source, uint32_t level, const char *fmt)
|
||||
{
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && frontend_runtime_filtering(source, level)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) {
|
||||
log_frontend_simple_0(source, level, fmt);
|
||||
} else {
|
||||
|
|
@ -141,7 +162,7 @@ void z_impl_z_log_msg_simple_create_0(const void *source, uint32_t level, const
|
|||
void z_impl_z_log_msg_simple_create_1(const void *source, uint32_t level,
|
||||
const char *fmt, uint32_t arg)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && frontend_runtime_filtering(source, level)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) {
|
||||
log_frontend_simple_1(source, level, fmt, arg);
|
||||
} else {
|
||||
|
|
@ -181,7 +202,7 @@ void z_impl_z_log_msg_simple_create_1(const void *source, uint32_t level,
|
|||
void z_impl_z_log_msg_simple_create_2(const void *source, uint32_t level,
|
||||
const char *fmt, uint32_t arg0, uint32_t arg1)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && frontend_runtime_filtering(source, level)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND_OPT_API)) {
|
||||
log_frontend_simple_2(source, level, fmt, arg0, arg1);
|
||||
} else {
|
||||
|
|
@ -223,7 +244,7 @@ void z_impl_z_log_msg_static_create(const void *source,
|
|||
const struct log_msg_desc desc,
|
||||
uint8_t *package, const void *data)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && frontend_runtime_filtering(source, desc.level)) {
|
||||
log_frontend_msg(source, desc, package, data);
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +345,7 @@ void z_log_msg_runtime_vcreate(uint8_t domain_id, const void *source,
|
|||
__ASSERT_NO_MSG(plen >= 0);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && frontend_runtime_filtering(source, desc.level)) {
|
||||
log_frontend_msg(source, desc, pkg, data);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue