mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-17 11:06:54 +00:00
MINOR: vars: add a "set-var-fmt" directive to the global section
Just like the set-var-fmt action for tcp/http rules, the set-var-fmt directive in global sections allows to pre-set process-wide variables using a format string instead of a sample expression. This is often more convenient when it is required to concatenate multiple fields, or when emitting just one word.
This commit is contained in:
parent
20b7a0f9ed
commit
753d4db5f3
@ -1750,7 +1750,7 @@ set-var <var-name> <expr>
|
||||
'set-var' action in TCP or HTTP rules except that the expression is evaluated
|
||||
at configuration parsing time and that the variable is instantly set. The
|
||||
sample fetch functions and converters permitted in the expression are only
|
||||
those using internal data, typically 'int(value)' or 'str(value)'. It's is
|
||||
those using internal data, typically 'int(value)' or 'str(value)'. It is
|
||||
possible to reference previously allocated variables as well. These variables
|
||||
will then be readable (and modifiable) from the regular rule sets.
|
||||
|
||||
@ -1760,6 +1760,23 @@ set-var <var-name> <expr>
|
||||
set-var proc.prio int(100)
|
||||
set-var proc.threshold int(200),sub(proc.prio)
|
||||
|
||||
set-var-fmt <var-name> <fmt>
|
||||
Sets the process-wide variable '<var-name>' to the string resulting from the
|
||||
evaluation of the log-format <fmt>. The variable '<var-name>' may only be a
|
||||
process-wide variable (using the 'proc.' prefix). It works exactly like the
|
||||
'set-var-fmt' action in TCP or HTTP rules except that the expression is
|
||||
evaluated at configuration parsing time and that the variable is instantly
|
||||
set. The sample fetch functions and converters permitted in the expression
|
||||
are only those using internal data, typically 'int(value)' or 'str(value)'.
|
||||
It is possible to reference previously allocated variables as well. These
|
||||
variables will then be readable (and modifiable) from the regular rule sets.
|
||||
Please see section 8.2.4 for details on the log-format syntax.
|
||||
|
||||
Example:
|
||||
global
|
||||
set-var-fmt proc.current_state "primary"
|
||||
set-var-fmt proc.bootid "%pid|%t"
|
||||
|
||||
setenv <name> <value>
|
||||
Sets environment variable <name> to value <value>. If the variable exists, it
|
||||
is overwritten. The changes immediately take effect so that the next line in
|
||||
|
@ -10,7 +10,7 @@ haproxy h1 -conf {
|
||||
set-var proc.str1 str("this is")
|
||||
set-var proc.str2 str("a string")
|
||||
set-var proc.str var(proc.str1)
|
||||
set-var proc.str str(""),concat("",proc.str," a string")
|
||||
set-var-fmt proc.str "%[var(proc.str)] a string"
|
||||
set-var proc.uuid uuid()
|
||||
|
||||
defaults
|
||||
|
25
src/vars.c
25
src/vars.c
@ -12,6 +12,7 @@
|
||||
#include <haproxy/list.h>
|
||||
#include <haproxy/log.h>
|
||||
#include <haproxy/sample.h>
|
||||
#include <haproxy/session.h>
|
||||
#include <haproxy/stream-t.h>
|
||||
#include <haproxy/tcp_rules.h>
|
||||
#include <haproxy/tcpcheck.h>
|
||||
@ -894,6 +895,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
|
||||
* expression that are parsed, processed, and released on the fly so that we
|
||||
* respect the real set-var syntax. These directives take the following format:
|
||||
* set-var <name> <expression>
|
||||
* set-var-fmt <name> <fmt>
|
||||
* Note that parse_store() expects "set-var(name) <expression>" so we have to
|
||||
* temporarily replace the keyword here.
|
||||
*/
|
||||
@ -910,21 +912,29 @@ static int vars_parse_global_set_var(char **args, int section_type, struct proxy
|
||||
.arg.vars.scope = SCOPE_PROC,
|
||||
.from = ACT_F_CFG_PARSER,
|
||||
};
|
||||
enum obj_type objt = OBJ_TYPE_NONE;
|
||||
struct session *sess = NULL;
|
||||
enum act_parse_ret p_ret;
|
||||
char *old_arg1;
|
||||
char *tmp_arg1;
|
||||
int arg = 2; // variable name
|
||||
int ret = -1;
|
||||
int use_fmt = 0;
|
||||
|
||||
LIST_INIT(&px.conf.args.list);
|
||||
|
||||
use_fmt = strcmp(args[0], "set-var-fmt") == 0;
|
||||
|
||||
if (!*args[1] || !*args[2]) {
|
||||
memprintf(err, "'%s' requires a process-wide variable name ('proc.<name>') and a sample expression.", args[0]);
|
||||
if (use_fmt)
|
||||
memprintf(err, "'%s' requires a process-wide variable name ('proc.<name>') and a format string.", args[0]);
|
||||
else
|
||||
memprintf(err, "'%s' requires a process-wide variable name ('proc.<name>') and a sample expression.", args[0]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
tmp_arg1 = NULL;
|
||||
if (!memprintf(&tmp_arg1, "set-var(%s)", args[1]))
|
||||
if (!memprintf(&tmp_arg1, "set-var%s(%s)", use_fmt ? "-fmt" : "", args[1]))
|
||||
goto end;
|
||||
|
||||
/* parse_store() will always return a message in <err> on error */
|
||||
@ -946,8 +956,16 @@ static int vars_parse_global_set_var(char **args, int section_type, struct proxy
|
||||
goto end;
|
||||
}
|
||||
|
||||
action_store(&rule, &px, NULL, NULL, 0);
|
||||
if (use_fmt && !(sess = session_new(&px, NULL, &objt))) {
|
||||
release_sample_expr(rule.arg.vars.expr);
|
||||
memprintf(err, "'%s': out of memory when trying to set variable '%s' in the global section.", args[0], args[1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
action_store(&rule, &px, sess, NULL, 0);
|
||||
release_sample_expr(rule.arg.vars.expr);
|
||||
if (sess)
|
||||
session_free(sess);
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
@ -1205,6 +1223,7 @@ INITCALL1(STG_REGISTER, http_after_res_keywords_register, &http_after_res_kws);
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {{ },{
|
||||
{ CFG_GLOBAL, "set-var", vars_parse_global_set_var },
|
||||
{ CFG_GLOBAL, "set-var-fmt", vars_parse_global_set_var },
|
||||
{ CFG_GLOBAL, "tune.vars.global-max-size", vars_max_size_global },
|
||||
{ CFG_GLOBAL, "tune.vars.proc-max-size", vars_max_size_proc },
|
||||
{ CFG_GLOBAL, "tune.vars.sess-max-size", vars_max_size_sess },
|
||||
|
Loading…
Reference in New Issue
Block a user