From patchwork Tue Apr 24 16:58:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 38834 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 B115C5942; Tue, 24 Apr 2018 18:58:25 +0200 (CEST) Received: from mail-pg0-f67.google.com (mail-pg0-f67.google.com [74.125.83.67]) by dpdk.org (Postfix) with ESMTP id 6A5754CC0 for ; Tue, 24 Apr 2018 18:58:18 +0200 (CEST) Received: by mail-pg0-f67.google.com with SMTP id m21so8295715pgv.8 for ; Tue, 24 Apr 2018 09:58:18 -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=FqtDHNm+zZzwoDouMu0RdYhsBTsiur6U+0XtNoBJslI=; b=vDZzv+ik66m4OVmtI8Ec4SY2oBifApn01gZjs9lwujQbS5M2IDyLerrWBPzPI1sAx6 W1CQrQVrgx9lJLOQttoakGsBctX4cvl8i/dORyaonm9iNGy4lJOxmE+mlE7NbSARv0e0 A3Qy161IuAvCqD+x6Lt4dR1IvkykFnw9GNaJyft/oe0nPd5YZJ/Fq1y34S9vD3tCnLwG SICbPOsMV+smuHJp6JBwjNdugJH+jeSAWakJ8wCvU0wA4YmGCmCFIhr29/iGz33UfdrI uVJmNjHJNlcJM03TQbFXEBV92o2aR5c3ae/sWrLi0pairy8jWLBMmQAG2qse/MyNeWyO UGAQ== 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=FqtDHNm+zZzwoDouMu0RdYhsBTsiur6U+0XtNoBJslI=; b=e9B7gWZnbe+t3d835yZyxfgmKpsDbGyBX0zZWRaf89K2PfraBzlUO+FBUXpUCvD5kY SofZSCWlHDQQUArn5oygjDgZ9ce/TVD7/DsmEkEME9PHjIOHLdmA3PLd7T91RaDbby+I KHbgouEpLq1psRtQ9fHaYDuYNvDbin+gMzGDCkZHJ8kOW+UVmN4XgP408UOFLX6M28fh S0rdAhWwkDbos5rxqYI1c81k3tjsbgfkkbC/p0F/7V7fSfsXV3TufDk/OaBQrN4/u3Yi C08Y/dcMMq87JBds/vniogOP3aIi0Pc+dX9XnbkDyJAV0UdqpoAaGtJaEeE+h9eVMFxO S8AQ== X-Gm-Message-State: ALQs6tBDHqFQo/fhf6mzo+0nKE8duVhPOOYJkJhaeiFl3q7aT4xCqBdF rRM4HFIgW6qkyNAQhPw/I19sXK7wsP0= X-Google-Smtp-Source: AIpwx489IfYOVHXMri5yqHaC6fKBDbRroCF1ouJ4180ZQFhXvz+ru2+xibjhy0iVHCId4R+QAp4iOg== X-Received: by 10.98.90.135 with SMTP id o129mr24729100pfb.38.1524589097222; Tue, 24 Apr 2018 09:58:17 -0700 (PDT) Received: from xeon-e3.lan (204-195-71-95.wavecable.com. [204.195.71.95]) by smtp.gmail.com with ESMTPSA id a28sm19851114pfl.86.2018.04.24.09.58.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Apr 2018 09:58:16 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Date: Tue, 24 Apr 2018 09:58:07 -0700 Message-Id: <20180424165808.23292-5-stephen@networkplumber.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180424165808.23292-1-stephen@networkplumber.org> References: <20180424165808.23292-1-stephen@networkplumber.org> Subject: [dpdk-dev] [PATCH v2 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 | 2 +- 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 | 3 +- lib/librte_eal/common/include/rte_log.h | 18 ++++- 6 files changed, 107 insertions(+), 36 deletions(-) diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst index b0f0adb887b4..365a4b17a983 100644 --- a/doc/guides/contributing/coding_style.rst +++ b/doc/guides/contributing/coding_style.rst @@ -615,7 +615,7 @@ In the DPDK environment, use the logging interface provided: 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); + rte_log_set_level_match("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 c47e53b3db74..d1484dacd98f 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_eal_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_eal_log_save_regexp(const char *regex, int tmp) return -1; } +int rte_eal_log_save_regexp(const char *regex, int priority) +{ + return rte_log_save_level(priority, 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_eal_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 038e75d86348..604aef2b56e0 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_eal_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_eal_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_eal_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 d505a9a3c76f..c2f541c169a9 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -85,7 +85,8 @@ int rte_eal_log_init(const char *id, int facility); /** * Save the log regexp for later */ -int rte_eal_log_save_regexp(const char *type, int priority); +int rte_eal_log_save_regexp(const char *regex, int priority); +int rte_eal_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.