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
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
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)
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]) {
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;
}
}
- 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];
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];