<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/20029">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">logger: Add channel-based filtering.<br><br>This adds the ability to filter console<br>logging by channel or groups of channels.<br>This can be useful on busy systems where<br>an administrator would like to analyze certain<br>calls in detail. A dialplan application is also<br>included for the purpose of assigning a channel<br>to a group (e.g. by tenant, or some other metric).<br><br>Change-Id: I678550ab95ebf7d46c7acc17ec2f3a6fce31123e<br>---<br>A doc/CHANGES-staging/logger_cli.txt<br>M main/logger.c<br>2 files changed, 307 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/29/20029/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/logger_cli.txt b/doc/CHANGES-staging/logger_cli.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..5989c90</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/logger_cli.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: logger</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The console log can now be filtered by channels</span><br><span style="color: hsl(120, 100%, 40%);">+or groups of channels, using the logger filter</span><br><span style="color: hsl(120, 100%, 40%);">+CLI commands.</span><br><span>diff --git a/main/logger.c b/main/logger.c</span><br><span>index d742b49..df1d491 100644</span><br><span>--- a/main/logger.c</span><br><span>+++ b/main/logger.c</span><br><span>@@ -176,6 +176,7 @@</span><br><span>     int line;</span><br><span>    int lwp;</span><br><span>     ast_callid callid;</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int hidecli:1;         /*!< Whether to suppress log message from CLI output (but log normally to other log channels */</span><br><span>   AST_DECLARE_STRING_FIELDS(</span><br><span>           AST_STRING_FIELD(date);</span><br><span>              AST_STRING_FIELD(file);</span><br><span>@@ -1645,6 +1646,266 @@</span><br><span>    }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Call ID filtering */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_THREADSTORAGE(callid_group_name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief map call ID to group */</span><br><span style="color: hsl(120, 100%, 40%);">+struct chan_group_lock {</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_RWLIST_ENTRY(chan_group_lock) entry;</span><br><span style="color: hsl(120, 100%, 40%);">+      char name[0];</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%);">+AST_RWLIST_HEAD_STATIC(chan_group_lock_list, chan_group_lock);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int callid_filtering = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *ast_get_callid_group(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   char **callid_group;</span><br><span style="color: hsl(120, 100%, 40%);">+  callid_group = ast_threadstorage_get(&callid_group_name, sizeof(*callid_group));</span><br><span style="color: hsl(120, 100%, 40%);">+  return callid_group ? *callid_group : NULL;</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 int ast_callid_set_chanloggroup(const char *group)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Use threadstorage for constant time access, rather than a linked list */</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_callid callid;</span><br><span style="color: hsl(120, 100%, 40%);">+    char **callid_group;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        callid = ast_read_threadstorage_callid();</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!callid) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Should never be called on non-PBX threads */</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_assert(0);</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</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%);">+   callid_group = ast_threadstorage_get(&callid_group_name, sizeof(*callid_group));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!group) {</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Remove from list */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!*callid_group) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 return 0; /* Wasn't in any group to begin with */</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_free(*callid_group);</span><br><span style="color: hsl(120, 100%, 40%);">+              return 0; /* Set Call ID group for the first time */</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Existing group */</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_free(*callid_group);</span><br><span style="color: hsl(120, 100%, 40%);">+      *callid_group = ast_strdup(group);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!*callid_group) {</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0; /* Set Call ID group for the first time */</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 int callid_group_remove_filters(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct chan_group_lock *cgl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_RWLIST_WRLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ while ((cgl = AST_RWLIST_REMOVE_HEAD(&chan_group_lock_list, entry))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_free(cgl);</span><br><span style="color: hsl(120, 100%, 40%);">+                i++;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     callid_filtering = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ return i;</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 int callid_group_set_filter(const char *group, int enabled)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct chan_group_lock *cgl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_RWLIST_WRLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&chan_group_lock_list, cgl, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!strcmp(group, cgl->name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!enabled) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               AST_RWLIST_REMOVE_CURRENT(entry);</span><br><span style="color: hsl(120, 100%, 40%);">+                             ast_free(cgl);</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</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%);">+     AST_RWLIST_TRAVERSE_SAFE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!enabled) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (AST_LIST_EMPTY(&chan_group_lock_list)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      callid_filtering = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</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%);">+   if (!cgl) {</span><br><span style="color: hsl(120, 100%, 40%);">+           cgl = ast_calloc(1, sizeof(*cgl) + strlen(group) + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!cgl) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             strcpy(cgl->name, group); /* Safe */</span><br><span style="color: hsl(120, 100%, 40%);">+               AST_RWLIST_INSERT_HEAD(&chan_group_lock_list, cgl, entry);</span><br><span style="color: hsl(120, 100%, 40%);">+        } /* else, already existed, and was already enabled, no change */</span><br><span style="color: hsl(120, 100%, 40%);">+     callid_filtering = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</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 int callid_logging_enabled(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct chan_group_lock *cgl;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *callidgroup;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!callid_filtering) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return 1; /* Everything enabled by default, if no filtering */</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%);">+   callidgroup = ast_get_callid_group();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!callidgroup) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0; /* Filtering, but no call group, not enabled */</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%);">+   AST_RWLIST_RDLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_TRAVERSE(&chan_group_lock_list, cgl, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!strcmp(callidgroup, cgl->name)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</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%);">+     AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ return cgl ? 1 : 0; /* If found, enabled, otherwise not */</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%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+   <application name="SetChannelLogGroup" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+            <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                      Set the channel group name for log filtering on this channel</span><br><span style="color: hsl(120, 100%, 40%);">+          </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+             <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+                        <parameter name="group" required="false"></span><br><span style="color: hsl(120, 100%, 40%);">+                           <para>Channel log group name. Leave empty to remove any existing group membership.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                         <para>You can use any arbitrary alphanumeric name that can then be used by the</span><br><span style="color: hsl(120, 100%, 40%);">+                          "logger filter changroup" CLI command to filter dialplan output by group name.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                 </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+            </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+               <description></span><br><span style="color: hsl(120, 100%, 40%);">+                   <para>Assign a channel to a group for log filtering.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                       <para>Because this application can result in dialplan execution logs</span><br><span style="color: hsl(120, 100%, 40%);">+                    being suppressed (or unsuppressed) from the CLI if filtering is active,</span><br><span style="color: hsl(120, 100%, 40%);">+                       it is recommended to call this as soon as possible when dialplan execution begins.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                       <para>Calling this multiple times will replace any previous group assignment.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                      <example title="Associate channel with group test"></span><br><span style="color: hsl(120, 100%, 40%);">+                   exten => s,1,SetChannelLogGroup(test)</span><br><span style="color: hsl(120, 100%, 40%);">+                              same => n,NoOp() ; if a logging call ID group filter name is enabled but test is not included, you will not see this</span><br><span style="color: hsl(120, 100%, 40%);">+                       </example></span><br><span style="color: hsl(120, 100%, 40%);">+                      <example title="Associate channel with group important"></span><br><span style="color: hsl(120, 100%, 40%);">+                      exten => s,1,SetChannelLogGroup(important)</span><br><span style="color: hsl(120, 100%, 40%);">+                         same => n,Set(foo=bar) ; do some important things to show on the CLI (assuming it is filtered with important enabled)</span><br><span style="color: hsl(120, 100%, 40%);">+                              same => n,SetChannelLogGroup() ; remove from group important to stop showing execution on the CLI</span><br><span style="color: hsl(120, 100%, 40%);">+                          same => n,Wait(5) ; do some unimportant stuff</span><br><span style="color: hsl(120, 100%, 40%);">+                      </example></span><br><span style="color: hsl(120, 100%, 40%);">+              </description></span><br><span style="color: hsl(120, 100%, 40%);">+          <see-also></span><br><span style="color: hsl(120, 100%, 40%);">+                      <ref type="application">Log</ref></span><br><span style="color: hsl(120, 100%, 40%);">+               </see-also></span><br><span style="color: hsl(120, 100%, 40%);">+     </application></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 int set_chanloggroup_exec(struct ast_channel *chan, const char *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int res = ast_callid_set_chanloggroup(data);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_log(LOG_ERROR, "Failed to set channel log group for %s\n", ast_channel_name(chan));</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</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 char *handle_logger_chanloggroup_filter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int enabled;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CLI_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+                e->command = "logger filter changroup";</span><br><span style="color: hsl(120, 100%, 40%);">+          e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: logger filter changroup <group> {on|off}\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                   "       Add or remove channel groups from log filtering.\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                 "       If filtering is active, only channels assigned\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                   "       to a group that has been enabled using this command\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "       will have execution shown in the CLI.\n";</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  case CLI_GENERATE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</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%);">+   if (a->argc < 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return CLI_SHOWUSAGE;</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%);">+   enabled = ast_true(a->argv[4]) ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (callid_group_set_filter(a->argv[3], enabled)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_cli(a->fd, "Failed to set channel group filter for group %s\n", a->argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+              return CLI_FAILURE;</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%);">+   ast_cli(a->fd, "Logging of channel group '%s' is now %s\n", a->argv[3], enabled ? "enabled" : "disabled");</span><br><span style="color: hsl(120, 100%, 40%);">+        return CLI_SUCCESS;</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 char *handle_logger_filter_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct chan_group_lock *cgl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CLI_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+                e->command = "logger filter show";</span><br><span style="color: hsl(120, 100%, 40%);">+               e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: logger filter show\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                       "       Show current logger filtering settings.\n";</span><br><span style="color: hsl(120, 100%, 40%);">+         return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  case CLI_GENERATE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</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%);">+   AST_RWLIST_RDLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_RWLIST_TRAVERSE(&chan_group_lock_list, cgl, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_cli(a->fd, "%3d %-32s\n", ++i, cgl->name);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_UNLOCK(&chan_group_lock_list);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (i) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_cli(a->fd, "%d channel group%s currently enabled\n", i, ESS(i));</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_cli(a->fd, "No filtering currently active\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return CLI_SUCCESS;</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 char *handle_logger_filter_reset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int removed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CLI_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+                e->command = "logger filter reset";</span><br><span style="color: hsl(120, 100%, 40%);">+              e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: logger filter reset\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "       Reset the logger filter.\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                 "       This removes any channel groups from filtering\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                   "       (all channel execution will be shown)\n";</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  case CLI_GENERATE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</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%);">+   removed = callid_group_remove_filters();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_cli(a->fd, "Log filtering has been reset (%d filter%s removed)\n", removed, ESS(removed));</span><br><span style="color: hsl(120, 100%, 40%);">+   return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct ast_cli_entry cli_logger[] = {</span><br><span>     AST_CLI_DEFINE(handle_logger_show_channels, "List configured log channels"),</span><br><span>       AST_CLI_DEFINE(handle_logger_show_levels, "List configured log levels"),</span><br><span>@@ -1653,6 +1914,9 @@</span><br><span>   AST_CLI_DEFINE(handle_logger_set_level, "Enables/Disables a specific logging level for this console"),</span><br><span>     AST_CLI_DEFINE(handle_logger_add_channel, "Adds a new logging channel"),</span><br><span>   AST_CLI_DEFINE(handle_logger_remove_channel, "Removes a logging channel"),</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_CLI_DEFINE(handle_logger_chanloggroup_filter, "Filter PBX logs by channel log group"),</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_CLI_DEFINE(handle_logger_filter_show, "Show current PBX channel filtering"),</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_CLI_DEFINE(handle_logger_filter_reset, "Reset PBX channel filtering"),</span><br><span> };</span><br><span> </span><br><span> static void _handle_SIGXFSZ(int sig)</span><br><span>@@ -1709,7 +1973,7 @@</span><br><span>                               }</span><br><span>                            break;</span><br><span>                       case LOGTYPE_CONSOLE:</span><br><span style="color: hsl(0, 100%, 40%);">-                           if (!chan->formatter.format_log(chan, logmsg, buf, sizeof(buf))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (!logmsg->hidecli && !chan->formatter.format_log(chan, logmsg, buf, sizeof(buf))) {</span><br><span>                                         ast_console_puts_mutable_full(buf, logmsg->level, logmsg->sublevel);</span><br><span>                           }</span><br><span>                            break;</span><br><span>@@ -1977,6 +2241,7 @@</span><br><span> </span><br><span>   /* register the logger cli commands */</span><br><span>       ast_cli_register_multiple(cli_logger, ARRAY_LEN(cli_logger));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_register_application_xml("SetChannelLogGroup", set_chanloggroup_exec);</span><br><span> </span><br><span>     ast_mkdir(ast_config_AST_LOG_DIR, 0777);</span><br><span> </span><br><span>@@ -2001,6 +2266,7 @@</span><br><span> </span><br><span>     ast_logger_category_unload();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     ast_unregister_application("SetChannelLogGroup");</span><br><span>  ast_cli_unregister_multiple(cli_logger, ARRAY_LEN(cli_logger));</span><br><span> </span><br><span>  logger_initialized = 0;</span><br><span>@@ -2030,6 +2296,8 @@</span><br><span>              ast_free(f);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ callid_group_remove_filters();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     closelog(); /* syslog */</span><br><span> </span><br><span>         AST_RWLIST_UNLOCK(&logchannels);</span><br><span>@@ -2140,12 +2408,26 @@</span><br><span>       const char *file, int line, const char *function, ast_callid callid,</span><br><span>         const char *fmt, va_list ap)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+     int hidecli = 0;</span><br><span>     struct logmsg *logmsg = NULL;</span><br><span> </span><br><span>    if (level == __LOG_VERBOSE && ast_opt_remote && ast_opt_exec) {</span><br><span>              return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (callid_filtering && !callid_logging_enabled()) {</span><br><span style="color: hsl(120, 100%, 40%);">+          switch (level) {</span><br><span style="color: hsl(120, 100%, 40%);">+              case __LOG_VERBOSE:</span><br><span style="color: hsl(120, 100%, 40%);">+           case __LOG_DEBUG:</span><br><span style="color: hsl(120, 100%, 40%);">+             case __LOG_TRACE:</span><br><span style="color: hsl(120, 100%, 40%);">+             case __LOG_DTMF:</span><br><span style="color: hsl(120, 100%, 40%);">+                      hidecli = 1; /* Hide the message from the CLI, but still log to any log files */</span><br><span style="color: hsl(120, 100%, 40%);">+              default: /* Always show NOTICE, WARNING, ERROR, etc. */</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  AST_LIST_LOCK(&logmsgs);</span><br><span>         if (logger_queue_size >= logger_queue_limit && !close_logger_thread) {</span><br><span>            logger_messages_discarded++;</span><br><span>@@ -2166,6 +2448,8 @@</span><br><span>                 return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ logmsg->hidecli = hidecli;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      /* If the logger thread is active, append it to the tail end of the list - otherwise skip that step */</span><br><span>       if (logthread != AST_PTHREADT_NULL) {</span><br><span>                AST_LIST_LOCK(&logmsgs);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/20029">change 20029</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.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.asterisk.org/c/asterisk/+/20029"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I678550ab95ebf7d46c7acc17ec2f3a6fce31123e </div>
<div style="display:none"> Gerrit-Change-Number: 20029 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>