From: Stephen Hemminger Date: Wed, 25 Apr 2018 03:17:49 +0000 (-0700) Subject: log: add ability to match log type with globbing X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=7f0bb634a1406b132ff15c9cd56a0a9f33e5f11d;p=dpdk.git log: add ability to match log type with globbing Regular expressions are not the best way to match a hierarchical pattern like dynamic log levels. And the separator for dynamic log levels is period which is the regex wildcard character. A better solution is to use filename matching 'globbing' so that log levels match like file paths. For compatibility, use colon to separate pattern match style arguments. For example: --log-level 'pmd.net.virtio.*:debug' This also makes the documentation match what really happens internally. Signed-off-by: Stephen Hemminger --- diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst index b0f0adb887..25876059bb 100644 --- a/doc/guides/contributing/coding_style.rst +++ b/doc/guides/contributing/coding_style.rst @@ -614,8 +614,8 @@ In the DPDK environment, use the logging interface provided: * is DEBUG) */ rte_log_set_level(my_logtype2, RTE_LOG_NOTICE); - /* enable all PMD logs (whose identifier string starts with "pmd") */ - rte_log_set_level_regexp("pmd.*", RTE_LOG_DEBUG); + /* enable all PMD logs (whose identifier string starts with "pmd.") */ + rte_log_set_level_pattern("pmd.*", RTE_LOG_DEBUG); /* log in debug level */ rte_log_set_global_level(RTE_LOG_DEBUG); diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst index 63ce9b4c60..42dd70db39 100644 --- a/doc/guides/nics/qede.rst +++ b/doc/guides/nics/qede.rst @@ -193,7 +193,7 @@ This section provides instructions to configure SR-IOV with Linux OS. #. Running testpmd - (Supply ``--log-level="pmd.net.qede.driver",7`` to view informational messages): + (Supply ``--log-level="pmd.net.qede.driver:7`` to view informational messages): Refer to the document :ref:`compiling and testing a PMD for a NIC ` to run diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c index c04bcde878..c660ca6592 100644 --- a/lib/librte_eal/common/eal_common_log.c +++ b/lib/librte_eal/common/eal_common_log.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,8 @@ struct rte_eal_opt_loglevel { TAILQ_ENTRY(rte_eal_opt_loglevel) next; /** Compiled regular expression obtained from the option */ regex_t re_match; + /** Glob match string option */ + char *pattern; /** Log level value obtained from the option */ uint32_t level; }; @@ -104,9 +107,9 @@ rte_log_set_level(uint32_t type, uint32_t level) return 0; } -/* set level */ +/* set log level by regular expression */ int -rte_log_set_level_regexp(const char *pattern, uint32_t level) +rte_log_set_level_regexp(const char *regex, uint32_t level) { regex_t r; size_t i; @@ -114,7 +117,7 @@ rte_log_set_level_regexp(const char *pattern, uint32_t level) if (level > RTE_LOG_DEBUG) return -1; - if (regcomp(&r, pattern, 0) != 0) + if (regcomp(&r, regex, 0) != 0) return -1; for (i = 0; i < rte_logs.dynamic_types_len; i++) { @@ -131,24 +134,30 @@ rte_log_set_level_regexp(const char *pattern, uint32_t level) } /* - * Save the type (regexp string) and the loglevel - * in the global storage so that it could be used - * to configure dynamic logtypes which are absent - * at the moment of EAL option processing but may - * be registered during runtime. + * Save the type string and the loglevel for later dynamic + * logtypes which may register later. */ -int rte_log_save_regexp(const char *regex, int tmp) +static int rte_log_save_level(int priority, + const char *regex, const char *pattern) { - struct rte_eal_opt_loglevel *opt_ll; + struct rte_eal_opt_loglevel *opt_ll = NULL; opt_ll = malloc(sizeof(*opt_ll)); if (opt_ll == NULL) - return -1; - - if (regcomp(&opt_ll->re_match, regex, 0) != 0) goto fail; - opt_ll->level = tmp; + opt_ll->level = priority; + + if (regex) { + opt_ll->pattern = NULL; + if (regcomp(&opt_ll->re_match, regex, 0) != 0) + goto fail; + } else if (pattern) { + opt_ll->pattern = strdup(pattern); + if (opt_ll->pattern == NULL) + goto fail; + } else + goto fail; TAILQ_INSERT_HEAD(&opt_loglevel_list, opt_ll, next); return 0; @@ -157,6 +166,36 @@ fail: return -1; } +int rte_log_save_regexp(const char *regex, int tmp) +{ + return rte_log_save_level(tmp, regex, NULL); +} + +/* set log level based on glob (file match) pattern */ +int +rte_log_set_level_pattern(const char *pattern, uint32_t level) +{ + size_t i; + + if (level > RTE_LOG_DEBUG) + return -1; + + for (i = 0; i < rte_logs.dynamic_types_len; i++) { + if (rte_logs.dynamic_types[i].name == NULL) + continue; + + if (fnmatch(pattern, rte_logs.dynamic_types[i].name, 0)) + rte_logs.dynamic_types[i].loglevel = level; + } + + return 0; +} + +int rte_log_save_pattern(const char *pattern, int priority) +{ + return rte_log_save_level(priority, NULL, pattern); +} + /* get the current loglevel for the message being processed */ int rte_log_cur_msg_loglevel(void) { @@ -244,8 +283,13 @@ rte_log_register_type_and_pick_level(const char *name, uint32_t level_def) if (opt_ll->level > RTE_LOG_DEBUG) continue; - if (regexec(&opt_ll->re_match, name, 0, NULL, 0) == 0) - level = opt_ll->level; + if (opt_ll->pattern) { + if (fnmatch(opt_ll->pattern, name, 0)) + level = opt_ll->level; + } else { + if (regexec(&opt_ll->re_match, name, 0, NULL, 0) == 0) + level = opt_ll->level; + } } rte_logs.dynamic_types[type].loglevel = level; diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c index 522aa9ea69..ecebb29231 100644 --- a/lib/librte_eal/common/eal_common_options.c +++ b/lib/librte_eal/common/eal_common_options.c @@ -959,19 +959,23 @@ eal_parse_log_priority(const char *level) static int eal_parse_log_level(const char *arg) { - char *str, *type, *level; + const char *pattern = NULL; + const char *regex = NULL; + char *str, *level; int priority; str = strdup(arg); if (str == NULL) return -1; - if (strchr(str, ',') == NULL) { - type = NULL; - level = str; + if ((level = strchr(str, ','))) { + regex = str; + *level++ = '\0'; + } else if ((level = strchr(str, ':'))) { + pattern = str; + *level++ = '\0'; } else { - type = strsep(&str, ","); - level = strsep(&str, ","); + level = str; } priority = eal_parse_log_priority(level); @@ -980,14 +984,24 @@ eal_parse_log_level(const char *arg) goto fail; } - if (type == NULL) { + if (regex) { + if (rte_log_set_level_regexp(regex, priority) < 0) { + fprintf(stderr, "cannot set log level %s,%d\n", + pattern, priority); + goto fail; + } + if (rte_log_save_regexp(regex, priority) < 0) + goto fail; + } else if (pattern) { + if (rte_log_set_level_pattern(pattern, priority) < 0) { + fprintf(stderr, "cannot set log level %s:%d\n", + pattern, priority); + goto fail; + } + if (rte_log_save_pattern(pattern, priority) < 0) + goto fail; + } else { rte_log_set_global_level(priority); - } else if (rte_log_set_level_regexp(type, priority) < 0) { - fprintf(stderr, "cannot set log level %s,%d\n", - type, priority); - goto fail; - } else if (rte_log_save_regexp(type, priority) < 0) { - goto fail; } free(str); @@ -1352,7 +1366,7 @@ eal_common_usage(void) " --"OPT_PROC_TYPE" Type of this process (primary|secondary|auto)\n" " --"OPT_SYSLOG" Set syslog facility\n" " --"OPT_LOG_LEVEL"= Set global log level\n" - " --"OPT_LOG_LEVEL"=,\n" + " --"OPT_LOG_LEVEL"=:\n" " Set specific log level\n" " -v Display version information on startup\n" " -h, --help This help\n" diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index a2d2def2ba..bdadc4d502 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -86,6 +86,7 @@ int rte_eal_log_init(const char *id, int facility); * Save the log regexp for later */ int rte_log_save_regexp(const char *type, int priority); +int rte_log_save_pattern(const char *pattern, int priority); /** * Init tail queues for non-EAL library structures. This is to allow diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h index 2d817c3da7..2f789cb902 100644 --- a/lib/librte_eal/common/include/rte_log.h +++ b/lib/librte_eal/common/include/rte_log.h @@ -130,16 +130,28 @@ uint32_t rte_log_get_global_level(void); int rte_log_get_level(uint32_t logtype); /** - * Set the log level for a given type. + * Set the log level for a given type based on shell pattern. * * @param pattern - * The regexp identifying the log type. + * The match pattern identifying the log type. + * @param level + * The level to be set. + * @return + * 0 on success, a negative value if level is invalid. + */ +int rte_log_set_level_pattern(const char *pattern, uint32_t level); + +/** + * Set the log level for a given type based on regular expression. + * + * @param regex + * The regular expression identifying the log type. * @param level * The level to be set. * @return * 0 on success, a negative value if level is invalid. */ -int rte_log_set_level_regexp(const char *pattern, uint32_t level); +int rte_log_set_level_regexp(const char *regex, uint32_t level); /** * Set the log level for a given type. diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 42540ff7a8..02fb9cc806 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -209,6 +209,13 @@ DPDK_18.02 { } DPDK_17.11; +DPDK_18.05 { + global: + + rte_log_set_level_pattern; + +} DPDK_18.02; + EXPERIMENTAL { global: