From patchwork Wed Apr 25 03:17:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 38858 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id F24E34C76; Wed, 25 Apr 2018 05:18:07 +0200 (CEST) Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by dpdk.org (Postfix) with ESMTP id 275972B86 for ; Wed, 25 Apr 2018 05:18:00 +0200 (CEST) Received: by mail-pf0-f195.google.com with SMTP id z9so13978126pfe.6 for ; Tue, 24 Apr 2018 20:18:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Se6Udo18Kl4a87X5XzVWWbct3zNLtVlNaYLS/UUajRw=; b=1372jYzHYPSfbY1hWYGmBcvz8hHohx7FRtVFv84KkYDy3F01tEesfD5PoyxqkaPWKC V2TQlHchQ9ffq9IEC5FkbZGAc+XmFNQR+q3WzeO6VowBorIESQINh3zKA73miIpnF2J3 wzs7c2oKY85wlcC/sKmo/09TlvDHG1Xk9t43bXeF4u74hv+Vmzibi1VjnoE3h4YXxs2Y VwewhjOdZMekeC/DpBEoiKLVIMcUt/OqVcUSvsxWKaVBNLVasFizcuqa4Xa7qocx4WHU fT/M3BUVQ/MGC4RpKS6Rtt5Roh/kuXycUgndAng7SC0nN+AQZQeQmEv/YNypseU4DFaD Y3jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Se6Udo18Kl4a87X5XzVWWbct3zNLtVlNaYLS/UUajRw=; b=q5Z5HgWXuoGd9x2N9kwzEyVovgdpi2cbMcpVQBmTe6SekKW1sRnVO5SaSl27rTqKyE LMEZgnmH8Xm/tiASReKe4YG9psyalWPfqSdUfSmuGsujGc8pi4qQx85dEN34QESm9YOL P1/vgieS9ivDFNIlWiTG66EE3DLpPcX+AUcFrSgKklzfPVRGbYg/nNXeNGg3MZAZx+wM NwmkT716dlFz4AQbBsygH8WO9QA+siKGVkD9y0GHZpyUxDsO8ytZOiH+abwPzbtuoFGF X2hXpAuC9q/AmzrtKmYu+oZXsxyiY4ZNEzfleXZ2Ofm9k15C4OolgZEqXEm1sAy4Hd/Z YQIQ== X-Gm-Message-State: ALQs6tD534udrPaCeOgqoPhEpOhMesPotcThO5JPrMogEL5ehM17qRVJ Xpjic4XniqyWjVcOaFxill3Mdq0vDBY= X-Google-Smtp-Source: AIpwx48VQOOGqkh5AVLInATy5lD9EkHpCNv9PTF0jA28hKtpr0EWMLvhuXITTkgIZZlTV8DZxx/E0Q== X-Received: by 2002:a17:902:24c:: with SMTP id 70-v6mr27682628plc.384.1524626278623; Tue, 24 Apr 2018 20:17:58 -0700 (PDT) Received: from xeon-e3.lan (204-195-71-95.wavecable.com. [204.195.71.95]) by smtp.gmail.com with ESMTPSA id x5sm20137303pfh.115.2018.04.24.20.17.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Apr 2018 20:17:57 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Date: Tue, 24 Apr 2018 20:17:49 -0700 Message-Id: <20180425031750.30973-5-stephen@networkplumber.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180425031750.30973-1-stephen@networkplumber.org> References: <20180425031750.30973-1-stephen@networkplumber.org> Subject: [dpdk-dev] [PATCH v3 4/5] log: add ability to match dynamic log based on shell pattern X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- doc/guides/contributing/coding_style.rst | 4 +- doc/guides/nics/qede.rst | 2 +- lib/librte_eal/common/eal_common_log.c | 76 +++++++++++++++++----- lib/librte_eal/common/eal_common_options.c | 42 ++++++++---- lib/librte_eal/common/eal_private.h | 1 + lib/librte_eal/common/include/rte_log.h | 18 ++++- lib/librte_eal/rte_eal_version.map | 7 ++ 7 files changed, 114 insertions(+), 36 deletions(-) diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst index b0f0adb887b4..25876059bb53 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 63ce9b4c60c6..42dd70db39df 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 c04bcde87853..c660ca659252 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 @@ int rte_log_save_regexp(const char *regex, int tmp) 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 522aa9ea6974..ecebb2923131 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 a2d2def2bac7..bdadc4d502f5 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 2d817c3da7c1..2f789cb90293 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 42540ff7a890..fa7dcd6d7e06 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: