All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>
Subject: [PATCH v2 4/5] log: add ability to match dynamic log based on shell pattern
Date: Tue, 24 Apr 2018 09:58:07 -0700	[thread overview]
Message-ID: <20180424165808.23292-5-stephen@networkplumber.org> (raw)
In-Reply-To: <20180424165808.23292-1-stephen@networkplumber.org>

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 <stephen@networkplumber.org>
---
 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 <pmd_build_and_test>` 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 <string.h>
 #include <errno.h>
 #include <regex.h>
+#include <fnmatch.h>
 
 #include <rte_eal.h>
 #include <rte_log.h>
@@ -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"=<int>   Set global log level\n"
-	       "  --"OPT_LOG_LEVEL"=<type-regexp>,<int>\n"
+	       "  --"OPT_LOG_LEVEL"=<type-match>:<int>\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.
-- 
2.17.0

  parent reply	other threads:[~2018-04-24 16:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-24 16:58 [PATCH v2 0/5] logging enhancements Stephen Hemminger
2018-04-24 16:58 ` [PATCH v2 1/5] eal: make syslog facility table const Stephen Hemminger
2018-04-24 16:58 ` [PATCH v2 2/5] eal: allow symbolic log levels Stephen Hemminger
2018-04-24 16:58 ` [PATCH v2 3/5] eal: make eal_log_level save private Stephen Hemminger
2018-04-24 23:55   ` Thomas Monjalon
2018-04-24 16:58 ` Stephen Hemminger [this message]
2018-04-25  0:02   ` [PATCH v2 4/5] log: add ability to match dynamic log based on shell pattern Thomas Monjalon
2018-04-25  0:08   ` Thomas Monjalon
2018-04-24 16:58 ` [PATCH v2 5/5] doc: update guides for current preferrred log level syntax Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180424165808.23292-5-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.