mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-25 12:28:01 +00:00
MEDIUM: checks: Add status-code sample expression on tcp-check expect rules
This option defines a sample expression, evaluated as an integer, to set the status code (check->code) if a tcp-check healthcheck ends on the corresponding expect rule.
This commit is contained in:
parent
be52b4de66
commit
98cc57cf5c
@ -9873,7 +9873,7 @@ tcp-check connect [params*]
|
|||||||
|
|
||||||
|
|
||||||
tcp-check expect [min-recv <int>] [error-status <st>] [tout-status <st>]
|
tcp-check expect [min-recv <int>] [error-status <st>] [tout-status <st>]
|
||||||
[on-success <fmt>] [on-error <fmt>]
|
[on-success <fmt>] [on-error <fmt>] [status-code <expr>]
|
||||||
[!] <match> <pattern>
|
[!] <match> <pattern>
|
||||||
Specify data to be collected and analyzed during a generic health check
|
Specify data to be collected and analyzed during a generic health check
|
||||||
May be used in sections: defaults | frontend | listen | backend
|
May be used in sections: defaults | frontend | listen | backend
|
||||||
@ -9922,6 +9922,11 @@ tcp-check expect [min-recv <int>] [error-status <st>] [tout-status <st>]
|
|||||||
occurred during the expect rule evaluation. <fmt> is a
|
occurred during the expect rule evaluation. <fmt> is a
|
||||||
log-format string.
|
log-format string.
|
||||||
|
|
||||||
|
status-code <expr> is optional and can be used to set the check status code
|
||||||
|
reported in logs, on success or on error. <expr> is a
|
||||||
|
standard HAProxy expression formed by a sample-fetch
|
||||||
|
followed by some converters.
|
||||||
|
|
||||||
<pattern> is the pattern to look for. It may be a string or a regular
|
<pattern> is the pattern to look for. It may be a string or a regular
|
||||||
expression. If the pattern contains spaces, they must be escaped
|
expression. If the pattern contains spaces, they must be escaped
|
||||||
with the usual backslash ('\').
|
with the usual backslash ('\').
|
||||||
|
@ -268,6 +268,7 @@ struct tcpcheck_expect {
|
|||||||
struct list onsuccess_fmt; /* log-format string to use as comment on success (if last rule) */
|
struct list onsuccess_fmt; /* log-format string to use as comment on success (if last rule) */
|
||||||
enum healthcheck_status err_status; /* The healthcheck status to use on error (default: L7RSP) */
|
enum healthcheck_status err_status; /* The healthcheck status to use on error (default: L7RSP) */
|
||||||
enum healthcheck_status tout_status; /* The healthcheck status to use on timeout (default: L7TOUT) */
|
enum healthcheck_status tout_status; /* The healthcheck status to use on timeout (default: L7TOUT) */
|
||||||
|
struct sample_expr *status_expr; /* sample expr to determine the check status code */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tcpcheck_action_kw {
|
struct tcpcheck_action_kw {
|
||||||
|
67
src/checks.c
67
src/checks.c
@ -3187,6 +3187,16 @@ static enum tcpcheck_eval_ret tcpcheck_eval_expect(struct check *check, struct t
|
|||||||
chunk_appendf(msg, " comment: '%s'", rule->comment);
|
chunk_appendf(msg, " comment: '%s'", rule->comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expect->status_expr) {
|
||||||
|
struct sample *smp;
|
||||||
|
|
||||||
|
smp = sample_fetch_as_type(check->proxy, check->sess, NULL,
|
||||||
|
SMP_OPT_DIR_RES | SMP_OPT_FINAL,
|
||||||
|
expect->status_expr, SMP_T_SINT);
|
||||||
|
if (smp)
|
||||||
|
check->code = smp->data.u.sint;
|
||||||
|
}
|
||||||
|
|
||||||
no_desc:
|
no_desc:
|
||||||
set_server_check_status(check, expect->err_status, (msg ? b_head(msg) : NULL));
|
set_server_check_status(check, expect->err_status, (msg ? b_head(msg) : NULL));
|
||||||
ret = TCPCHK_EVAL_STOP;
|
ret = TCPCHK_EVAL_STOP;
|
||||||
@ -3386,12 +3396,23 @@ static int tcpcheck_main(struct check *check)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* All rules was evaluated */
|
/* All rules was evaluated */
|
||||||
if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT &&
|
if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT) {
|
||||||
!LIST_ISEMPTY(&check->current_step->expect.onsuccess_fmt)) {
|
if (!LIST_ISEMPTY(&check->current_step->expect.onsuccess_fmt)) {
|
||||||
msg = alloc_trash_chunk();
|
msg = alloc_trash_chunk();
|
||||||
if (msg)
|
if (msg)
|
||||||
msg->data += sess_build_logline(check->sess, NULL, b_tail(msg), b_room(msg),
|
msg->data += sess_build_logline(check->sess, NULL, b_tail(msg), b_room(msg),
|
||||||
&check->current_step->expect.onsuccess_fmt);
|
&check->current_step->expect.onsuccess_fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check->current_step->expect.status_expr) {
|
||||||
|
struct sample *smp;
|
||||||
|
|
||||||
|
smp = sample_fetch_as_type(check->proxy, check->sess, NULL,
|
||||||
|
SMP_OPT_DIR_RES | SMP_OPT_FINAL,
|
||||||
|
check->current_step->expect.status_expr, SMP_T_SINT);
|
||||||
|
if (smp)
|
||||||
|
check->code = smp->data.u.sint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_server_check_status(check, HCHK_STATUS_L7OKD, (msg ? b_head(msg) : "(tcp-check)"));
|
set_server_check_status(check, HCHK_STATUS_L7OKD, (msg ? b_head(msg) : "(tcp-check)"));
|
||||||
@ -3492,6 +3513,7 @@ static void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool)
|
|||||||
free(lf->arg);
|
free(lf->arg);
|
||||||
free(lf);
|
free(lf);
|
||||||
}
|
}
|
||||||
|
release_sample_expr(rule->expect.status_expr);
|
||||||
switch (rule->expect.type) {
|
switch (rule->expect.type) {
|
||||||
case TCPCHK_EXPECT_STRING:
|
case TCPCHK_EXPECT_STRING:
|
||||||
case TCPCHK_EXPECT_BINARY:
|
case TCPCHK_EXPECT_BINARY:
|
||||||
@ -4556,6 +4578,7 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
const char *file, int line, char **errmsg)
|
const char *file, int line, char **errmsg)
|
||||||
{
|
{
|
||||||
struct tcpcheck_rule *prev_check, *chk = NULL;
|
struct tcpcheck_rule *prev_check, *chk = NULL;
|
||||||
|
struct sample_expr *status_expr = NULL;
|
||||||
char *str, *on_success_msg, *on_error_msg, *comment, *pattern;
|
char *str, *on_success_msg, *on_error_msg, *comment, *pattern;
|
||||||
enum tcpcheck_expect_type type = TCPCHK_EXPECT_UNDEF;
|
enum tcpcheck_expect_type type = TCPCHK_EXPECT_UNDEF;
|
||||||
enum healthcheck_status err_st = HCHK_STATUS_L7RSP;
|
enum healthcheck_status err_st = HCHK_STATUS_L7RSP;
|
||||||
@ -4693,6 +4716,36 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
}
|
}
|
||||||
cur_arg++;
|
cur_arg++;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(args[cur_arg], "status-code") == 0) {
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (in_pattern) {
|
||||||
|
memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!*(args[cur_arg+1])) {
|
||||||
|
memprintf(errmsg, "'%s' expects an expression as argument", args[cur_arg]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_arg++;
|
||||||
|
release_sample_expr(status_expr);
|
||||||
|
px->conf.args.ctx = ARGC_SRV;
|
||||||
|
status_expr = sample_parse_expr((char *[]){args[cur_arg], NULL}, &idx,
|
||||||
|
file, line, errmsg, &px->conf.args, NULL);
|
||||||
|
if (!status_expr) {
|
||||||
|
memprintf(errmsg, "error detected while parsing status-code expression : %s", *errmsg);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!(status_expr->fetch->val & SMP_VAL_BE_CHK_RUL)) {
|
||||||
|
memprintf(errmsg, "error detected while parsing status-code expression : "
|
||||||
|
" fetch method '%s' extracts information from '%s', "
|
||||||
|
"none of which is available here.\n",
|
||||||
|
args[cur_arg], sample_src_names(status_expr->fetch->use));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
px->http_needed |= !!(status_expr->fetch->use & SMP_USE_HTTP_ANY);
|
||||||
|
}
|
||||||
else if (strcmp(args[cur_arg], "tout-status") == 0) {
|
else if (strcmp(args[cur_arg], "tout-status") == 0) {
|
||||||
if (in_pattern) {
|
if (in_pattern) {
|
||||||
memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]);
|
memprintf(errmsg, "[!] not supported with '%s'", args[cur_arg]);
|
||||||
@ -4758,6 +4811,7 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
chk->expect.with_capture = with_capture;
|
chk->expect.with_capture = with_capture;
|
||||||
chk->expect.err_status = err_st;
|
chk->expect.err_status = err_st;
|
||||||
chk->expect.tout_status = tout_st;
|
chk->expect.tout_status = tout_st;
|
||||||
|
chk->expect.status_expr = status_expr; status_expr = NULL;
|
||||||
|
|
||||||
if (on_success_msg) {
|
if (on_success_msg) {
|
||||||
px->conf.args.ctx = ARGC_SRV;
|
px->conf.args.ctx = ARGC_SRV;
|
||||||
@ -4825,6 +4879,7 @@ static struct tcpcheck_rule *parse_tcpcheck_expect(char **args, int cur_arg, str
|
|||||||
free(comment);
|
free(comment);
|
||||||
free(on_success_msg);
|
free(on_success_msg);
|
||||||
free(on_error_msg);
|
free(on_error_msg);
|
||||||
|
release_sample_expr(status_expr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user