MINOR: action: add do-log action

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.
This commit is contained in:
Aurelien DARRAGON 2024-09-20 09:34:13 +02:00
parent 0e271f1d2a
commit 3ba924a4da
4 changed files with 133 additions and 0 deletions

View 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.

View 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 },

View 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 */ },

View 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