MINOR: include comment in tcpcheck error log
tcpcheck error messages include the step id where the error occurs. In some cases, this is not enough. Now, HAProxy also use the comment field of the latest tcpcheck rule which has been run. This commit allows HAProxy to parse a new directive in the tcpcheck ruleset: 'comment'. It is used to setup comments on the current tcpcheck rules.
This commit is contained in:
parent
aa12b47b06
commit
22b09d2393
@ -204,6 +204,7 @@ enum {
|
||||
TCPCHK_ACT_SEND = 0, /* send action, regular string format */
|
||||
TCPCHK_ACT_EXPECT, /* expect action, either regular or binary string */
|
||||
TCPCHK_ACT_CONNECT, /* connect action, to probe a new port */
|
||||
TCPCHK_ACT_COMMENT, /* no action, simply a comment used for logs */
|
||||
};
|
||||
|
||||
/* flags used by tcpcheck_rule->conn_opts */
|
||||
|
105
src/cfgparse.c
105
src/cfgparse.c
@ -2106,7 +2106,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
rc = PR_CAP_LISTEN;
|
||||
else if (!strcmp(args[0], "frontend"))
|
||||
rc = PR_CAP_FE | PR_CAP_RS;
|
||||
else if (!strcmp(args[0], "backend"))
|
||||
else if (!strcmp(args[0], "backend"))
|
||||
rc = PR_CAP_BE | PR_CAP_RS;
|
||||
else if (!strcmp(args[0], "ruleset"))
|
||||
rc = PR_CAP_RS;
|
||||
@ -4683,7 +4683,26 @@ stats_error_parsing:
|
||||
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
|
||||
err_code |= ERR_WARN;
|
||||
|
||||
if (strcmp(args[1], "connect") == 0) {
|
||||
if (strcmp(args[1], "comment") == 0) {
|
||||
int cur_arg;
|
||||
struct tcpcheck_rule *tcpcheck;
|
||||
|
||||
cur_arg = 1;
|
||||
tcpcheck = (struct tcpcheck_rule *)calloc(1, sizeof(*tcpcheck));
|
||||
tcpcheck->action = TCPCHK_ACT_COMMENT;
|
||||
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tcpcheck->comment = strdup(args[cur_arg + 1]);
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
else if (strcmp(args[1], "connect") == 0) {
|
||||
const char *ptr_arg;
|
||||
int cur_arg;
|
||||
struct tcpcheck_rule *tcpcheck;
|
||||
@ -4693,6 +4712,13 @@ stats_error_parsing:
|
||||
l = (struct list *)&curproxy->tcpcheck_rules;
|
||||
if (l->p != l->n) {
|
||||
tcpcheck = (struct tcpcheck_rule *)l->n;
|
||||
while (tcpcheck->action == TCPCHK_ACT_COMMENT) {
|
||||
tcpcheck = (struct tcpcheck_rule *)tcpcheck->list.n;
|
||||
}
|
||||
/* we've reached the end of the list, and the list is full of comments */
|
||||
if (tcpcheck == (struct tcpcheck_rule *)l)
|
||||
tcpcheck = NULL;
|
||||
|
||||
if (tcpcheck && tcpcheck->action != TCPCHK_ACT_CONNECT) {
|
||||
Alert("parsing [%s:%d] : first step MUST also be a 'connect' when there is a 'connect' step in the tcp-check ruleset.\n",
|
||||
file, linenum);
|
||||
@ -4731,11 +4757,22 @@ stats_error_parsing:
|
||||
cur_arg++;
|
||||
}
|
||||
#endif /* USE_OPENSSL */
|
||||
/* comment for this tcpcheck line */
|
||||
else if (strcmp(args[cur_arg], "comment") == 0) {
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[cur_arg + 1]);
|
||||
cur_arg += 2;
|
||||
}
|
||||
else {
|
||||
#ifdef USE_OPENSSL
|
||||
Alert("parsing [%s:%d] : '%s %s' expects 'port', 'send-proxy' or 'ssl' but got '%s' as argument.\n",
|
||||
Alert("parsing [%s:%d] : '%s %s' expects 'comment', 'port', 'send-proxy' or 'ssl' but got '%s' as argument.\n",
|
||||
#else /* USE_OPENSSL */
|
||||
Alert("parsing [%s:%d] : '%s %s' expects 'port', 'send-proxy' or but got '%s' as argument.\n",
|
||||
Alert("parsing [%s:%d] : '%s %s' expects 'comment', 'port', 'send-proxy' or but got '%s' as argument.\n",
|
||||
#endif /* USE_OPENSSL */
|
||||
file, linenum, args[0], args[1], args[cur_arg]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
@ -4763,6 +4800,17 @@ stats_error_parsing:
|
||||
tcpcheck->string = strdup(args[2]);
|
||||
tcpcheck->expect_regex = NULL;
|
||||
|
||||
/* comment for this tcpcheck line */
|
||||
if (strcmp(args[3], "comment") == 0) {
|
||||
if (!*args[4]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[4]);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
}
|
||||
@ -4788,6 +4836,17 @@ stats_error_parsing:
|
||||
}
|
||||
tcpcheck->expect_regex = NULL;
|
||||
|
||||
/* comment for this tcpcheck line */
|
||||
if (strcmp(args[3], "comment") == 0) {
|
||||
if (!*args[4]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[4]);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
}
|
||||
@ -4839,6 +4898,18 @@ stats_error_parsing:
|
||||
tcpcheck->expect_regex = NULL;
|
||||
tcpcheck->inverse = inverse;
|
||||
|
||||
/* tcpcheck comment */
|
||||
cur_arg += 2;
|
||||
if (strcmp(args[cur_arg], "comment") == 0) {
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[cur_arg + 1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[cur_arg + 1]);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "string") == 0) {
|
||||
@ -4859,6 +4930,18 @@ stats_error_parsing:
|
||||
tcpcheck->expect_regex = NULL;
|
||||
tcpcheck->inverse = inverse;
|
||||
|
||||
/* tcpcheck comment */
|
||||
cur_arg += 2;
|
||||
if (strcmp(args[cur_arg], "comment") == 0) {
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[cur_arg + 1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[cur_arg + 1]);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
else if (strcmp(ptr_arg, "rstring") == 0) {
|
||||
@ -4887,6 +4970,18 @@ stats_error_parsing:
|
||||
}
|
||||
tcpcheck->inverse = inverse;
|
||||
|
||||
/* tcpcheck comment */
|
||||
cur_arg += 2;
|
||||
if (strcmp(args[cur_arg], "comment") == 0) {
|
||||
if (!*args[cur_arg + 1]) {
|
||||
Alert("parsing [%s:%d] : '%s' expects a comment string.\n",
|
||||
file, linenum, args[cur_arg + 1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
tcpcheck->comment = strdup(args[cur_arg + 1]);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
|
||||
}
|
||||
else {
|
||||
@ -4897,7 +4992,7 @@ stats_error_parsing:
|
||||
}
|
||||
}
|
||||
else {
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'connect', 'send' or 'expect'.\n", file, linenum, args[0]);
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'comment', 'connect', 'send' or 'expect'.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
92
src/checks.c
92
src/checks.c
@ -62,6 +62,7 @@
|
||||
|
||||
static int httpchk_expect(struct server *s, int done);
|
||||
static int tcpcheck_get_step_id(struct check *);
|
||||
static char * tcpcheck_get_step_comment(struct check *, int);
|
||||
static void tcpcheck_main(struct connection *);
|
||||
|
||||
static const struct check_status check_statuses[HCHK_STATUS_SIZE] = {
|
||||
@ -608,6 +609,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
|
||||
const char *err_msg;
|
||||
struct chunk *chk;
|
||||
int step;
|
||||
char *comment;
|
||||
|
||||
if (check->result != CHK_RES_UNKNOWN)
|
||||
return;
|
||||
@ -648,6 +650,10 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi
|
||||
else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_SEND) {
|
||||
chunk_appendf(chk, " (send)");
|
||||
}
|
||||
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(chk, " comment: '%s'", comment);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2382,9 +2388,44 @@ static int tcpcheck_get_step_id(struct check *check)
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the latest known comment before (including) the given stepid
|
||||
* returns NULL if no comment found
|
||||
*/
|
||||
static char * tcpcheck_get_step_comment(struct check *check, int stepid)
|
||||
{
|
||||
struct tcpcheck_rule *cur = NULL;
|
||||
char *ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
/* not even started anything yet, return latest comment found before any action */
|
||||
if (!check->current_step) {
|
||||
list_for_each_entry(cur, check->tcpcheck_rules, list) {
|
||||
if (cur->action == TCPCHK_ACT_COMMENT)
|
||||
ret = cur->comment;
|
||||
else
|
||||
goto return_comment;
|
||||
}
|
||||
}
|
||||
|
||||
i = 1;
|
||||
list_for_each_entry(cur, check->tcpcheck_rules, list) {
|
||||
if (cur->comment)
|
||||
ret = cur->comment;
|
||||
|
||||
if (i >= stepid)
|
||||
goto return_comment;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return_comment:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tcpcheck_main(struct connection *conn)
|
||||
{
|
||||
char *contentptr;
|
||||
char *contentptr, *comment;
|
||||
struct tcpcheck_rule *cur, *next;
|
||||
int done = 0, ret = 0, step = 0;
|
||||
struct check *check = conn->owner;
|
||||
@ -2483,6 +2524,12 @@ static void tcpcheck_main(struct connection *conn)
|
||||
|
||||
/* have 'next' point to the next rule or NULL if we're on the last one */
|
||||
next = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (next->action == TCPCHK_ACT_COMMENT)
|
||||
next = (struct tcpcheck_rule *)next->list.n;
|
||||
|
||||
/* NULL if we're on the last rule */
|
||||
if (&next->list == head)
|
||||
next = NULL;
|
||||
|
||||
@ -2572,6 +2619,9 @@ static void tcpcheck_main(struct connection *conn)
|
||||
step = tcpcheck_get_step_id(check);
|
||||
chunk_printf(&trash, "TCPCHK error establishing connection at step %d: %s",
|
||||
step, strerror(errno));
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_L4CON, trash.str);
|
||||
goto out_end_tcpcheck;
|
||||
case SF_ERR_PRXCOND:
|
||||
@ -2579,12 +2629,20 @@ static void tcpcheck_main(struct connection *conn)
|
||||
case SF_ERR_INTERNAL:
|
||||
step = tcpcheck_get_step_id(check);
|
||||
chunk_printf(&trash, "TCPCHK error establishing connection at step %d", step);
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_SOCKERR, trash.str);
|
||||
goto out_end_tcpcheck;
|
||||
}
|
||||
|
||||
/* allow next rule */
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (cur->action == TCPCHK_ACT_COMMENT)
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
check->current_step = cur;
|
||||
|
||||
/* don't do anything until the connection is established */
|
||||
@ -2640,6 +2698,11 @@ static void tcpcheck_main(struct connection *conn)
|
||||
|
||||
/* go to next rule and try to send */
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (cur->action == TCPCHK_ACT_COMMENT)
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
check->current_step = cur;
|
||||
} /* end 'send' */
|
||||
else if (check->current_step->action == TCPCHK_ACT_EXPECT) {
|
||||
@ -2688,6 +2751,9 @@ static void tcpcheck_main(struct connection *conn)
|
||||
/* empty response */
|
||||
step = tcpcheck_get_step_id(check);
|
||||
chunk_printf(&trash, "TCPCHK got an empty response at step %d", step);
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.str);
|
||||
|
||||
goto out_end_tcpcheck;
|
||||
@ -2719,13 +2785,23 @@ static void tcpcheck_main(struct connection *conn)
|
||||
/* we were looking for a regex */
|
||||
chunk_printf(&trash, "TCPCHK matched unwanted content (regex) at step %d", step);
|
||||
}
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.str);
|
||||
goto out_end_tcpcheck;
|
||||
}
|
||||
/* matched and was supposed to => OK, next step */
|
||||
else {
|
||||
cur = (struct tcpcheck_rule*)cur->list.n;
|
||||
/* allow next rule */
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (cur->action == TCPCHK_ACT_COMMENT)
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
check->current_step = cur;
|
||||
|
||||
if (check->current_step->action == TCPCHK_ACT_EXPECT)
|
||||
goto tcpcheck_expect;
|
||||
__conn_data_stop_recv(conn);
|
||||
@ -2735,6 +2811,15 @@ static void tcpcheck_main(struct connection *conn)
|
||||
/* not matched */
|
||||
/* not matched and was not supposed to => OK, next step */
|
||||
if (cur->inverse) {
|
||||
/* allow next rule */
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
/* bypass all comment rules */
|
||||
while (cur->action == TCPCHK_ACT_COMMENT)
|
||||
cur = (struct tcpcheck_rule *)cur->list.n;
|
||||
|
||||
check->current_step = cur;
|
||||
|
||||
cur = (struct tcpcheck_rule*)cur->list.n;
|
||||
check->current_step = cur;
|
||||
if (check->current_step->action == TCPCHK_ACT_EXPECT)
|
||||
@ -2753,6 +2838,9 @@ static void tcpcheck_main(struct connection *conn)
|
||||
chunk_printf(&trash, "TCPCHK did not match content (regex) at step %d",
|
||||
step);
|
||||
}
|
||||
comment = tcpcheck_get_step_comment(check, step);
|
||||
if (comment)
|
||||
chunk_appendf(&trash, " comment: '%s'", comment);
|
||||
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.str);
|
||||
goto out_end_tcpcheck;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user