From: Willy Tarreau Date: Tue, 6 Aug 2024 17:18:43 +0000 (+0200) Subject: MINOR: trace: support setting the sink and level for all sources at once X-Git-Tag: v3.1-dev5~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2a49de9c77a61f7036b9f2d379e47b19029115c;p=thirdparty%2Fhaproxy.git MINOR: trace: support setting the sink and level for all sources at once It's extremely painful to have to set "trace 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. --- diff --git a/doc/management.txt b/doc/management.txt index 095ee3a418..6187297248 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -3975,7 +3975,9 @@ trace 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 lock [criterion] Without argument, this will list all the criteria supported by this source @@ -4045,7 +4047,9 @@ trace 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 verbosity [] Without argument, this will list all verbosity levels for this source, and the diff --git a/src/trace.c b/src/trace.c index b8a1397723..5a8891b53a 100644 --- a/src/trace.c +++ b/src/trace.c @@ -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];