OPTIM: log: resolve logformat options during postparsing
In lf_buildctx_prepare(), we perform costly bitwise operations for every nodes to resolve node options and check for incompatibilities with global options. In fact, all this logic may safely be performed during postparsing. This is what we're doing in this commit. Doing so saves us from unnecessary runtime checks and could help speedup sess_build_logline(). Since checks are not as costly as before (due to them being performed during postparsing and not on log building path anymore), an complementary check for OPT_HTTP vs OPT_ENCODE incompatibity was added: encoding is ignored if HTTP option is set, unless HTTP option wasn't set globally and encoding was set globally, which means encoding takes the precedence Thanks to this patch, lf_buildctx_prepare() now only takes care of assigning proper typecast and options settings depending if it's used from global or per-node context, and prepares CBOR-specific structure members when CBOR encode option is set.
This commit is contained in:
parent
05ecba0813
commit
03ca16f38b
98
src/log.c
98
src/log.c
@ -887,6 +887,58 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* automatically resolves incompatible LOG_OPT options by taking into
|
||||
* account current options and global options
|
||||
*/
|
||||
static inline void _lf_expr_postcheck_node_opt(int *options, int g_options)
|
||||
{
|
||||
/* encoding is incompatible with HTTP option, so it is ignored
|
||||
* if HTTP option is set, unless HTTP option wasn't set globally
|
||||
* and encoding was set globally, which means encoding takes the
|
||||
* precedence>
|
||||
*/
|
||||
if (*options & LOG_OPT_HTTP) {
|
||||
if ((g_options & (LOG_OPT_HTTP | LOG_OPT_ENCODE)) == LOG_OPT_ENCODE) {
|
||||
/* global encoding enabled and http enabled individually */
|
||||
*options &= ~LOG_OPT_HTTP;
|
||||
}
|
||||
else
|
||||
*options &= ~LOG_OPT_ENCODE;
|
||||
}
|
||||
|
||||
if (*options & LOG_OPT_ENCODE) {
|
||||
/* when encoding is set, ignore +E option */
|
||||
*options &= ~LOG_OPT_ESC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Performs LOG_OPT postparsing check on logformat node <node> belonging to a
|
||||
* given logformat expression <lf_expr>
|
||||
*
|
||||
* It returns 1 on success and 0 on error, <err> will be set in case of error
|
||||
*/
|
||||
static int lf_expr_postcheck_node_opt(struct lf_expr *lf_expr, struct logformat_node *node, char **err)
|
||||
{
|
||||
/* per-node encoding options cannot be disabled if already
|
||||
* enabled globally
|
||||
*
|
||||
* Also, ensure we don't mix encoding types, global setting
|
||||
* prevails over per-node one.
|
||||
*
|
||||
* Finally, ignore LOG_OPT_BIN since it is a global-only option
|
||||
*/
|
||||
if (lf_expr->nodes.options & LOG_OPT_ENCODE) {
|
||||
node->options &= ~(LOG_OPT_BIN | LOG_OPT_ENCODE);
|
||||
node->options |= (lf_expr->nodes.options & LOG_OPT_ENCODE);
|
||||
}
|
||||
else
|
||||
node->options &= ~LOG_OPT_BIN;
|
||||
|
||||
_lf_expr_postcheck_node_opt(&node->options, lf_expr->nodes.options);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Performs a postparsing check on logformat expression <expr> for a given <px>
|
||||
* proxy. The function will behave differently depending on the proxy state
|
||||
* (during parsing we will try to adapt proxy configuration to make it
|
||||
@ -902,6 +954,9 @@ 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;
|
||||
|
||||
/* postcheck global node options */
|
||||
_lf_expr_postcheck_node_opt(&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;
|
||||
@ -914,7 +969,7 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
|
||||
expr->fetch->kw);
|
||||
goto fail;
|
||||
}
|
||||
continue;
|
||||
goto next_node;
|
||||
}
|
||||
/* 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 */
|
||||
@ -943,6 +998,10 @@ 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:
|
||||
/* postcheck individual node's options */
|
||||
if (!lf_expr_postcheck_node_opt(lf_expr, lf, err))
|
||||
goto fail;
|
||||
}
|
||||
if ((px->to_log & (LW_REQ | LW_RESP)) &&
|
||||
(px->mode != PR_MODE_HTTP && !(px->options & PR_O_HTTP_UPG))) {
|
||||
@ -1819,22 +1878,8 @@ static inline void lf_buildctx_prepare(struct lf_buildctx *ctx,
|
||||
const struct logformat_node *node)
|
||||
{
|
||||
if (node) {
|
||||
/* per-node encoding options cannot be disabled if already
|
||||
* enabled globally
|
||||
*
|
||||
* Also, ensure we don't mix encoding types, global setting
|
||||
* prevails over per-node one.
|
||||
*
|
||||
* Finally, ignore LOG_OPT_BIN since it is a global-only option
|
||||
*/
|
||||
if (g_options & LOG_OPT_ENCODE) {
|
||||
ctx->options = (g_options & LOG_OPT_ENCODE);
|
||||
ctx->options |= (node->options & ~(LOG_OPT_BIN | LOG_OPT_ENCODE));
|
||||
}
|
||||
else
|
||||
ctx->options = (node->options & ~LOG_OPT_BIN);
|
||||
|
||||
/* consider node's typecast setting */
|
||||
/* consider node's options and typecast setting */
|
||||
ctx->options = node->options;
|
||||
ctx->typecast = node->typecast;
|
||||
}
|
||||
else {
|
||||
@ -1842,21 +1887,10 @@ static inline void lf_buildctx_prepare(struct lf_buildctx *ctx,
|
||||
ctx->typecast = SMP_T_SAME; /* default */
|
||||
}
|
||||
|
||||
/* encoding is incompatible with HTTP option, so it is ignored
|
||||
* if HTTP option is set
|
||||
*/
|
||||
if (ctx->options & LOG_OPT_HTTP)
|
||||
ctx->options &= ~LOG_OPT_ENCODE;
|
||||
|
||||
if (ctx->options & LOG_OPT_ENCODE) {
|
||||
/* when encoding is set, ignore +E option */
|
||||
ctx->options &= ~LOG_OPT_ESC;
|
||||
|
||||
if (ctx->options & LOG_OPT_ENCODE_CBOR) {
|
||||
/* prepare cbor-specific encode ctx */
|
||||
ctx->encode.cbor.e_fct_byte = _lf_cbor_encode_byte;
|
||||
ctx->encode.cbor.e_fct_ctx = ctx;
|
||||
}
|
||||
if (ctx->options & LOG_OPT_ENCODE_CBOR) {
|
||||
/* prepare cbor-specific encode ctx */
|
||||
ctx->encode.cbor.e_fct_byte = _lf_cbor_encode_byte;
|
||||
ctx->encode.cbor.e_fct_ctx = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user