mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-05 04:56:10 +02:00
BUG/MINOR: log: fix global lf_expr node options behavior (2nd try)
In 98b44e8 ("BUG/MINOR: log: fix global lf_expr node options behavior"),
I properly restored global node options behavior for when encoding is
not used, however the fix is not optimal when encoding is involved:
Indeed, encoding logic in sess_build_logline() relies on global node
options to know if encoding must be handled expression-wide or
individually. However, because of the above fix, if an expression is
made of 1 or multiple nodes that all set an encoding option manually
(without '%o'), we consider that the option was set globally, but
that's probably not what the user intended. Instead we should only
evaluate global options from '%o', so that it remains possible to
skip global encoding when needed.
No backport needed.
This commit is contained in:
parent
97240d01b3
commit
9931a62c3f
@ -189,7 +189,7 @@ struct lf_expr {
|
||||
union {
|
||||
struct {
|
||||
struct list list; /* logformat_node list */
|
||||
int options; /* global options (common to all nodes) */
|
||||
int options; /* global '%o' options (common to all nodes) */
|
||||
} nodes;
|
||||
char *str; /* original string prior to parsing (NULL once compiled) */
|
||||
};
|
||||
|
||||
31
src/log.c
31
src/log.c
@ -442,6 +442,21 @@ static int parse_logformat_tag(char *arg, int arg_len, char *name, int name_len,
|
||||
}
|
||||
if (node->tag->type == LOG_FMT_GLOBAL) {
|
||||
*defoptions = node->options;
|
||||
if (lf_expr->nodes.options == LOG_OPT_NONE)
|
||||
lf_expr->nodes.options = node->options;
|
||||
else {
|
||||
/* global options were previously set and were
|
||||
* overwritten for nodes that appear after the
|
||||
* current one.
|
||||
*
|
||||
* However, for lf_expr->nodes.options we must
|
||||
* keep a track of options common to ALL nodes,
|
||||
* thus we take previous global options into
|
||||
* account to compute the new logformat
|
||||
* expression wide (global) node options.
|
||||
*/
|
||||
lf_expr->nodes.options &= node->options;
|
||||
}
|
||||
free_logformat_node(node);
|
||||
} else {
|
||||
LIST_APPEND(list_format, &node->list);
|
||||
@ -620,6 +635,7 @@ int lf_expr_compile(struct lf_expr *lf_expr,
|
||||
* returning.
|
||||
*/
|
||||
LIST_INIT(&lf_expr->nodes.list);
|
||||
lf_expr->nodes.options = LOG_OPT_NONE;
|
||||
/* we must set the compiled flag now for proper deinit in case of failure */
|
||||
lf_expr->flags |= LF_FL_COMPILED;
|
||||
|
||||
@ -885,11 +901,6 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
||||
if (!(px->flags & PR_FL_CHECKED))
|
||||
px->to_log |= LW_INIT;
|
||||
|
||||
/* start with all options, then perform ANDmask with each node's
|
||||
* options to end with options common to ALL nodes
|
||||
*/
|
||||
lf_expr->nodes.options = ~LOG_OPT_NONE;
|
||||
|
||||
list_for_each_entry(lf, &lf_expr->nodes.list, list) {
|
||||
if (lf->type == LOG_FMT_EXPR) {
|
||||
struct sample_expr *expr = lf->expr;
|
||||
@ -902,7 +913,7 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
||||
expr->fetch->kw);
|
||||
goto fail;
|
||||
}
|
||||
goto next_node;
|
||||
continue;
|
||||
}
|
||||
/* check if we need to allocate an http_txn struct for HTTP parsing */
|
||||
/* Note, we may also need to set curpx->to_log with certain fetches */
|
||||
@ -931,14 +942,6 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
||||
if (!(px->flags & PR_FL_CHECKED))
|
||||
px->to_log |= lf->tag->lw;
|
||||
}
|
||||
next_node:
|
||||
if (LF_NODE_WITH_OPT(lf)) {
|
||||
/* For configurable nodes, apply current node's option
|
||||
* mask to global node options to keep options common
|
||||
* to all nodes
|
||||
*/
|
||||
lf_expr->nodes.options &= lf->options;
|
||||
}
|
||||
}
|
||||
if ((px->to_log & (LW_REQ | LW_RESP)) &&
|
||||
(px->mode != PR_MODE_HTTP && !(px->options & PR_O_HTTP_UPG))) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user