/* * Parse the sample fetch expression <text> and add a node to <list_format> upon * success. At the moment, sample converters are not yet supported but fetch arguments * should work. The curpx->conf.args.ctx must be set by the caller. */ void add_sample_to_logformat_list(char *text, char *arg, int arg_len, struct proxy *curpx, struct list *list_format, int options, int cap, const char *file, int line) { char *cmd[2]; struct sample_expr *expr; struct logformat_node *node; int cmd_arg; char *errmsg = NULL; cmd[0] = text; cmd[1] = ""; cmd_arg = 0; expr = sample_parse_expr(cmd, &cmd_arg, file, line, &errmsg, &curpx->conf.args); if (!expr) { Warning("parsing [%s:%d] : '%s' : sample fetch <%s> failed with : %s\n", curpx->conf.args.file, curpx->conf.args.line, fmt_directive(curpx), text, errmsg); return; } node = calloc(1, sizeof(struct logformat_node)); node->type = LOG_FMT_EXPR; node->expr = expr; node->options = options; if (arg_len) { node->arg = my_strndup(arg, arg_len); parse_logformat_var_args(node->arg, node); } if (expr->fetch->val & cap & SMP_VAL_REQUEST) node->options |= LOG_OPT_REQ_CAP; /* fetch method is request-compatible */ if (expr->fetch->val & cap & SMP_VAL_RESPONSE) node->options |= LOG_OPT_RES_CAP; /* fetch method is response-compatible */ if (!(expr->fetch->val & cap)) Warning("parsing [%s:%d] : '%s' : sample fetch <%s> may not be reliably used here because it needs '%s' which is not available here.\n", curpx->conf.args.file, curpx->conf.args.line, fmt_directive(curpx), text, sample_src_names(expr->fetch->use)); /* check if we need to allocate an hdr_idx struct for HTTP parsing */ /* Note, we may also need to set curpx->to_log with certain fetches */ curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY); /* FIXME: temporary workaround for missing LW_XPRT and LW_REQ flags * needed with some sample fetches (eg: ssl*). We always set it for * now on, but this will leave with sample capabilities soon. */ curpx->to_log |= LW_XPRT; curpx->to_log |= LW_REQ; LIST_ADDQ(list_format, &node->list); }
/* * Parse a variable '%varname' or '%{args}varname' in log-format. The caller * must pass the args part in the <arg> pointer with its length in <arg_len>, * and varname with its length in <var> and <var_len> respectively. <arg> is * ignored when arg_len is 0. Neither <var> nor <var_len> may be null. */ int parse_logformat_var(char *arg, int arg_len, char *var, int var_len, struct proxy *curproxy, struct list *list_format, int *defoptions) { int j; struct logformat_node *node; for (j = 0; logformat_keywords[j].name; j++) { // search a log type if (strlen(logformat_keywords[j].name) == var_len && strncmp(var, logformat_keywords[j].name, var_len) == 0) { if (logformat_keywords[j].mode != PR_MODE_HTTP || curproxy->mode == PR_MODE_HTTP) { node = calloc(1, sizeof(struct logformat_node)); node->type = logformat_keywords[j].type; node->options = *defoptions; if (arg_len) { node->arg = my_strndup(arg, arg_len); parse_logformat_var_args(node->arg, node); } if (node->type == LOG_FMT_GLOBAL) { *defoptions = node->options; free(node->arg); free(node); } else { if (logformat_keywords[j].config_callback && logformat_keywords[j].config_callback(node, curproxy) != 0) { return -1; } curproxy->to_log |= logformat_keywords[j].lw; LIST_ADDQ(list_format, &node->list); } if (logformat_keywords[j].replace_by) Warning("parsing [%s:%d] : deprecated variable '%s' in '%s', please replace it with '%s'.\n", curproxy->conf.args.file, curproxy->conf.args.line, logformat_keywords[j].name, fmt_directive(curproxy), logformat_keywords[j].replace_by); return 0; } else { Warning("parsing [%s:%d] : '%s' : format variable '%s' is reserved for HTTP mode.\n", curproxy->conf.args.file, curproxy->conf.args.line, fmt_directive(curproxy), logformat_keywords[j].name); return -1; } } } j = var[var_len]; var[var_len] = 0; Warning("parsing [%s:%d] : no such format variable '%s' in '%s'. If you wanted to emit the '%%' character verbatim, you need to use '%%%%' in log-format expressions.\n", curproxy->conf.args.file, curproxy->conf.args.line, var, fmt_directive(curproxy)); var[var_len] = j; return -1; }