*/
static int parse_logformat_tag(char *arg, int arg_len, char *name, int name_len, int typecast,
char *tag, int tag_len, struct lf_expr *lf_expr,
- char **err)
+ int *defoptions, char **err)
{
int j;
struct list *list_format= &lf_expr->nodes.list;
node->typecast = typecast;
if (name && name_len)
node->name = my_strndup(name, name_len);
- node->options = lf_expr->nodes.options;
+ node->options = *defoptions;
if (arg_len) {
node->arg = my_strndup(arg, arg_len);
if (!parse_logformat_tag_args(node->arg, node, err))
goto error_free;
}
if (node->tag->type == LOG_FMT_GLOBAL) {
- lf_expr->nodes.options = node->options;
+ *defoptions = node->options;
free_logformat_node(node);
} else {
LIST_APPEND(list_format, &node->list);
*/
static int add_sample_to_logformat_list(char *text, char *name, int name_len, int typecast,
char *arg, int arg_len, struct lf_expr *lf_expr,
- struct arg_list *al, int cap, char **err, char **endptr)
+ struct arg_list *al, int options, int cap, char **err, char **endptr)
{
char *cmd[2];
struct list *list_format = &lf_expr->nodes.list;
node->type = LOG_FMT_EXPR;
node->typecast = typecast;
node->expr = expr;
- node->options = lf_expr->nodes.options;
+ node->options = options;
if (arg_len) {
node->arg = my_strndup(arg, arg_len);
goto error_free;
}
- if ((lf_expr->nodes.options & LOG_OPT_HTTP) && (expr->fetch->use & (SMP_USE_L6REQ|SMP_USE_L6RES))) {
+ if ((options & LOG_OPT_HTTP) && (expr->fetch->use & (SMP_USE_L6REQ|SMP_USE_L6RES))) {
ha_warning("parsing [%s:%d] : L6 sample fetch <%s> ignored in HTTP log-format string.\n",
lf_expr->conf.file, lf_expr->conf.line, text);
}
* returning.
*/
LIST_INIT(&lf_expr->nodes.list);
- lf_expr->nodes.options = options;
/* we must set the compiled flag now for proper deinit in case of failure */
lf_expr->flags |= LF_FL_COMPILED;
* part of the expression, which MUST be the trailing
* angle bracket.
*/
- if (!add_sample_to_logformat_list(tag, name, name_len, typecast, arg, arg_len, lf_expr, al, cap, err, &str))
+ if (!add_sample_to_logformat_list(tag, name, name_len, typecast, arg, arg_len, lf_expr, al, options, cap, err, &str))
goto fail;
if (*str == ']') {
if (cformat != pformat || pformat == LF_SEPARATOR) {
switch (pformat) {
case LF_TAG:
- if (!parse_logformat_tag(arg, arg_len, name, name_len, typecast, tag, tag_len, lf_expr, err))
+ if (!parse_logformat_tag(arg, arg_len, name, name_len, typecast, tag, tag_len, lf_expr, &options, err))
goto fail;
break;
case LF_TEXT:
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;
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 */
if (!(px->flags & PR_FL_CHECKED))
px->to_log |= lf->tag->lw;
}
+ next_node:
+ if (lf->type == LOG_FMT_EXPR || lf->type == LOG_FMT_TAG) {
+ /* 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))) {