123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 |
- /*
- * Copyright (c) 2018 Nordic Semiconductor ASA
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <shell/shell.h>
- #include <logging/log_ctrl.h>
- #include <logging/log.h>
- #include <string.h>
- typedef int (*log_backend_cmd_t)(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc,
- char **argv);
- static const char * const severity_lvls[] = {
- "none",
- "err",
- "wrn",
- "inf",
- "dbg",
- };
- static const char * const severity_lvls_sorted[] = {
- "dbg",
- "err",
- "inf",
- "none",
- "wrn",
- };
- /**
- * @brief Function for finding backend instance with given name.
- *
- * @param p_name Name of the backend instance.
- *
- * @return Pointer to the instance or NULL.
- *
- */
- static const struct log_backend *backend_find(char const *name)
- {
- const struct log_backend *backend;
- size_t slen = strlen(name);
- for (int i = 0; i < log_backend_count_get(); i++) {
- backend = log_backend_get(i);
- if (strncmp(name, backend->name, slen) == 0) {
- return backend;
- }
- }
- return NULL;
- }
- static bool shell_state_precheck(const struct shell *shell)
- {
- if (shell->log_backend->control_block->state
- == SHELL_LOG_BACKEND_UNINIT) {
- shell_error(shell, "Shell log backend not initialized.");
- return false;
- }
- return true;
- }
- /**
- * @brief Function for executing command on given backend.
- */
- static int shell_backend_cmd_execute(const struct shell *shell,
- size_t argc,
- char **argv,
- log_backend_cmd_t func)
- {
- /* Based on the structure of backend commands, name of the backend can
- * be found at -1 (log backend <name> command).
- */
- char const *name = argv[-1];
- const struct log_backend *backend = backend_find(name);
- if (backend != NULL) {
- func(shell, backend, argc, argv);
- } else {
- shell_error(shell, "Invalid backend: %s", name);
- return -ENOEXEC;
- }
- return 0;
- }
- static int log_status(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc, char **argv)
- {
- uint32_t modules_cnt = log_sources_count();
- uint32_t dynamic_lvl;
- uint32_t compiled_lvl;
- if (!log_backend_is_active(backend)) {
- shell_warn(shell, "Logs are halted!");
- }
- shell_fprintf(shell, SHELL_NORMAL, "%-40s | current | built-in \r\n",
- "module_name");
- shell_fprintf(shell, SHELL_NORMAL,
- "----------------------------------------------------------\r\n");
- for (int16_t i = 0U; i < modules_cnt; i++) {
- dynamic_lvl = log_filter_get(backend, CONFIG_LOG_DOMAIN_ID,
- i, true);
- compiled_lvl = log_filter_get(backend, CONFIG_LOG_DOMAIN_ID,
- i, false);
- shell_fprintf(shell, SHELL_NORMAL, "%-40s | %-7s | %s\r\n",
- log_source_name_get(CONFIG_LOG_DOMAIN_ID, i),
- severity_lvls[dynamic_lvl],
- severity_lvls[compiled_lvl]);
- }
- return 0;
- }
- static int cmd_log_self_status(const struct shell *shell,
- size_t argc, char **argv)
- {
- if (!shell_state_precheck(shell)) {
- return 0;
- }
- log_status(shell, shell->log_backend->backend, argc, argv);
- return 0;
- }
- static int cmd_log_backend_status(const struct shell *shell,
- size_t argc, char **argv)
- {
- shell_backend_cmd_execute(shell, argc, argv, log_status);
- return 0;
- }
- static int module_id_get(const char *name)
- {
- uint32_t modules_cnt = log_sources_count();
- const char *tmp_name;
- uint32_t i;
- for (i = 0U; i < modules_cnt; i++) {
- tmp_name = log_source_name_get(CONFIG_LOG_DOMAIN_ID, i);
- if (strncmp(tmp_name, name, 64) == 0) {
- return i;
- }
- }
- return -1;
- }
- static void filters_set(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc, char **argv, uint32_t level)
- {
- int i;
- int id;
- bool all = argc ? false : true;
- int cnt = all ? log_sources_count() : argc;
- if (!backend->cb->active) {
- shell_warn(shell, "Backend not active.");
- }
- for (i = 0; i < cnt; i++) {
- id = all ? i : module_id_get(argv[i]);
- if (id >= 0) {
- uint32_t set_lvl = log_filter_set(backend,
- CONFIG_LOG_DOMAIN_ID,
- id, level);
- if (set_lvl != level) {
- const char *name;
- name = all ?
- log_source_name_get(
- CONFIG_LOG_DOMAIN_ID, i) :
- argv[i];
- shell_warn(shell, "%s: level set to %s.",
- name, severity_lvls[set_lvl]);
- }
- } else {
- shell_error(shell, "%s: unknown source name.", argv[i]);
- }
- }
- }
- static int severity_level_get(const char *str)
- {
- int i;
- for (i = 0; i < ARRAY_SIZE(severity_lvls); i++) {
- if (strncmp(str, severity_lvls[i], 4) == 0) {
- return i;
- }
- }
- return -1;
- }
- static int log_enable(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc,
- char **argv)
- {
- int severity_level;
- severity_level = severity_level_get(argv[1]);
- if (severity_level < 0) {
- shell_error(shell, "Invalid severity: %s", argv[1]);
- return -ENOEXEC;
- }
- /* Arguments following severity level are interpreted as module names.*/
- filters_set(shell, backend, argc - 2, &argv[2], severity_level);
- return 0;
- }
- static int cmd_log_self_enable(const struct shell *shell,
- size_t argc, char **argv)
- {
- if (!shell_state_precheck(shell)) {
- return 0;
- }
- return log_enable(shell, shell->log_backend->backend, argc, argv);
- }
- static int cmd_log_backend_enable(const struct shell *shell,
- size_t argc, char **argv)
- {
- return shell_backend_cmd_execute(shell, argc, argv, log_enable);
- }
- static int log_disable(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc,
- char **argv)
- {
- filters_set(shell, backend, argc - 1, &argv[1], LOG_LEVEL_NONE);
- return 0;
- }
- static int cmd_log_self_disable(const struct shell *shell,
- size_t argc, char **argv)
- {
- if (!shell_state_precheck(shell)) {
- return 0;
- }
- return log_disable(shell, shell->log_backend->backend, argc, argv);
- }
- static int cmd_log_backend_disable(const struct shell *shell,
- size_t argc, char **argv)
- {
- return shell_backend_cmd_execute(shell, argc, argv, log_disable);
- }
- static void module_name_get(size_t idx, struct shell_static_entry *entry);
- SHELL_DYNAMIC_CMD_CREATE(dsub_module_name, module_name_get);
- static void module_name_get(size_t idx, struct shell_static_entry *entry)
- {
- entry->handler = NULL;
- entry->help = NULL;
- entry->subcmd = &dsub_module_name;
- entry->syntax = log_source_name_get(CONFIG_LOG_DOMAIN_ID, idx);
- }
- static void severity_lvl_get(size_t idx, struct shell_static_entry *entry)
- {
- entry->handler = NULL;
- entry->help = NULL;
- entry->subcmd = &dsub_module_name;
- entry->syntax = (idx < ARRAY_SIZE(severity_lvls_sorted)) ?
- severity_lvls_sorted[idx] : NULL;
- }
- SHELL_DYNAMIC_CMD_CREATE(dsub_severity_lvl, severity_lvl_get);
- static int log_halt(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc,
- char **argv)
- {
- log_backend_deactivate(backend);
- return 0;
- }
- static int cmd_log_self_halt(const struct shell *shell,
- size_t argc, char **argv)
- {
- if (!shell_state_precheck(shell)) {
- return 0;
- }
- return log_halt(shell, shell->log_backend->backend, argc, argv);
- }
- static int cmd_log_backend_halt(const struct shell *shell,
- size_t argc, char **argv)
- {
- return shell_backend_cmd_execute(shell, argc, argv, log_halt);
- }
- static int log_go(const struct shell *shell,
- const struct log_backend *backend,
- size_t argc,
- char **argv)
- {
- log_backend_activate(backend, backend->cb->ctx);
- return 0;
- }
- static int cmd_log_self_go(const struct shell *shell,
- size_t argc, char **argv)
- {
- if (!shell_state_precheck(shell)) {
- return 0;
- }
- return log_go(shell, shell->log_backend->backend, argc, argv);
- }
- static int cmd_log_backend_go(const struct shell *shell,
- size_t argc, char **argv)
- {
- return shell_backend_cmd_execute(shell, argc, argv, log_go);
- }
- static int cmd_log_backends_list(const struct shell *shell,
- size_t argc, char **argv)
- {
- int backend_count;
- backend_count = log_backend_count_get();
- for (int i = 0; i < backend_count; i++) {
- const struct log_backend *backend = log_backend_get(i);
- shell_fprintf(shell, SHELL_NORMAL,
- "%s\r\n"
- "\t- Status: %s\r\n"
- "\t- ID: %d\r\n\r\n",
- backend->name,
- backend->cb->active ? "enabled" : "disabled",
- backend->cb->id);
- }
- return 0;
- }
- static int cmd_log_strdup_utilization(const struct shell *shell,
- size_t argc, char **argv)
- {
- /* Defines needed when string duplication is disabled (LOG_IMMEDIATE is
- * on). In that case, this function is not compiled in.
- */
- #ifndef CONFIG_LOG_STRDUP_BUF_COUNT
- #define CONFIG_LOG_STRDUP_BUF_COUNT 0
- #endif
- #ifndef CONFIG_LOG_STRDUP_MAX_STRING
- #define CONFIG_LOG_STRDUP_MAX_STRING 0
- #endif
- uint32_t cur_cnt = log_get_strdup_pool_current_utilization();
- uint32_t buf_cnt = log_get_strdup_pool_utilization();
- uint32_t buf_size = log_get_strdup_longest_string();
- uint32_t percent = CONFIG_LOG_STRDUP_BUF_COUNT ?
- buf_cnt * 100U / CONFIG_LOG_STRDUP_BUF_COUNT : 0U;
- shell_print(shell, "Current utilization of the buffer pool: %d.",
- cur_cnt);
- shell_print(shell,
- "Maximal utilization of the buffer pool: %d / %d (%d %%).",
- buf_cnt, CONFIG_LOG_STRDUP_BUF_COUNT, percent);
- if (buf_cnt == CONFIG_LOG_STRDUP_BUF_COUNT) {
- shell_warn(shell, "Buffer count too small.");
- }
- shell_print(shell,
- "Longest duplicated string: %d, buffer capacity: %d.",
- buf_size, CONFIG_LOG_STRDUP_MAX_STRING);
- if (buf_size > CONFIG_LOG_STRDUP_MAX_STRING) {
- shell_warn(shell, "Buffer size too small.");
- }
- return 0;
- }
- static int cmd_log_memory_slabs(const struct shell *sh, size_t argc, char **argv)
- {
- uint32_t slabs_free;
- uint32_t used;
- uint32_t max;
- slabs_free = log_msg_mem_get_free();
- used = log_msg_mem_get_used();
- shell_print(sh, "Blocks used:\t%d", used);
- shell_print(sh, "Blocks free:\t%d", slabs_free);
- if (IS_ENABLED(CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION)) {
- max = log_msg_mem_get_max_used();
- shell_print(sh, "Blocks max:\t%d", max);
- } else {
- shell_print(
- sh,
- "Enable CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION to get max memory utilization");
- }
- return 0;
- }
- SHELL_STATIC_SUBCMD_SET_CREATE(sub_log_backend,
- SHELL_CMD_ARG(disable, &dsub_module_name,
- "'log disable <module_0> .. <module_n>' disables logs in "
- "specified modules (all if no modules specified).",
- cmd_log_backend_disable, 2, 255),
- SHELL_CMD_ARG(enable, &dsub_severity_lvl,
- "'log enable <level> <module_0> ... <module_n>' enables logs"
- " up to given level in specified modules (all if no modules "
- "specified).",
- cmd_log_backend_enable, 2, 255),
- SHELL_CMD(go, NULL, "Resume logging", cmd_log_backend_go),
- SHELL_CMD(halt, NULL, "Halt logging", cmd_log_backend_halt),
- SHELL_CMD(status, NULL, "Logger status", cmd_log_backend_status),
- SHELL_SUBCMD_SET_END
- );
- static void backend_name_get(size_t idx, struct shell_static_entry *entry)
- {
- entry->handler = NULL;
- entry->help = NULL;
- entry->subcmd = &sub_log_backend;
- entry->syntax = NULL;
- if (idx < log_backend_count_get()) {
- const struct log_backend *backend = log_backend_get(idx);
- entry->syntax = backend->name;
- }
- }
- SHELL_DYNAMIC_CMD_CREATE(dsub_backend_name_dynamic, backend_name_get);
- SHELL_STATIC_SUBCMD_SET_CREATE(
- sub_log_stat,
- SHELL_CMD(backend, &dsub_backend_name_dynamic, "Logger backends commands.", NULL),
- SHELL_COND_CMD_ARG(CONFIG_SHELL_LOG_BACKEND, disable, &dsub_module_name,
- "'log disable <module_0> .. <module_n>' disables logs in specified "
- "modules (all if no modules specified).",
- cmd_log_self_disable, 1, 255),
- SHELL_COND_CMD_ARG(CONFIG_SHELL_LOG_BACKEND, enable, &dsub_severity_lvl,
- "'log enable <level> <module_0> ... <module_n>' enables logs up to"
- " given level in specified modules (all if no modules specified).",
- cmd_log_self_enable, 2, 255),
- SHELL_COND_CMD(CONFIG_SHELL_LOG_BACKEND, go, NULL, "Resume logging", cmd_log_self_go),
- SHELL_COND_CMD(CONFIG_SHELL_LOG_BACKEND, halt, NULL, "Halt logging", cmd_log_self_halt),
- SHELL_CMD_ARG(list_backends, NULL, "Lists logger backends.", cmd_log_backends_list, 1, 0),
- SHELL_COND_CMD(CONFIG_SHELL_LOG_BACKEND, status, NULL, "Logger status",
- cmd_log_self_status),
- SHELL_COND_CMD_ARG(CONFIG_LOG_STRDUP_POOL_PROFILING, strdup_utilization, NULL,
- "Get utilization of string duplicates pool", cmd_log_strdup_utilization,
- 1, 0),
- SHELL_COND_CMD(CONFIG_LOG_MODE_DEFERRED, mem, NULL, "Logger memory usage",
- cmd_log_memory_slabs),
- SHELL_SUBCMD_SET_END);
- SHELL_CMD_REGISTER(log, &sub_log_stat, "Commands for controlling logger",
- NULL);
|