]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: trace: support -dt optional format
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 22 Nov 2023 16:27:57 +0000 (17:27 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 27 Nov 2023 16:15:14 +0000 (17:15 +0100)
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.

doc/management.txt
include/haproxy/trace.h
src/haproxy.c
src/trace.c

index 2f106dbbdf7894a394d38f928532b92c812859ac..f76a13e7c70907e5eafc681d18a95c5594365ac7 100644 (file)
@@ -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
index e91b25dd46fe5f6f1afaca8dc0dab9b13d0f604c..703ac8dbdea261cbb5e9d7d92c004061344ecf94 100644 (file)
@@ -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)
index 0d26ac103aa0040fd917914c729253e551d52f85..3b5b1719b2fd42938d2408e170afba3429f3e196 100644 (file)
@@ -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;
index 63853c67223b068ac27eeab998e517c73890b954..a233c0de1dafc2225cdf7412ec3ae03953bcfd6c 100644 (file)
@@ -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;