]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: log: support 'to' parameter fo do-log action
authorAurelien DARRAGON <adarragon@haproxy.com>
Fri, 2 Oct 2026 07:15:32 +0000 (09:15 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Mon, 5 Oct 2026 11:02:16 +0000 (13:02 +0200)
Similar to the "to" argument for "log" directive, the optional "to"
parameter allows to specify a list of comma separater loggers section
names to be used as log destination for the logs produce by the do-log
action.

However, while the "to" argument from "log" directive adds up loggers
to existing loggers of the proxy, the do-log "to" argument actually
replaces the loggers configured on the proxy! Indeed, the ultimate
goal is to be able to filter which loggers sections should receive
do-log logs, which by default are sent to all loggers from the proxy.

include/haproxy/action-t.h
src/log.c

index 490005c71c5b88b31c35535ac59b7df176e1f4b0..01432a439ad130333deac4ed7153557571db76f3 100644 (file)
@@ -203,6 +203,8 @@ struct act_rule {
                        enum log_orig_id orig;
                        char *profile_name;
                        struct log_profile *profile;
+                       char *loggers_names;
+                       struct list *loggers;
                } do_log; /* 'do-log' action */
                struct {
                        int value;
index 8568035c3ebbccbb0fea33732da04ce8d85a70c1..3d5dff7b16a8885badec587497b0644b1c5a39e2 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -7422,7 +7422,8 @@ static enum act_return do_log_action(struct act_rule *rule, struct proxy *px,
        ctx.stream = s;
        ctx.profile = rule->arg.do_log.profile;
 
-       do_log_ctx(&ctx, NULL);
+       do_log_ctx(&ctx, rule->arg.do_log.loggers);
+
        return ACT_RET_CONT;
 }
 
@@ -7446,12 +7447,45 @@ static int do_log_action_check(struct act_rule *rule, struct proxy *px, char **e
                }
                rule->arg.do_log.profile = prof;
        }
+       if (rule->arg.do_log.loggers_names) {
+               rule->arg.do_log.loggers = calloc(1, sizeof(*rule->arg.do_log.loggers));
+
+               if (rule->arg.do_log.loggers == NULL) {
+                       memprintf(err, "memory error while parsing loggers for do-log action on %s %s",
+                                 proxy_type_str(px), px->id);
+                       ha_free(&rule->arg.do_log.loggers_names);
+                       return 0;
+               }
+
+               LIST_INIT(rule->arg.do_log.loggers);
+
+               if (!parse_loggers_list(rule->arg.do_log.loggers_names, rule->arg.do_log.loggers, rule->conf.file, rule->conf.line, err)) {
+                       memprintf(err, "error while parsing loggers for do-log action on %s %s : %s",
+                                 proxy_type_str(px), px->id, *err);
+                       ha_free(&rule->arg.do_log.loggers_names);
+                       return 0;
+               }
+
+               ha_free(&rule->arg.do_log.loggers_names);
+       }
+
        return 1; // success
 }
 
 static void do_log_action_release(struct act_rule *rule)
 {
+       struct logger *logger, *back;
+
        ha_free(&rule->arg.do_log.profile_name);
+       ha_free(&rule->arg.do_log.loggers_names);
+
+       if (rule->arg.do_log.loggers) {
+               list_for_each_entry_safe(logger, back, rule->arg.do_log.loggers, list) {
+                       LIST_DEL_INIT(&logger->list);
+                       free_logger(logger);
+               }
+               ha_free(&rule->arg.do_log.loggers);
+       }
 }
 
 
@@ -7489,6 +7523,22 @@ enum act_parse_ret do_log_parse_act(enum log_orig_id id,
                        }
                        *orig_arg += 2;
                }
+               else if (strcmp(args[*orig_arg], "to") == 0) {
+                       if (!*args[*orig_arg + 1]) {
+                               memprintf(err,
+                                         "action '%s': 'to' expects comma separated list of loggers section names.",
+                                         args[cur_arg-1]);
+                               return ACT_RET_PRS_ERR;
+                       }
+                       rule->arg.do_log.loggers_names = strdup(args[*orig_arg + 1]);
+                       if (!rule->arg.do_log.loggers_names) {
+                               memprintf(err,
+                                         "action '%s': memory error when setting 'to'",
+                                          args[cur_arg-1]);
+                               return ACT_RET_PRS_ERR;
+                       }
+                       *orig_arg += 2;
+               }
                else
                        break;
        }