From: Aurelien DARRAGON Date: Wed, 31 Jul 2024 15:06:57 +0000 (+0200) Subject: MINOR: log: introduce "log-steps" proxy keyword X-Git-Tag: v3.1-dev9~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c043d5d37236d246b88407a9607f4c291205fa82;p=thirdparty%2Fhaproxy.git MINOR: log: introduce "log-steps" proxy keyword For now it is only available for proxies with frontend capability because log-steps are only evaluated under sess_log() or strm_log() which essentially focus on the frontend side when it comes to log settings so it's better to keep it this way for better consistency, at least for now. For now the setting does nothing (it is not considered during runtime), it will be implemented and documented in upcoming commits. --- diff --git a/include/haproxy/log-t.h b/include/haproxy/log-t.h index 85ea15f048..7447c862d3 100644 --- a/include/haproxy/log-t.h +++ b/include/haproxy/log-t.h @@ -59,6 +59,7 @@ * and appear as flags in session->logs.logwait, which are removed once the * required information has been collected. */ +#define LW_LOGSTEPS -1 /* special value: ignore LW_* fields and consider proxy log-steps */ #define LW_INIT 1 /* anything */ #define LW_CLIP 2 /* CLient IP */ #define LW_SVIP 4 /* SerVer IP */ diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index e404f9a80b..677eacea0f 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -379,7 +379,7 @@ struct proxy { struct buffer log_tag; /* override default syslog tag */ struct ist header_unique_id; /* unique-id header */ struct lf_expr format_unique_id; /* unique-id format */ - int to_log; /* things to be logged (LW_*) */ + int to_log; /* things to be logged (LW_*), special value LW_LOGSTEPS == follow log-steps */ int nb_req_cap, nb_rsp_cap; /* # of headers to be captured */ struct cap_hdr *req_cap; /* chained list of request headers to be captured */ struct cap_hdr *rsp_cap; /* chained list of response headers to be captured */ diff --git a/src/log.c b/src/log.c index 2d73d1b963..9e01ea3d19 100644 --- a/src/log.c +++ b/src/log.c @@ -1293,6 +1293,13 @@ static int _postcheck_log_backend_compat(struct proxy *be) err_code |= ERR_WARN; free_server_rules(&be->server_rules); } + if (be->to_log == LW_LOGSTEPS) { + ha_warning("Cannot use \"log-steps\" with 'mode log' in %s '%s'. It will be ignored.\n", + proxy_type_str(be), be->id); + + err_code |= ERR_WARN; + /* we don't have a convenient freeing function, let the proxy free it upon deinit */ + } if (balance_algo != BE_LB_ALGO_RR && balance_algo != BE_LB_ALGO_RND && balance_algo != BE_LB_ALGO_SS && @@ -6606,6 +6613,105 @@ static int postresolve_loggers() /* config parsers for this section */ REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL); REGISTER_CONFIG_SECTION("log-profile", cfg_parse_log_profile, NULL); + +static int px_parse_log_steps(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + char *str; + size_t cur_sep; + int retval = -1; + + if (!(curpx->cap & PR_CAP_FE)) { + memprintf(err, "%s will be ignored because %s '%s' has no frontend capability", + args[0], proxy_type_str(curpx), curpx->id); + retval = 1; + goto end; + } + + if (args[1] == NULL) { + memprintf(err, "%s: invalid arguments, expects 'all' or a composition of logging" + "steps separated by spaces.", + args[0]); + goto end; + } + + if (strcmp(args[1], "all") == 0) { + /* enable all logging steps */ + curpx->to_log = LW_LOGSTEPS; + retval = 0; + goto end; + } + + /* selectively enable logging steps */ + str = args[1]; + + while (str[0]) { + struct eb32_node *cur_step; + enum log_orig_id cur_id; + + cur_sep = strcspn(str, ","); + + /* check for valid logging step */ + if (cur_sep == 6 && strncmp(str, "accept", cur_sep) == 0) + cur_id = LOG_ORIG_TXN_ACCEPT; + else if (cur_sep == 7 && strncmp(str, "request", cur_sep) == 0) + cur_id = LOG_ORIG_TXN_REQUEST; + else if (cur_sep == 7 && strncmp(str, "connect", cur_sep) == 0) + cur_id = LOG_ORIG_TXN_CONNECT; + else if (cur_sep == 8 && strncmp(str, "response", cur_sep) == 0) + cur_id = LOG_ORIG_TXN_RESPONSE; + else if (cur_sep == 5 && strncmp(str, "close", cur_sep) == 0) + cur_id = LOG_ORIG_TXN_CLOSE; + else { + struct log_origin_node *cur; + + list_for_each_entry(cur, &log_origins, list) { + if (cur_sep == strlen(cur->name) && strncmp(str, cur->name, cur_sep) == 0) { + cur_id = cur->tree.key; + break; + } + } + + memprintf(err, + "invalid log step name (%.*s). Expected values are: " + "accept, request, connect, response, close", + (int)cur_sep, str); + list_for_each_entry(cur, &log_origins, list) + memprintf(err, "%s, %s", *err, cur->name); + + goto end; + } + + cur_step = malloc(sizeof(*cur_step)); + if (!cur_step) { + memprintf(err, "memory failure when trying to configure log-step (%.*s)", + (int)cur_sep, str); + goto end; + } + cur_step->key = cur_id; + eb32_insert(&curpx->conf.log_steps, cur_step); + next: + if (str[cur_sep]) + str += cur_sep + 1; + else + str += cur_sep; + } + + curpx->to_log = LW_LOGSTEPS; + retval = 0; + + end: + return retval; +} + +static struct cfg_kw_list cfg_kws_li = {ILH, { + { CFG_LISTEN, "log-steps", px_parse_log_steps }, + { 0, NULL, NULL }, +}}; + +INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws_li); + REGISTER_POST_CHECK(postresolve_loggers); REGISTER_POST_PROXY_CHECK(postcheck_log_backend); REGISTER_POST_PROXY_CHECK(postcheck_logformat_proxy);