Skip to content

Commit

Permalink
MINOR: trace: support -dt optional format
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
a-denoyelle committed Nov 27, 2023
1 parent 7a86350 commit a42a5d1
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 12 deletions.
9 changes: 6 additions & 3 deletions doc/management.txt
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,12 @@ list of options is :
the libc fails to resolve an address, the startup sequence is not
interrupted.

-dt : activates traces on stderr. This enables all trace sources on error
level. This can be notably 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 be notably 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 allows to activate one or all trace sources with an
optional level and verbosity in this order using ':' as inner separator.

-m <limit> : limit the total allocatable memory to <limit> megabytes across
all processes. This may cause some connection refusals or some slowdowns
Expand Down
2 changes: 1 addition & 1 deletion include/haproxy/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 11 additions & 1 deletion src/haproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
105 changes: 98 additions & 7 deletions src/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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

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;
/* Reset arg to NULL for strtok. */
arg = NULL;
}

return 0;
Expand Down

0 comments on commit a42a5d1

Please sign in to comment.