]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: action: add do-log action
authorAurelien DARRAGON <adarragon@haproxy.com>
Fri, 20 Sep 2024 07:34:13 +0000 (09:34 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Fri, 4 Oct 2024 19:38:14 +0000 (21:38 +0200)
Thanks to the two previous commits, we can now expose the do-log action
on all available action contexts, including the new quic-init context.

Each context is responsible for exposing the do-log action by registering
the relevant log steps, saving the idendifier, and then store it in the
rule's context so that do_log_action() automatically uses it to produce
the log during runtime.

To use the feature, it is simply needed to use "do-log" (without argument)
on an action directive, example:

   tcp-request connection do-log

As mentioned before, each context where the action is exposed has its own
log step identifier. Currently known identifiers are:

  quic-initial:           quic-init
  tcp-request connection: tcp-req-conn
  tcp-request session:    tcp-req-sess
  tcp-request content:    tcp-req-cont
  tcp-response content:   tcp-res-cont
  http-request:           http-req
  http-response:          http-res
  http-after-response:    http-after-res

Thus, these "additional" logging steps can be used as-is under log-profile
section (after "on" keyword). However, although the parser will accept
them, it makes no sense to use them with the "log-steps" proxy keyword,
since the only path for these origins to trigger a log generation is
through the explicit use of "do-log" action.

This need was described in GH #401, it should help to conditionally
trigger logs using ACL at specific key points.. and may either be used
alone or combined with "log-steps" to add additional log "trackers" during
transaction handling.

Documentation was updated and some examples were added.

doc/configuration.txt
src/http_act.c
src/quic_rules.c
src/tcp_act.c

index 4a194e77592d48cda692ce10c430c2badb0c7647..f76b65b1b25815d1722eb2dc2812e740794ab47c 100644 (file)
@@ -14585,6 +14585,7 @@ del-map                        -           -     -     -     -            X   X
 deny                           -           -     -     -     -            X   X   -
 dgram-drop                     X           -     -     -     -            -   -   -
 disable-l7-retry               -           -     -     -     -            X   -   -
+do-log                         X           X     X     X     X            X   X   X
 do-resolve                     -           -     -     X     -            X   -   -
 early-hint                     -           -     -     -     -            X   -   -
 expect-netscaler-cip           -           X     -     -     -            -   -   -
@@ -14885,6 +14886,33 @@ disable-l7-retry
   reason than a connection failure. This can be useful for example to make
   sure POST requests aren't retried on failure.
 
+do-log
+  Usable in:  QUIC Ini|    TCP RqCon| RqSes| RqCnt| RsCnt|    HTTP Req| Res| Aft
+                    X |          X  |   X  |   X  |   X  |          X |  X |  X
+
+  This action manually triggers a log emission on the proxy. This means
+  log options on the proxy will be considered (including formatting options
+  such as "log-format"), but it will not interfere with the logs automatically
+  generated by the proxy during transaction handling. It currently doesn't
+  support any argument, though extensions may appear in future versions.
+
+  Using "log-profile", it is possible to precisely describe how the log should
+  be emitted for each of the available contexts where the action may be used.
+  That is, 'on' keyword followed by of the following values: 'quic-init',
+  'tcp-req-conn', 'tcp-req-sess', 'tcp-req-cont', 'tcp-res-cont', 'http-req',
+  'http-res', 'http-after-res'.
+
+  Also, they will be properly reported when using "%OG" logformat alias.
+
+  Example:
+    log-profile myprof
+      on tcp-req-conn format "Connect: %ci"
+
+    frontend myfront
+      log stdout format rfc5424 profile myprof local0
+      log-format "log generated using proxy logformat, from '%OG'"
+      tcp-request connection do-log             #uses special log-profile format
+      tcp-request content do-log                #uses proxy logformat
 
 do-resolve(<var>,<resolvers>,[ipv4,ipv6]) <expr>
   Usable in:  QUIC Ini|    TCP RqCon| RqSes| RqCnt| RsCnt|    HTTP Req| Res| Aft
@@ -26882,6 +26910,8 @@ on <step> [drop] [format <fmt>] [sd <sd_fmt>]
   - "any"      : override both log-format and error-log-format for all logging
                  steps, unless a more precise step override is declared.
 
+  See "do-log" action for relevant additional <step> values.
+
   This setting is only relevant for "log" directives used from contexts where
   using "log-format" directive makes sense (e.g.: http and tcp proxies).
   Else it will simply be ignored.
index 3a902ab352d3c5858c06d81d6baa74e34efbb47c..f0a19f362ec0b92dce72af9848ddca29cba8aa4a 100644 (file)
@@ -2371,6 +2371,40 @@ static enum act_parse_ret parse_http_wait_for_body(const char **args, int *orig_
        return ACT_RET_PRS_OK;
 }
 
+static enum log_orig_id do_log_http_req;
+static enum log_orig_id do_log_http_res;
+static enum log_orig_id do_log_http_after_res;
+
+static void init_do_log(void)
+{
+       do_log_http_req = log_orig_register("http-req");
+       BUG_ON(do_log_http_req == LOG_ORIG_UNSPEC);
+       do_log_http_res = log_orig_register("http-res");
+       BUG_ON(do_log_http_res == LOG_ORIG_UNSPEC);
+       do_log_http_after_res = log_orig_register("http-after-res");
+       BUG_ON(do_log_http_after_res == LOG_ORIG_UNSPEC);
+}
+
+INITCALL0(STG_PREPARE, init_do_log);
+
+static enum act_parse_ret parse_http_req_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_http_req, args, orig_arg, px, rule, err);
+}
+
+static enum act_parse_ret parse_http_res_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_http_res, args, orig_arg, px, rule, err);
+}
+
+static enum act_parse_ret parse_http_after_res_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                      struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_http_after_res, args, orig_arg, px, rule, err);
+}
+
 /************************************************************************/
 /*   All supported http-request action keywords must be declared here.  */
 /************************************************************************/
@@ -2387,6 +2421,7 @@ static struct action_kw_list http_req_actions = {
                { "del-map",          parse_http_set_map,              KWF_MATCH_PREFIX },
                { "deny",             parse_http_deny,                 0 },
                { "disable-l7-retry", parse_http_req_disable_l7_retry, 0 },
+               { "do-log",           parse_http_req_do_log,           0 },
                { "early-hint",       parse_http_set_header,           0 },
                { "normalize-uri",    parse_http_normalize_uri,        KWF_EXPERIMENTAL },
                { "redirect",         parse_http_redirect,             0 },
@@ -2425,6 +2460,7 @@ static struct action_kw_list http_res_actions = {
                { "del-header",      parse_http_del_header,     0 },
                { "del-map",         parse_http_set_map,        KWF_MATCH_PREFIX },
                { "deny",            parse_http_deny,           0 },
+               { "do-log",          parse_http_res_do_log,     0 },
                { "redirect",        parse_http_redirect,       0 },
                { "replace-header",  parse_http_replace_header, 0 },
                { "replace-value",   parse_http_replace_header, 0 },
@@ -2450,6 +2486,7 @@ static struct action_kw_list http_after_res_actions = {
                { "del-acl",          parse_http_set_map,       KWF_MATCH_PREFIX },
                { "del-header",      parse_http_del_header,     0 },
                { "del-map",          parse_http_set_map,       KWF_MATCH_PREFIX },
+               { "do-log",          parse_http_after_res_do_log, 0 },
                { "replace-header",  parse_http_replace_header, 0 },
                { "replace-value",   parse_http_replace_header, 0 },
                { "set-header",      parse_http_set_header,     0 },
index b9242095309c6b86bf93b37922a30bd30bdca7ab..4a9ad3d27d3de965dba4a48a747f1b3090e16ab2 100644 (file)
@@ -4,6 +4,7 @@
 #include <haproxy/action.h>
 #include <haproxy/list.h>
 #include <haproxy/listener.h>
+#include <haproxy/log.h>
 #include <haproxy/obj_type.h>
 #include <haproxy/proxy-t.h>
 #include <haproxy/quic_sock-t.h>
@@ -92,6 +93,23 @@ static enum act_parse_ret parse_dgram_drop(const char **args, int *orig_arg,
        return ACT_RET_PRS_OK;
 }
 
+static enum log_orig_id do_log_quic_init;
+
+static void init_do_log(void)
+{
+       do_log_quic_init = log_orig_register("quic-init");
+       BUG_ON(do_log_quic_init == LOG_ORIG_UNSPEC);
+}
+
+INITCALL0(STG_PREPARE, init_do_log);
+
+static enum act_parse_ret parse_do_log(const char **args, int *orig_arg,
+                                       struct proxy *px,
+                                       struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_quic_init, args, orig_arg, px, rule, err);
+}
+
 static enum act_return quic_init_action_reject(struct act_rule *rule, struct proxy *px,
                                                struct session *sess, struct stream *s, int flags)
 {
@@ -145,6 +163,7 @@ struct action_kw *action_quic_init_custom(const char *kw)
 static struct action_kw_list quic_init_actions = { ILH, {
                { "accept",           parse_accept,            0 },
                { "dgram-drop",       parse_dgram_drop,        0 },
+               { "do-log",           parse_do_log,            0 },
                { "reject",           parse_reject,            0 },
                { "send-retry",       parse_send_retry,        0 },
                { /* END */ },
index c8f5ca2863367cd5652905abfcdb3d7f30894c8b..8a4fd2f908e9a8702e8d82c3e2cded23cfff940a 100644 (file)
@@ -31,6 +31,7 @@
 #include <haproxy/connection.h>
 #include <haproxy/global.h>
 #include <haproxy/http_rules.h>
+#include <haproxy/log.h>
 #include <haproxy/proto_tcp.h>
 #include <haproxy/proxy.h>
 #include <haproxy/sample.h>
@@ -789,8 +790,51 @@ static enum act_parse_ret tcp_parse_silent_drop(const char **args, int *cur_arg,
        return ACT_RET_PRS_OK;
 }
 
+static enum log_orig_id do_log_tcp_req_conn;
+static enum log_orig_id do_log_tcp_req_sess;
+static enum log_orig_id do_log_tcp_req_cont;
+static enum log_orig_id do_log_tcp_res_cont;
+
+static void init_do_log(void)
+{
+       do_log_tcp_req_conn = log_orig_register("tcp-req-conn");
+       BUG_ON(do_log_tcp_req_conn == LOG_ORIG_UNSPEC);
+       do_log_tcp_req_sess = log_orig_register("tcp-req-sess");
+       BUG_ON(do_log_tcp_req_sess == LOG_ORIG_UNSPEC);
+       do_log_tcp_req_cont = log_orig_register("tcp-req-cont");
+       BUG_ON(do_log_tcp_req_cont == LOG_ORIG_UNSPEC);
+       do_log_tcp_res_cont = log_orig_register("tcp-res-cont");
+       BUG_ON(do_log_tcp_res_cont == LOG_ORIG_UNSPEC);
+}
+
+INITCALL0(STG_PREPARE, init_do_log);
+
+static enum act_parse_ret tcp_req_conn_parse_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                    struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_tcp_req_conn, args, orig_arg, px, rule, err);
+}
+
+static enum act_parse_ret tcp_req_sess_parse_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                    struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_tcp_req_sess, args, orig_arg, px, rule, err);
+}
+
+static enum act_parse_ret tcp_req_cont_parse_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                    struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_tcp_req_cont, args, orig_arg, px, rule, err);
+}
+
+static enum act_parse_ret tcp_res_cont_parse_do_log(const char **args, int *orig_arg, struct proxy *px,
+                                                    struct act_rule *rule, char **err)
+{
+       return do_log_parse_act(do_log_tcp_res_cont, args, orig_arg, px, rule, err);
+}
 
 static struct action_kw_list tcp_req_conn_actions = {ILH, {
+       { "do-log"      , tcp_req_conn_parse_do_log },
        { "set-dst"     , tcp_parse_set_src_dst },
        { "set-dst-port", tcp_parse_set_src_dst },
        { "set-fc-mark",  tcp_parse_set_mark    },
@@ -807,6 +851,7 @@ INITCALL1(STG_REGISTER, tcp_req_conn_keywords_register, &tcp_req_conn_actions);
 
 static struct action_kw_list tcp_req_sess_actions = {ILH, {
        { "attach-srv"  , tcp_parse_attach_srv  },
+       { "do-log",       tcp_req_sess_parse_do_log },
        { "set-dst"     , tcp_parse_set_src_dst },
        { "set-dst-port", tcp_parse_set_src_dst },
        { "set-fc-mark",  tcp_parse_set_mark    },
@@ -822,6 +867,7 @@ static struct action_kw_list tcp_req_sess_actions = {ILH, {
 INITCALL1(STG_REGISTER, tcp_req_sess_keywords_register, &tcp_req_sess_actions);
 
 static struct action_kw_list tcp_req_cont_actions = {ILH, {
+       { "do-log",       tcp_req_cont_parse_do_log },
        { "set-bc-mark",  tcp_parse_set_mark    },
        { "set-bc-tos",   tcp_parse_set_tos     },
        { "set-dst"     , tcp_parse_set_src_dst },
@@ -839,6 +885,7 @@ static struct action_kw_list tcp_req_cont_actions = {ILH, {
 INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &tcp_req_cont_actions);
 
 static struct action_kw_list tcp_res_cont_actions = {ILH, {
+       { "do-log",      tcp_res_cont_parse_do_log },
        { "set-fc-mark", tcp_parse_set_mark    },
        { "set-fc-tos",  tcp_parse_set_tos     },
        { "set-mark",    tcp_parse_set_mark    }, // DEPRECATED, see set-fc-mark