MINOR: trace: support -dt optional format
Add an optional argument for "-dt". This argument is interpreted as a list of several trace statement separated by comma. For each statement, a specific trace name can be specifed, or none to act on all sources. Using double-colon separator, it is possible to add specifications on the wanted level and verbosity.
This commit is contained in:
parent
670520cff8
commit
e97489a526
|
@ -402,9 +402,13 @@ list of options is :
|
|||
the libc fails to resolve an address, the startup sequence is not
|
||||
interrupted.
|
||||
|
||||
-dt : activate traces on stderr. This enables all trace sources on error
|
||||
level. This can notably be useful to detect protocol violations from
|
||||
clients or servers.
|
||||
-dt [<trace_desc>,...] : activates traces on stderr. Without argument, this
|
||||
enables all trace sources on error level. This can notably be useful to
|
||||
detect protocol violations from clients or servers. An optional argument
|
||||
can be used to specify a list of various trace configurations using ',' as
|
||||
separator. Each element activates one or all trace sources. Additionnaly,
|
||||
level and verbosity can be optionaly specified on each element using ':' as
|
||||
inner separator with trace name.
|
||||
|
||||
-m <limit> : limit the total allocatable memory to <limit> megabytes across
|
||||
all processes. This may cause some connection refusals or some slowdowns
|
||||
|
|
|
@ -190,7 +190,7 @@ void trace_no_cb(enum trace_level level, uint64_t mask, const struct trace_sourc
|
|||
|
||||
void trace_register_source(struct trace_source *source);
|
||||
|
||||
int trace_parse_cmd();
|
||||
int trace_parse_cmd(char *arg, char **errmsg);
|
||||
|
||||
/* return a single char to describe a trace state */
|
||||
static inline char trace_state_char(enum trace_state st)
|
||||
|
|
|
@ -1708,7 +1708,17 @@ static void init_args(int argc, char **argv)
|
|||
kwd_dump = flag + 2;
|
||||
}
|
||||
else if (*flag == 'd' && flag[1] == 't') {
|
||||
trace_parse_cmd();
|
||||
if (argc > 1 && argv[1][0] != '-') {
|
||||
if (trace_parse_cmd(argv[1], &err_msg)) {
|
||||
ha_alert("-dt: %s.\n", err_msg);
|
||||
ha_free(&err_msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
else {
|
||||
trace_parse_cmd(NULL, NULL);
|
||||
}
|
||||
}
|
||||
else if (*flag == 'd')
|
||||
arg_mode |= MODE_DEBUG;
|
||||
|
|
105
src/trace.c
105
src/trace.c
|
@ -770,19 +770,110 @@ static int trace_parse_statement(char **args, char **msg)
|
|||
|
||||
}
|
||||
|
||||
void _trace_parse_cmd(struct trace_source *src, int level, int verbosity)
|
||||
{
|
||||
src->sink = sink_find("stderr");
|
||||
src->level = level >= 0 ? level : TRACE_LEVEL_ERROR;
|
||||
src->verbosity = verbosity >= 0 ? verbosity : 1;
|
||||
src->state = TRACE_STATE_RUNNING;
|
||||
}
|
||||
|
||||
/* Parse a process argument specified via "-dt".
|
||||
*
|
||||
* Returns 0 on success else non-zero.
|
||||
*/
|
||||
int trace_parse_cmd()
|
||||
int trace_parse_cmd(char *arg, char **errmsg)
|
||||
{
|
||||
struct trace_source *src;
|
||||
char *str;
|
||||
|
||||
list_for_each_entry(src, &trace_sources, source_link) {
|
||||
src->sink = sink_find("stderr");
|
||||
src->level = TRACE_LEVEL_ERROR;
|
||||
src->verbosity = 1;
|
||||
src->state = TRACE_STATE_RUNNING;
|
||||
if (!arg) {
|
||||
/* No trace specification, activate all sources on error level. */
|
||||
struct trace_source *src = NULL;
|
||||
|
||||
list_for_each_entry(src, &trace_sources, source_link)
|
||||
_trace_parse_cmd(src, -1, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((str = strtok(arg, ","))) {
|
||||
struct trace_source *src = NULL;
|
||||
char *field, *name;
|
||||
char *sep;
|
||||
int level = -1, verbosity = -1;
|
||||
|
||||
/* 1. name */
|
||||
name = str;
|
||||
sep = strchr(str, ':');
|
||||
if (sep) {
|
||||
str = sep + 1;
|
||||
*sep = '\0';
|
||||
}
|
||||
else {
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
if (strlen(name)) {
|
||||
src = trace_find_source(name);
|
||||
if (!src) {
|
||||
memprintf(errmsg, "unknown trace source '%s'", name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!str || !strlen(str))
|
||||
goto parse;
|
||||
|
||||
/* 2. level */
|
||||
field = str;
|
||||
sep = strchr(str, ':');
|
||||
if (sep) {
|
||||
str = sep + 1;
|
||||
*sep = '\0';
|
||||
}
|
||||
else {
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
if (strlen(field)) {
|
||||
level = trace_parse_level(field);
|
||||
if (level < 0) {
|
||||
memprintf(errmsg, "no such level '%s'", field);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!str || !strlen(str))
|
||||
goto parse;
|
||||
|
||||
/* 3. verbosity */
|
||||
field = str;
|
||||
if (strchr(field, ':')) {
|
||||
memprintf(errmsg, "too many double-colon separator");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!src && strcmp(field, "quiet") != 0) {
|
||||
memprintf(errmsg, "trace source must be specified for verbosity other than 'quiet'");
|
||||
return 1;
|
||||
}
|
||||
|
||||
verbosity = trace_source_parse_verbosity(src, field);
|
||||
if (verbosity < 0) {
|
||||
memprintf(errmsg, "no such verbosity '%s' for source '%s'", field, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
parse:
|
||||
if (src) {
|
||||
_trace_parse_cmd(src, level, verbosity);
|
||||
}
|
||||
else {
|
||||
list_for_each_entry(src, &trace_sources, source_link)
|
||||
_trace_parse_cmd(src, level, verbosity);
|
||||
}
|
||||
|
||||
/* Reset arg to NULL for strtok. */
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue