]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: trace: support setting the sink and level for all sources at once
authorWilly Tarreau <w@1wt.eu>
Tue, 6 Aug 2024 17:18:43 +0000 (19:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Aug 2024 14:02:59 +0000 (16:02 +0200)
It's extremely painful to have to set "trace <src> sink buf1" for all
sources, then to do the same for "level developer" (for example). Let's
have a possibility via a meta-source "all" to apply the change to all
sources at once. This currently supports level and sink, which are not
dependent on the source, this is a good start.

doc/management.txt
src/trace.c

index 095ee3a4187d6085f44e3f224008245cf74198af..61872972484a8d5311f87d9ed62dce20163d9d51 100644 (file)
@@ -3975,7 +3975,9 @@ trace <source> level [<level>]
   It is highly recommended to always use the "user" level only and switch to
   other levels only if instructed to do so by a developer. Also it is a good
   idea to first configure the events before switching to higher levels, as it
-  may save from dumping many lines if no filter is applied.
+  may save from dumping many lines if no filter is applied. The meta-source
+  "all" may also be used with this command: in this case, the level will be
+  applied to all existing sources at once.
 
 trace <source> lock [criterion]
   Without argument, this will list all the criteria supported by this source
@@ -4045,7 +4047,9 @@ trace <source> sink [<sink>]
    ring buffers should be available as well. When a name is specified, the sink
    instantly changes for the specified source. Events are not changed during a
    sink change. In the worst case some may be lost if an invalid sink is used
-   (or "none"), but operations do continue to a different destination.
+   (or "none"), but operations do continue to a different destination. The
+   meta-source "all" may also be used with this command: in this case, the
+   sink will be applied to all existing sources at once.
 
 trace <source> verbosity [<level>]
   Without argument, this will list all verbosity levels for this source, and the
index b8a1397723468e14bb11149c5239c097dda88f45..5a8891b53ad8861e4a46f0e4e0b68a9d224e3c76 100644 (file)
@@ -434,6 +434,7 @@ static int trace_parse_statement(char **args, char **msg)
                chunk_printf(&trash,
                             "Supported trace sources and states (.=stopped, w=waiting, R=running) :\n"
                             " [.] 0          : not a source, will immediately stop all traces\n"
+                            " [.] all        : all sources below, only for 'sink' and 'level'\n"
                             );
 
                list_for_each_entry(src, &trace_sources, source_link)
@@ -452,10 +453,21 @@ static int trace_parse_statement(char **args, char **msg)
                return LOG_NOTICE;
        }
 
-       src = trace_find_source(args[1]);
-       if (!src) {
-               memprintf(msg, "No such trace source '%s'", args[1]);
-               return LOG_ERR;
+       if (strcmp(args[1], "all") == 0) {
+               if (*args[2] &&
+                   strcmp(args[2], "sink") != 0 &&
+                   strcmp(args[2], "level") != 0) {
+                       memprintf(msg, "'%s' not applicable to meta-source 'all'", args[2]);
+                       return LOG_ERR;
+               }
+               src = NULL;
+       }
+       else {
+               src = trace_find_source(args[1]);
+               if (!src) {
+                       memprintf(msg, "No such trace source '%s'", args[1]);
+                       return LOG_ERR;
+               }
        }
 
        if (!*args[2]) {
@@ -563,11 +575,11 @@ static int trace_parse_statement(char **args, char **msg)
                struct sink *sink;
 
                if (!*name) {
-                       chunk_printf(&trash, "Supported sinks for source %s (*=current):\n", src->name.ptr);
-                       chunk_appendf(&trash, "  %c none       : no sink\n", src->sink ? ' ' : '*');
+                       chunk_printf(&trash, "Supported sinks for source %s (*=current):\n", src ? src->name.ptr : "all");
+                       chunk_appendf(&trash, "  %c none       : no sink\n", src && src->sink ? ' ' : '*');
                        list_for_each_entry(sink, &sink_list, sink_list) {
                                chunk_appendf(&trash, "  %c %-10s : %s\n",
-                                             src->sink == sink ? '*' : ' ',
+                                             src && src->sink == sink ? '*' : ' ',
                                              sink->name, sink->desc);
                        }
                        trash.area[trash.data] = 0;
@@ -585,7 +597,11 @@ static int trace_parse_statement(char **args, char **msg)
                        }
                }
 
-               HA_ATOMIC_STORE(&src->sink, sink);
+               if (src)
+                       HA_ATOMIC_STORE(&src->sink, sink);
+               else
+                       list_for_each_entry(src, &trace_sources, source_link)
+                               HA_ATOMIC_STORE(&src->sink, sink);
        }
        else if (strcmp(args[2], "level") == 0) {
                const char *name = args[3];
@@ -598,25 +614,29 @@ static int trace_parse_statement(char **args, char **msg)
                        chunk_reset(&trash);
                        if (*name)
                                chunk_appendf(&trash, "No such trace level '%s'. ", name);
-                       chunk_appendf(&trash, "Supported trace levels for source %s:\n", src->name.ptr);
+                       chunk_appendf(&trash, "Supported trace levels for source %s:\n", src ? src->name.ptr : "all");
                        chunk_appendf(&trash, "  %c error      : report errors\n",
-                                     src->level == TRACE_LEVEL_ERROR ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_ERROR ? '*' : ' ');
                        chunk_appendf(&trash, "  %c user       : also information useful to the end user\n",
-                                     src->level == TRACE_LEVEL_USER ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_USER ? '*' : ' ');
                        chunk_appendf(&trash, "  %c proto      : also protocol-level updates\n",
-                                     src->level == TRACE_LEVEL_PROTO ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_PROTO ? '*' : ' ');
                        chunk_appendf(&trash, "  %c state      : also report internal state changes\n",
-                                     src->level == TRACE_LEVEL_STATE ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_STATE ? '*' : ' ');
                        chunk_appendf(&trash, "  %c data       : also report data transfers\n",
-                                     src->level == TRACE_LEVEL_DATA ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_DATA ? '*' : ' ');
                        chunk_appendf(&trash, "  %c developer  : also report information useful only to the developer\n",
-                                     src->level == TRACE_LEVEL_DEVELOPER ? '*' : ' ');
+                                     src && src->level == TRACE_LEVEL_DEVELOPER ? '*' : ' ');
                        trash.area[trash.data] = 0;
                        *msg = strdup(trash.area);
                        return *name ? LOG_ERR : LOG_WARNING;
                }
 
-               HA_ATOMIC_STORE(&src->level, level);
+               if (src)
+                       HA_ATOMIC_STORE(&src->level, level);
+               else
+                       list_for_each_entry(src, &trace_sources, source_link)
+                               HA_ATOMIC_STORE(&src->level, level);
        }
        else if (strcmp(args[2], "lock") == 0) {
                const char *name = args[3];