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.
This commit is contained in:
Aurelien DARRAGON 2024-07-31 17:06:57 +02:00
parent 9341792baf
commit c043d5d372
3 changed files with 108 additions and 1 deletions

View File

@ -59,6 +59,7 @@
* and appear as flags in session->logs.logwait, which are removed once the * and appear as flags in session->logs.logwait, which are removed once the
* required information has been collected. * 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_INIT 1 /* anything */
#define LW_CLIP 2 /* CLient IP */ #define LW_CLIP 2 /* CLient IP */
#define LW_SVIP 4 /* SerVer IP */ #define LW_SVIP 4 /* SerVer IP */

View File

@ -379,7 +379,7 @@ struct proxy {
struct buffer log_tag; /* override default syslog tag */ struct buffer log_tag; /* override default syslog tag */
struct ist header_unique_id; /* unique-id header */ struct ist header_unique_id; /* unique-id header */
struct lf_expr format_unique_id; /* unique-id format */ 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 */ 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 *req_cap; /* chained list of request headers to be captured */
struct cap_hdr *rsp_cap; /* chained list of response headers to be captured */ struct cap_hdr *rsp_cap; /* chained list of response headers to be captured */

106
src/log.c
View File

@ -1293,6 +1293,13 @@ static int _postcheck_log_backend_compat(struct proxy *be)
err_code |= ERR_WARN; err_code |= ERR_WARN;
free_server_rules(&be->server_rules); 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 && if (balance_algo != BE_LB_ALGO_RR &&
balance_algo != BE_LB_ALGO_RND && balance_algo != BE_LB_ALGO_RND &&
balance_algo != BE_LB_ALGO_SS && balance_algo != BE_LB_ALGO_SS &&
@ -6606,6 +6613,105 @@ static int postresolve_loggers()
/* config parsers for this section */ /* config parsers for this section */
REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL); REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL);
REGISTER_CONFIG_SECTION("log-profile", cfg_parse_log_profile, 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_CHECK(postresolve_loggers);
REGISTER_POST_PROXY_CHECK(postcheck_log_backend); REGISTER_POST_PROXY_CHECK(postcheck_log_backend);
REGISTER_POST_PROXY_CHECK(postcheck_logformat_proxy); REGISTER_POST_PROXY_CHECK(postcheck_logformat_proxy);