<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/10884">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">logging vty: rewrite 'logging level' vty cmd generation<br><br>Completely drop the implementations of log_vty_command_{str,description}().<br>These functions have been public API once, marked as deprecated since<br>c65c5b4ea075ef6cef11fff9442ae0b15c1d6af7 (March 2017). I considered to keep<br>them, or reduce them to useless stubs, but it is quite silly, really. These<br>functions are completely and utterly useless outside of libosmocore. Any<br>program linking these deserves to fail.<br><br>Re-implement vty logging level command gen, in logging_vty.c. logging.c is<br>simply the wrong place for that.<br><br>Introduce logging_internal.h to share logging definitions to logging_vty.c<br>without publishing as API.<br><br>Introduce static gen_logging_level_cmd_strs() to compose a list of category<br>arguments with their descriptions for VTY commands. Use osmo_talloc_asprintf()<br>instead of the previous error prone and chaotic strlen() counting method.<br><br>Do not dynamically generate log level arguments, just keep static strings. We<br>are super unlikely to ever change the log levels we have.<br><br>No changes in logging_vty_test.vty: proves that there is no functional change.<br><br>All of this, besides introducing basic sanity, is cosmetic preparation to be<br>able to re-use the generic command generation code for arbitrary commands with<br>category or level args (for deprecated and new keywords).<br><br>Rationale: I want to hide 'all' and 'everything' from the VTY command<br>documentation, by means of deprecating. I first tried to simply define a<br>deprecated 'logging level CAT everything' command:<br><br>  logging level (all|rsl|rr|...) (debug|info|notice|error|fatal)<br>  logging level CAT everything                   # <- deprecated and hidden<br><br>But unfortunately, command matching doesn't work as intended when the CAT<br>argument reflects a valid category; I want it to invoke the deprecated function<br>as soon as the 'everything' keyword follows, but it stays stuck to the "valid"<br>command when the category argument matches an explicit keyword in that list,<br>and will throw an error on the following 'everything' keyword. I.e.:<br><br>  logging level rsl everything<br>  % Unknown command  # <-- leads to config file parse error<br><br>  logging level unknown_string everything<br>  % Ignoring deprecated 'everything'  # <-- works only for invalid categories<br><br>So I need to define 'everything' separately, again with a list of each valid<br>category instead of a generic CAT arg.<br><br>Change-Id: I3b083f27e3d751ccec258880ae7676e9af959a63<br>---<br>M include/Makefile.am<br>M include/osmocom/core/logging.h<br>A include/osmocom/core/logging_internal.h<br>M src/logging.c<br>M src/vty/logging_vty.c<br>5 files changed, 82 insertions(+), 172 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index ef8ec65..19695d1 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -152,7 +152,10 @@</span><br><span> endif</span><br><span> </span><br><span> noinst_HEADERS = \</span><br><span style="color: hsl(0, 100%, 40%);">- osmocom/gsm/kasumi.h osmocom/gsm/gea.h</span><br><span style="color: hsl(120, 100%, 40%);">+        osmocom/gsm/kasumi.h \</span><br><span style="color: hsl(120, 100%, 40%);">+        osmocom/gsm/gea.h \</span><br><span style="color: hsl(120, 100%, 40%);">+   osmocom/core/logging_internal.h \</span><br><span style="color: hsl(120, 100%, 40%);">+     $(NULL)</span><br><span> </span><br><span> osmocom/core/bit%gen.h: osmocom/core/bitXXgen.h.tpl</span><br><span>   $(AM_V_GEN)$(MKDIR_P) $(dir $@)</span><br><span>diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h</span><br><span>index c60143d..295e5a8 100644</span><br><span>--- a/include/osmocom/core/logging.h</span><br><span>+++ b/include/osmocom/core/logging.h</span><br><span>@@ -374,10 +374,6 @@</span><br><span> void log_add_target(struct log_target *target);</span><br><span> void log_del_target(struct log_target *target);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Generate command string for VTY use */</span><br><span style="color: hsl(0, 100%, 40%);">-const char *log_vty_command_string() OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE;</span><br><span style="color: hsl(0, 100%, 40%);">-const char *log_vty_command_description() OSMO_DEPRECATED_OUTSIDE_LIBOSMOCORE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> struct log_target *log_target_find(int type, const char *fname);</span><br><span> extern struct llist_head osmo_log_target_list;</span><br><span> </span><br><span>diff --git a/include/osmocom/core/logging_internal.h b/include/osmocom/core/logging_internal.h</span><br><span>new file mode 100644</span><br><span>index 0000000..55b1bbd</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/core/logging_internal.h</span><br><span>@@ -0,0 +1,14 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup logging_internal Osmocom logging internals</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file logging_internal.h */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern void *tall_log_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct log_info *osmo_log_info;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void assert_loginfo(const char *src);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/logging.c b/src/logging.c</span><br><span>index de0f2b0..7c2d61f 100644</span><br><span>--- a/src/logging.c</span><br><span>+++ b/src/logging.c</span><br><span>@@ -35,7 +35,6 @@</span><br><span> #include <stdlib.h></span><br><span> #include <stdio.h></span><br><span> #include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <ctype.h></span><br><span> </span><br><span> #ifdef HAVE_STRINGS_H</span><br><span> #include <strings.h></span><br><span>@@ -61,12 +60,10 @@</span><br><span> struct log_info *osmo_log_info;</span><br><span> </span><br><span> static struct log_context log_context;</span><br><span style="color: hsl(0, 100%, 40%);">-static void *tall_log_ctx = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+void *tall_log_ctx = NULL;</span><br><span> LLIST_HEAD(osmo_log_target_list);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define LOGLEVEL_DEFS        6       /* Number of loglevels.*/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string loglevel_strs[LOGLEVEL_DEFS+1] = {</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct value_string loglevel_strs[] = {</span><br><span>   { 0,            "EVERYTHING" },</span><br><span>    { LOGL_DEBUG,   "DEBUG" },</span><br><span>         { LOGL_INFO,    "INFO" },</span><br><span>@@ -175,19 +172,7 @@</span><br><span>   },</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! descriptive string for each log level */</span><br><span style="color: hsl(0, 100%, 40%);">-/* You have to keep this in sync with the structure loglevel_strs. */</span><br><span style="color: hsl(0, 100%, 40%);">-static const char *loglevel_descriptions[LOGLEVEL_DEFS+1] = {</span><br><span style="color: hsl(0, 100%, 40%);">-      "Don't use. It doesn't log anything",</span><br><span style="color: hsl(0, 100%, 40%);">- "Log debug messages and higher levels",</span><br><span style="color: hsl(0, 100%, 40%);">-       "Log informational messages and higher levels",</span><br><span style="color: hsl(0, 100%, 40%);">-       "Log noticeable messages and higher levels",</span><br><span style="color: hsl(0, 100%, 40%);">-  "Log error messages and higher levels",</span><br><span style="color: hsl(0, 100%, 40%);">-       "Log only fatal messages",</span><br><span style="color: hsl(0, 100%, 40%);">-    NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void assert_loginfo(const char *src)</span><br><span style="color: hsl(120, 100%, 40%);">+void assert_loginfo(const char *src)</span><br><span> {</span><br><span>        if (!osmo_log_info) {</span><br><span>                fprintf(stderr, "ERROR: osmo_log_info == NULL! "</span><br><span>@@ -963,149 +948,6 @@</span><br><span>   return rc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! Generates the logging command string for VTY</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] unused_info Deprecated parameter, no longer used!</span><br><span style="color: hsl(0, 100%, 40%);">- *  \returns vty command string for use by VTY command node</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-const char *log_vty_command_string()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct log_info *info = osmo_log_info;</span><br><span style="color: hsl(0, 100%, 40%);">-  int len = 0, offset = 0, ret, i, rem;</span><br><span style="color: hsl(0, 100%, 40%);">-   int size = strlen("logging level (all|) ()") + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     char *str;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      assert_loginfo(__func__);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < info->num_cat; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (info->cat[i].name == NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               size += strlen(info->cat[i].name) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < LOGLEVEL_DEFS; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-          size += strlen(loglevel_strs[i].str) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rem = size;</span><br><span style="color: hsl(0, 100%, 40%);">-     str = talloc_zero_size(tall_log_ctx, size);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!str)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ret = snprintf(str + offset, rem, "logging level (all|");</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < info->num_cat; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (info->cat[i].name) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     int j, name_len = strlen(info->cat[i].name)+1;</span><br><span style="color: hsl(0, 100%, 40%);">-                       char name[name_len];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                    for (j = 0; j < name_len; j++)</span><br><span style="color: hsl(0, 100%, 40%);">-                               name[j] = tolower((unsigned char)info->cat[i].name[j]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      name[name_len-1] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-                        ret = snprintf(str + offset, rem, "%s|", name+1);</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-                       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       offset--;       /* to remove the trailing | */</span><br><span style="color: hsl(0, 100%, 40%);">-  rem++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  ret = snprintf(str + offset, rem, ") (");</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < LOGLEVEL_DEFS; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                int j, loglevel_str_len = strlen(loglevel_strs[i].str)+1;</span><br><span style="color: hsl(0, 100%, 40%);">-               char loglevel_str[loglevel_str_len];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            for (j = 0; j < loglevel_str_len; j++)</span><br><span style="color: hsl(0, 100%, 40%);">-                       loglevel_str[j] = tolower((unsigned char)loglevel_strs[i].str[j]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              loglevel_str[loglevel_str_len-1] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-                ret = snprintf(str + offset, rem, "%s|", loglevel_str);</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                 goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       offset--;       /* to remove the trailing | */</span><br><span style="color: hsl(0, 100%, 40%);">-  rem++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  ret = snprintf(str + offset, rem, ")");</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-err:</span><br><span style="color: hsl(0, 100%, 40%);">-   str[size-1] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-     return str;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! Generates the logging command description for VTY</span><br><span style="color: hsl(0, 100%, 40%);">- *  \param[in] unused_info Deprecated parameter, no longer used!</span><br><span style="color: hsl(0, 100%, 40%);">- *  \returns logging command description for use by VTY command node</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-const char *log_vty_command_description()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct log_info *info = osmo_log_info;</span><br><span style="color: hsl(0, 100%, 40%);">-  char *str;</span><br><span style="color: hsl(0, 100%, 40%);">-      int i, ret, len = 0, offset = 0, rem;</span><br><span style="color: hsl(0, 100%, 40%);">-   unsigned int size =</span><br><span style="color: hsl(0, 100%, 40%);">-             strlen(LOGGING_STR</span><br><span style="color: hsl(0, 100%, 40%);">-                     "Set the log level for a specified category\n") + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   assert_loginfo(__func__);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < info->num_cat; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (info->cat[i].name == NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               size += strlen(info->cat[i].description) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < LOGLEVEL_DEFS; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-          size += strlen(loglevel_descriptions[i]) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   size += strlen("Global setting for all subsystems") + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-      rem = size;</span><br><span style="color: hsl(0, 100%, 40%);">-     str = talloc_zero_size(tall_log_ctx, size);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!str)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ret = snprintf(str + offset, rem, LOGGING_STR</span><br><span style="color: hsl(0, 100%, 40%);">-                   "Set the log level for a specified category\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = snprintf(str + offset, rem,</span><br><span style="color: hsl(0, 100%, 40%);">-                       "Global setting for all subsystems\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < info->num_cat; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (info->cat[i].name == NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               ret = snprintf(str + offset, rem, "%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             info->cat[i].description);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                 goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < LOGLEVEL_DEFS; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ret = snprintf(str + offset, rem, "%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             loglevel_descriptions[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                 goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-err:</span><br><span style="color: hsl(0, 100%, 40%);">-   str[size-1] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-     return str;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*! Initialize the Osmocom logging core</span><br><span>  *  \param[in] inf Information regarding logging categories</span><br><span>  *  \param[in] ctx \ref talloc context for logging allocations</span><br><span>diff --git a/src/vty/logging_vty.c b/src/vty/logging_vty.c</span><br><span>index 7d97bb1..2b001bc 100644</span><br><span>--- a/src/vty/logging_vty.c</span><br><span>+++ b/src/vty/logging_vty.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging_internal.h></span><br><span> #include <osmocom/core/utils.h></span><br><span> #include <osmocom/core/strrb.h></span><br><span> #include <osmocom/core/loggingrb.h></span><br><span>@@ -40,6 +41,19 @@</span><br><span> #include <osmocom/vty/logging.h></span><br><span> </span><br><span> #define LOG_STR "Configure logging sub-system\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define LEVEL_STR "Set the log level for a specified category\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CATEGORY_ALL_STR "Global setting for all subsystems\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOG_LEVEL_ARGS "debug|info|notice|error|fatal"</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOG_LEVEL_STRS \</span><br><span style="color: hsl(120, 100%, 40%);">+        "Log debug messages and higher levels\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+  "Log informational messages and higher levels\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+  "Log noticeable messages and higher levels\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+     "Log error messages and higher levels\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+  "Log only fatal messages\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define EVERYTHING_STR "Don't use. It doesn't log anything\n"</span><br><span> </span><br><span> /*! \file logging_vty.c</span><br><span>  *  Configuration of logging from VTY</span><br><span>@@ -58,8 +72,6 @@</span><br><span>  *</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-extern const struct log_info *osmo_log_info;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void _vty_output(struct log_target *tgt,</span><br><span>                         unsigned int level, const char *line)</span><br><span> {</span><br><span>@@ -268,6 +280,47 @@</span><br><span>    return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void add_category_strings(char **cmd_str_p, char **doc_str_p,</span><br><span style="color: hsl(120, 100%, 40%);">+                             const struct log_info *categories)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < categories->num_cat; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (categories->cat[i].name == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* skip the leading 'D' in each category name, hence '+ 1' */</span><br><span style="color: hsl(120, 100%, 40%);">+         osmo_talloc_asprintf(tall_log_ctx, *cmd_str_p, "%s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   i ? "|" : "",</span><br><span style="color: hsl(120, 100%, 40%);">+                                     osmo_str_tolower(categories->cat[i].name + 1));</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_talloc_asprintf(tall_log_ctx, *doc_str_p, "%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   categories->cat[i].description);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void gen_logging_level_cmd_strs(struct cmd_element *cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      const char *level_args, const char *level_strs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     char *cmd_str = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *doc_str = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       assert_loginfo(__func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(cmd->string == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(cmd->doc == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_talloc_asprintf(tall_log_ctx, cmd_str, "logging level (all|");</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_talloc_asprintf(tall_log_ctx, doc_str,</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGGING_STR</span><br><span style="color: hsl(120, 100%, 40%);">+                           LEVEL_STR</span><br><span style="color: hsl(120, 100%, 40%);">+                             CATEGORY_ALL_STR);</span><br><span style="color: hsl(120, 100%, 40%);">+       add_category_strings(&cmd_str, &doc_str, osmo_log_info);</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_talloc_asprintf(tall_log_ctx, cmd_str, ") %s", level_args);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_talloc_asprintf(tall_log_ctx, doc_str, "%s", level_strs);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    cmd->string = cmd_str;</span><br><span style="color: hsl(120, 100%, 40%);">+     cmd->doc = doc_str;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* logging level (all|<categories>) (everything|debug|...|fatal) */</span><br><span> DEFUN(logging_level,</span><br><span>       logging_level_cmd,</span><br><span>       NULL, /* cmdstr is dynamically set in logging_vty_add_cmds(). */</span><br><span>@@ -847,7 +900,7 @@</span><br><span>                               name);</span><br><span>   printf("%s\n", cmd->string);</span><br><span>    cmd->func = log_deprecated_func;</span><br><span style="color: hsl(0, 100%, 40%);">-     cmd->doc = "Set the log level for a specified category\n"</span><br><span style="color: hsl(120, 100%, 40%);">+        cmd->doc = LEVEL_STR</span><br><span>                 "Deprecated Category\n";</span><br><span>        cmd->attr = CMD_ATTR_DEPRECATED;</span><br><span> </span><br><span>@@ -871,9 +924,11 @@</span><br><span>       install_element_ve(&logging_set_category_mask_cmd);</span><br><span>      install_element_ve(&logging_set_category_mask_old_cmd);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Logging level strings are generated dynamically. */</span><br><span style="color: hsl(0, 100%, 40%);">-  logging_level_cmd.string = log_vty_command_string();</span><br><span style="color: hsl(0, 100%, 40%);">-    logging_level_cmd.doc = log_vty_command_description();</span><br><span style="color: hsl(120, 100%, 40%);">+        /* logging level (all|<categories>) (everything|debug|...|fatal) */</span><br><span style="color: hsl(120, 100%, 40%);">+     gen_logging_level_cmd_strs(&logging_level_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+                               "(everything|" LOG_LEVEL_ARGS ")",</span><br><span style="color: hsl(120, 100%, 40%);">+                                EVERYTHING_STR LOG_LEVEL_STRS);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         install_element_ve(&logging_level_cmd);</span><br><span>  install_element_ve(&show_logging_vty_cmd);</span><br><span>       install_element_ve(&show_alarms_cmd);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10884">change 10884</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10884"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I3b083f27e3d751ccec258880ae7676e9af959a63 </div>
<div style="display:none"> Gerrit-Change-Number: 10884 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>