This patch provides some statistics about the conditions used in the
configuration. The main goal is to have a debugging tool to track
misconfigurations or to understand how the rules are applied.
The statistics are available on the UNIX socket with the below command :
show conds
Counters can be reset without the need to restart HAProxy, allowing the
statistics to be periodically monitored.
---
include/common/mini-clist.h | 13 ++
include/proto/dumpstats.h | 3 +
include/types/acl.h | 10 ++
include/types/proto_http.h | 1 +
include/types/proxy.h | 2 +
include/types/session.h | 28 ++++-
src/acl.c | 29 ++++-
src/cfgparse.c | 5 +
src/dumpstats.c | 317 ++++++++++++++++++++++++++++++++++++++++---
9 files changed, 382 insertions(+), 26 deletions(-)
diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h
index e89ffe0..0e10b47 100644
--- a/include/common/mini-clist.h
+++ b/include/common/mini-clist.h
@@ -185,6 +185,19 @@ struct cond_wordlist {
item = LIST_ELEM(item->member.n, typeof(item), member))
/*
+ * Iterates <item> through a list of items of type "typeof(*item)" which are
+ * linked via a "struct list" member named <member>, starting from a given item
+ * in the list. A pointer to the head of the list is passed in <list_head>,
+ * another pointer to the starting item is passed in <from>.
+ * No temporary variable is needed. Note that <item> must not be modified
during
+ * the loop.
+ */
+#define list_for_each_entry_from(item, list_head, from, member) \
+ for (item = LIST_ELEM((from)->n, typeof(item), member); \
+ &item->member != (list_head); \
+ item = LIST_ELEM(item->member.n, typeof(item), member))
+
+/*
* Simpler FOREACH_ITEM_SAFE macro inspired from Linux sources.
* Iterates <item> through a list of items of type "typeof(*item)" which are
* linked via a "struct list" member named <member>. A pointer to the head of
diff --git a/include/proto/dumpstats.h b/include/proto/dumpstats.h
index 9cf5eec..9019255 100644
--- a/include/proto/dumpstats.h
+++ b/include/proto/dumpstats.h
@@ -53,6 +53,7 @@
#define STAT_CLI_O_SESS 6 /* dump sessions */
#define STAT_CLI_O_ERR 7 /* dump errors */
#define STAT_CLI_O_TAB 8 /* dump tables */
+#define STAT_CLI_O_COND 9 /* dump conditions */
/* status codes (strictly 4 chars) used in the URL to display a message */
#define STAT_STATUS_UNKN "UNKN" /* an unknown error occured, shouldn't
happen */
@@ -71,6 +72,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px,
struct uri_auth *uri);
int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep);
int stats_dump_table_to_buffer(struct session *s, struct buffer *rep);
int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
+int stats_dump_conds_to_buffer(struct session *s, struct buffer *rep);
+int stats_dump_conds_proxy(struct session *s, struct proxy *px);
void http_stats_io_handler(struct stream_interface *si);
diff --git a/include/types/acl.h b/include/types/acl.h
index 58ea7cc..bf8eb21 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -325,11 +325,14 @@ struct acl_term {
struct list list; /* chaining */
struct acl *acl; /* acl pointed to by this term */
int neg; /* 1 if the ACL result must be negated */
+ int uid;
+ long long tot_pass, tot_fail;
};
struct acl_term_suite {
struct list list; /* chaining of term suites */
struct list terms; /* list of acl_terms */
+ int uid;
};
struct acl_cond {
@@ -339,6 +342,13 @@ struct acl_cond {
unsigned int requires; /* or'ed bit mask of all acl's ACL_USE_* */
const char *file; /* config file where the condition is
declared */
int line; /* line in the config file where the
condition is declared */
+ int uid;
+ long long tot_pass, tot_fail;
+};
+
+struct acl_conds {
+ struct list list; /* chaining of acl_conds */
+ struct acl_cond *cond;
};
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 2222304..192b5ff 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -208,6 +208,7 @@ enum {
DATA_ST_PX_LI,
DATA_ST_PX_SV,
DATA_ST_PX_BE,
+ DATA_ST_PX_AC,
DATA_ST_PX_END,
DATA_ST_PX_FIN,
};
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 7a3276e..9671046 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -311,6 +311,8 @@ struct proxy {
unsigned int bind_proc; /* bitmask of processes using
this proxy. 0 = all. */
struct error_snapshot invalid_req, invalid_rep; /* captures of last
errors */
+ struct list acl_conds; /* the full list of acl_conds
used by this proxy */
+
/* used only during configuration parsing */
int no_options; /* PR_O_REDISP, PR_O_TRANSP,
... */
int no_options2; /* PR_O2_* */
diff --git a/include/types/session.h b/include/types/session.h
index 0bbb9bf..5dcdad0 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -212,11 +212,31 @@ struct session {
union {
struct {
struct proxy *px;
- struct server *sv;
- struct listener *l;
- short px_st, sv_st; /* DATA_ST_INIT or DATA_ST_DATA
*/
+ short px_st; /* DATA_ST_INIT or DATA_ST_DATA
*/
unsigned int flags; /* STAT_* */
- int iid, type, sid; /* proxy id, type and service
id if bounding of stats is enabled */
+ int iid; /* proxy id if bounding of
stats is enabled */
+ union {
+ /* used by "show conds" */
+ struct {
+ int cuid, suid; /* current cond and
suite uids being dumped */
+ struct list *cl;/* current cond list
item */
+ struct list *sl;/* current suite list
item */
+ struct list *tl;/* current term list
item */
+ /* if bounding of stats is enabled */
+ int bcid; /* acl_cond id */
+ int bsid; /* acl_term_suite id */
+ int btid; /* acl_term id */
+ } conds;
+ /* default structure for other commands */
+ struct {
+ struct listener *l;
+ struct server *sv;
+ short sv_st; /* DATA_ST_INIT or
DATA_ST_DATA */
+ /* if bounding of stats is enabled */
+ int type; /* type of dumpable
objects */
+ int sid; /* service id */
+ } def;
+ } cmd;
const char *st_code; /* pointer to the status code
returned by an action */
} stats;
struct {
diff --git a/src/acl.c b/src/acl.c
index c8a5a88..aa546ed 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -29,6 +29,8 @@
#include <ebsttree.h>
+int next_cond_uid = 1;
+
/* The capabilities of filtering hooks describe the type of information
* available to each of them.
*/
@@ -1406,6 +1408,7 @@ struct acl_cond *parse_acl_cond(const char **args, struct
list *known_acl, int p
{
__label__ out_return, out_free_suite, out_free_term;
int arg, neg;
+ int next_suite_uid, next_term_uid;
const char *word;
struct acl *cur_acl;
struct acl_term *cur_term;
@@ -1422,6 +1425,7 @@ struct acl_cond *parse_acl_cond(const char **args, struct
list *known_acl, int p
cur_suite = NULL;
neg = 0;
+ next_suite_uid = next_term_uid = 1;
for (arg = 0; *args[arg]; arg++) {
word = args[arg];
@@ -1477,6 +1481,8 @@ struct acl_cond *parse_acl_cond(const char **args, struct
list *known_acl, int p
* it to the list of ACLs of this proxy. This makes it
possible
* to override them.
*/
+ if (invalid_char(word))
+ goto out_free_suite;
cur_acl = find_acl_by_name(word, known_acl);
if (cur_acl == NULL) {
cur_acl = find_acl_default(word, known_acl);
@@ -1494,12 +1500,15 @@ struct acl_cond *parse_acl_cond(const char **args,
struct list *known_acl, int p
cond->requires |= cur_acl->requires;
if (!cur_suite) {
+ next_term_uid = 1;
cur_suite = (struct acl_term_suite *)calloc(1,
sizeof(*cur_suite));
- if (cur_term == NULL)
+ if (cur_suite == NULL)
goto out_free_term;
+ cur_suite->uid = next_suite_uid++;
LIST_INIT(&cur_suite->terms);
LIST_ADDQ(&cond->suites, &cur_suite->list);
}
+ cur_term->uid = next_term_uid++;
LIST_ADDQ(&cur_suite->terms, &cur_term->list);
neg = 0;
}
@@ -1543,6 +1552,13 @@ struct acl_cond *build_acl_cond(const char *file, int
line, struct proxy *px, co
cond->file = file;
cond->line = line;
+ cond->uid = next_cond_uid++;
+
+ struct acl_conds *conds;
+ conds = (struct acl_conds *)calloc(1, sizeof(*conds));
+ conds->cond = cond;
+ LIST_ADDQ(&px->acl_conds, &conds->list);
+
px->acl_requires |= cond->requires;
return cond;
@@ -1674,6 +1690,11 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy
*px, struct session *l4, v
if (term->neg)
acl_res = acl_neg(acl_res);
+ if (acl_res & ACL_PAT_PASS)
+ term->tot_pass++;
+ else
+ term->tot_fail++;
+
suite_res &= acl_res;
/* we're ANDing these terms, so a single FAIL is enough
*/
@@ -1686,6 +1707,12 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy
*px, struct session *l4, v
if (cond_res == ACL_PAT_PASS)
break;
}
+
+ if (cond_res & ACL_PAT_PASS)
+ cond->tot_pass++;
+ else
+ cond->tot_fail++;
+
return cond_res;
}
diff --git a/src/cfgparse.c b/src/cfgparse.c
index dd266af..a9e5393 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -64,6 +64,8 @@
#include <proto/stick_table.h>
+extern int next_cond_uid;
+
/* This is the SSLv3 CLIENT HELLO packet used in conjunction with the
* ssl-hello-chk option to ensure that the remote server speaks SSL.
*
@@ -1071,10 +1073,13 @@ static void init_new_proxy(struct proxy *p)
LIST_INIT(&p->tcp_req.l4_rules);
LIST_INIT(&p->req_add);
LIST_INIT(&p->rsp_add);
+ LIST_INIT(&p->acl_conds);
/* Timeouts are defined as -1 */
proxy_reset_timeouts(p);
p->tcp_rep.inspect_delay = TICK_ETERNITY;
+
+ next_cond_uid = 1;
}
void init_default_instance()
diff --git a/src/dumpstats.c b/src/dumpstats.c
index a45d40a..a254ce6 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -64,6 +64,7 @@ const char stats_sock_usage_msg[] =
" show info : report information about the running process\n"
" show stat : report counters for each proxy and server\n"
" show errors : report last request and response errors for each
proxy\n"
+ " show conds : report statistics about the conditions\n"
" show sess [id] : report the list of current sessions or dump this
session\n"
" show table [id]: report table usage stats or dump this table's
contents\n"
" get weight : report a server's current weight\n"
@@ -349,12 +350,48 @@ int stats_sock_parse_request(struct stream_interface *si,
char *line)
s->data_ctx.stats.flags = 0;
if (strcmp(args[0], "show") == 0) {
- if (strcmp(args[1], "stat") == 0) {
+ if (strcmp(args[1], "conds") == 0) {
+ int n = 2;
+
+ s->data_state = DATA_ST_INIT;
+ si->st0 = STAT_CLI_O_COND; // stats_dump_conds_to_buffer
+
+ if (strcmp(args[n], "clear") == 0) {
+ s->data_ctx.stats.flags |= STAT_ADMIN;
+ n++;
+ }
+ if (*args[n]) {
+ s->data_ctx.stats.flags |= STAT_BOUND;
+ s->data_ctx.stats.iid = atoi(args[n]);
+ }
+ /* bounding cond */
+ if (*args[n + 1]) {
+ s->data_ctx.stats.cmd.conds.bcid = atoi(args[n
+ 1]);
+ }
+ else {
+ s->data_ctx.stats.cmd.conds.bcid = -1;
+ }
+ /* bounding suite */
+ if (*args[n + 2]) {
+ s->data_ctx.stats.cmd.conds.bsid = atoi(args[n
+ 2]);
+ }
+ else {
+ s->data_ctx.stats.cmd.conds.bsid = -1;
+ }
+ /* bounding term */
+ if (*args[n + 3]) {
+ s->data_ctx.stats.cmd.conds.btid = atoi(args[n
+ 3]);
+ }
+ else {
+ s->data_ctx.stats.cmd.conds.btid = -1;
+ }
+ }
+ else if (strcmp(args[1], "stat") == 0) {
if (*args[2] && *args[3] && *args[4]) {
s->data_ctx.stats.flags |= STAT_BOUND;
- s->data_ctx.stats.iid = atoi(args[2]);
- s->data_ctx.stats.type = atoi(args[3]);
- s->data_ctx.stats.sid = atoi(args[4]);
+ s->data_ctx.stats.iid = atoi(args[2]);
+ s->data_ctx.stats.cmd.def.type = atoi(args[3]);
+ s->data_ctx.stats.cmd.def.sid = atoi(args[4]);
}
s->data_ctx.stats.flags |= STAT_SHOW_STAT;
@@ -930,6 +967,10 @@ void stats_io_handler(struct stream_interface *si)
}
switch (si->st0) {
+ case STAT_CLI_O_COND:
+ if (stats_dump_conds_to_buffer(s, res))
+ si->st0 = STAT_CLI_PROMPT;
+ break;
case STAT_CLI_PRINT:
if (buffer_feed(si->ib, s->data_ctx.cli.msg) <
0)
si->st0 = STAT_CLI_PROMPT;
@@ -1021,6 +1062,71 @@ void stats_io_handler(struct stream_interface *si)
}
/* This function is called to send output to the response buffer.
+ * It dumps conditions statistics onto the output buffer <rep>
+ * owned by session <s>.
+ * s->data_ctx must have been zeroed first, and the flags properly set.
+ * It returns 0 as long as it does not complete, non-zero upon completion.
+ */
+int stats_dump_conds_to_buffer(struct session *s, struct buffer *rep)
+{
+ struct proxy *px;
+ struct chunk msg;
+
+ chunk_init(&msg, trash, sizeof(trash));
+
+ switch (s->data_state) {
+ case DATA_ST_INIT:
+ /* the function had not been called yet */
+ s->data_state = DATA_ST_HEAD;
+ /* fall through */
+
+ case DATA_ST_HEAD:
+ chunk_printf(&msg, "pct,pass,fail,path,detail\n");
+ if (buffer_feed_chunk(rep, &msg) >= 0)
+ return 0;
+ s->data_state = DATA_ST_INFO;
+ /* fall through */
+
+ case DATA_ST_INFO:
+ s->data_ctx.stats.px = proxy;
+ s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
+
+ s->data_state = DATA_ST_LIST;
+ /* fall through */
+
+ case DATA_ST_LIST:
+ /* dump proxies */
+ while (s->data_ctx.stats.px) {
+ px = s->data_ctx.stats.px;
+ /* skip the disabled proxies and non-networked ones */
+ if (px->state != PR_STSTOPPED &&
+ (px->cap & (PR_CAP_FE | PR_CAP_BE))) {
+ if (stats_dump_conds_proxy(s, px) == 0)
+ return 0;
+ }
+
+ s->data_ctx.stats.px = px->next;
+ s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
+ }
+
+ s->data_state = DATA_ST_END;
+ /* fall through */
+
+ case DATA_ST_END:
+ s->data_state = DATA_ST_FIN;
+ /* fall through */
+
+ case DATA_ST_FIN:
+ return 1;
+
+ default:
+ /* unknown state ! */
+ s->data_state = DATA_ST_FIN;
+ return 1;
+ }
+}
+
+/* This function is called to send output to the response buffer.
* It dumps statistics onto the output buffer <rep> owned by session <s>.
* s->data_ctx must have been zeroed first, and the flags properly set.
* It returns 0 as long as it does not complete, non-zero upon completion.
@@ -1095,8 +1201,8 @@ int stats_dump_raw_to_buffer(struct session *s, struct
buffer *rep)
s->data_ctx.stats.px = proxy;
s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
- s->data_ctx.stats.sv = NULL;
- s->data_ctx.stats.sv_st = 0;
+ s->data_ctx.stats.cmd.def.sv = NULL;
+ s->data_ctx.stats.cmd.def.sv_st = 0;
s->data_state = DATA_ST_LIST;
/* fall through */
@@ -1231,6 +1337,175 @@ void http_stats_io_handler(struct stream_interface *si)
/*
+ * Dumps conditions statistics for a proxy.
+ * Returns 0 if it had to stop dumping data because of lack of buffer space,
+ * ot non-zero if everything completed.
+ */
+int stats_dump_conds_proxy(struct session *s, struct proxy *px)
+{
+ struct buffer *rep = s->rep;
+ struct acl_conds *conds;
+ struct chunk msg;
+
+ chunk_init(&msg, trash, sizeof(trash));
+
+ switch (s->data_ctx.stats.px_st) {
+ case DATA_ST_PX_INIT:
+ /* we are on a new proxy */
+ if ((s->data_ctx.stats.flags & STAT_BOUND) &&
+ (s->data_ctx.stats.iid != -1) &&
+ (px->uuid != s->data_ctx.stats.iid))
+ return 1;
+
+ s->data_ctx.stats.cmd.conds.cl = &px->acl_conds;
+ s->data_ctx.stats.cmd.conds.cuid = 0;
+ if (!(s->data_ctx.stats.flags & STAT_BOUND) ||
+ (s->data_ctx.stats.cmd.conds.bcid <= 0)) {
+ chunk_printf(&msg, ",,,%d-0-0-0,[PROXY %s (#%d) %s]\n",
+ px->uuid, px->id, px->uuid, px->conf.file);
+ if (buffer_feed_chunk(rep, &msg) >= 0)
+ return 0;
+ }
+
+ s->data_ctx.stats.px_st = DATA_ST_PX_AC;
+ /* fall through */
+
+ case DATA_ST_PX_AC:
+ list_for_each_entry_from(conds, &px->acl_conds,
s->data_ctx.stats.cmd.conds.cl, list) {
+ struct acl_cond *cond;
+ struct acl_term_suite *suite;
+
+ cond = conds->cond;
+
+ /* filter conds not matching the bound one */
+ if ((s->data_ctx.stats.flags & STAT_BOUND) &&
+ (s->data_ctx.stats.cmd.conds.bcid != -1)) {
+ if (cond->uid <
s->data_ctx.stats.cmd.conds.bcid) {
+ continue;
+ }
+ else if (cond->uid >
s->data_ctx.stats.cmd.conds.bcid) {
+ return 1;
+ }
+ }
+
+ if (cond->uid > s->data_ctx.stats.cmd.conds.cuid) {
+ if (!(s->data_ctx.stats.flags & STAT_BOUND) ||
+ (s->data_ctx.stats.cmd.conds.bsid <= 0)) {
+ chunk_printf(&msg,
"%.2f,%lld,%lld,%d-%d-0-0,[%s line %d]\n",
+ (cond->tot_pass +
cond->tot_fail) ? 100LL * cond->tot_pass / (double) (cond->tot_pass +
cond->tot_fail) : 0LL,
+ cond->tot_pass, cond->tot_fail,
+ px->uuid, cond->uid,
+ (cond->pol == ACL_COND_IF) ?
"IF" : "UNLESS", cond->line);
+ if (buffer_feed_chunk(rep, &msg) >= 0)
+ return 0;
+ }
+
+ s->data_ctx.stats.cmd.conds.cuid = cond->uid;
+ s->data_ctx.stats.cmd.conds.suid = 0;
+ s->data_ctx.stats.cmd.conds.sl = &cond->suites;
+ }
+
+ list_for_each_entry_from(suite, &cond->suites,
s->data_ctx.stats.cmd.conds.sl, list) {
+ struct acl_term *term;
+
+ /* filter suites not matching the bound one */
+ if ((s->data_ctx.stats.flags & STAT_BOUND) &&
+ (s->data_ctx.stats.cmd.conds.bsid != -1)) {
+ if (suite->uid <
s->data_ctx.stats.cmd.conds.bsid) {
+ continue;
+ }
+ else if (suite->uid >
s->data_ctx.stats.cmd.conds.bsid) {
+ return 1;
+ }
+ }
+
+ if (suite->uid >
s->data_ctx.stats.cmd.conds.suid) {
+ if ((suite->uid > 1) &&
+ (!(s->data_ctx.stats.flags &
STAT_BOUND) ||
+ (s->data_ctx.stats.cmd.conds.bsid
== -1))) {
+ chunk_printf(&msg,
",,,%d-%d-%d-0,[OR]\n",
+ px->uuid, cond->uid,
suite->uid);
+ if (buffer_feed_chunk(rep,
&msg) >= 0)
+ return 0;
+ }
+
+ s->data_ctx.stats.cmd.conds.suid =
suite->uid;
+ s->data_ctx.stats.cmd.conds.tl =
&suite->terms;
+ }
+ list_for_each_entry_from(term, &suite->terms,
s->data_ctx.stats.cmd.conds.tl, list) {
+ struct acl_expr *expr;
+ struct acl_keyword * keyword;
+
+ /* filter terms not matching the bound
one */
+ if ((s->data_ctx.stats.flags &
STAT_BOUND) &&
+ (s->data_ctx.stats.cmd.conds.btid
!= -1)) {
+ if (term->uid <
s->data_ctx.stats.cmd.conds.btid) {
+ continue;
+ }
+ else if (term->uid >
s->data_ctx.stats.cmd.conds.btid) {
+ return 1;
+ }
+ }
+
+ if (!(s->data_ctx.stats.flags &
STAT_BOUND) ||
+ (s->data_ctx.stats.cmd.conds.btid
== -1) ||
+ (s->data_ctx.stats.cmd.conds.btid
== term->uid)) {
+ /* anonymous acl, we'll display
the first keyword */
+ expr = NULL;
+ keyword = NULL;
+ if (! *term->acl->name) {
+ expr =
LIST_NEXT(&term->acl->expr, struct acl_expr *, list);
+ if (expr) {
+ keyword =
expr->kw;
+ }
+ }
+
+ chunk_printf(&msg,
"%.2f,%lld,%lld,%d-%d-%d-%d,%s%s%s%s%s%s%s\n",
+ (term->tot_pass +
term->tot_fail) ? 100LL * term->tot_pass / (double) (term->tot_pass +
term->tot_fail) : 0LL,
+ term->tot_pass,
term->tot_fail,
+ px->uuid, cond->uid,
suite->uid, term->uid,
+ term->neg ? "!" : "",
+ keyword ? "{ " :
term->acl->name,
+ keyword ? keyword->kw
: "",
+ expr && expr->arg_len ?
"(" : "",
+ expr && expr->arg_len ?
expr->arg.str : "",
+ expr && expr->arg_len ?
")" : "",
+ keyword ? " }" : "");
+ if (buffer_feed_chunk(rep,
&msg) >= 0)
+ return 0;
+ }
+
+ s->data_ctx.stats.cmd.conds.tl =
&term->list;
+
+ if (s->data_ctx.stats.flags &
STAT_ADMIN) {
+ term->tot_pass = 0;
+ term->tot_fail = 0;
+ }
+ }
+ s->data_ctx.stats.cmd.conds.sl = &suite->list;
+ }
+
+ s->data_ctx.stats.cmd.conds.cl = &conds->list;
+ if (s->data_ctx.stats.flags & STAT_ADMIN) {
+ cond->tot_pass = 0;
+ cond->tot_fail = 0;
+ }
+ }
+
+ s->data_ctx.stats.px_st = DATA_ST_PX_FIN;
+ /* fall through */
+
+ case DATA_ST_PX_FIN:
+ return 1;
+
+ default:
+ /* unknown state, we should put an abort() here ! */
+ return 1;
+ }
+}
+
+
+/*
* Produces statistics data for the session <s>. Expects to be called with
* client socket shut down on input. It stops by itself by unsetting the
* BF_HIJACK flag from the buffer, which it uses to keep on being called
@@ -1702,7 +1977,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px,
struct uri_auth *uri)
case DATA_ST_PX_FE:
/* print the frontend */
if ((px->cap & PR_CAP_FE) &&
- (!(s->data_ctx.stats.flags & STAT_BOUND) ||
(s->data_ctx.stats.type & (1 << STATS_TYPE_FE)))) {
+ (!(s->data_ctx.stats.flags & STAT_BOUND) ||
(s->data_ctx.stats.cmd.def.type & (1 << STATS_TYPE_FE)))) {
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg,
/* name, queue */
@@ -1852,25 +2127,25 @@ int stats_dump_proxy(struct session *s, struct proxy
*px, struct uri_auth *uri)
return 0;
}
- s->data_ctx.stats.l = px->listen; /* may be NULL */
+ s->data_ctx.stats.cmd.def.l = px->listen; /* may be NULL */
s->data_ctx.stats.px_st = DATA_ST_PX_LI;
/* fall through */
case DATA_ST_PX_LI:
- /* stats.l has been initialized above */
- for (; s->data_ctx.stats.l != NULL; s->data_ctx.stats.l =
l->next) {
+ /* stats.cmd.def.l has been initialized above */
+ for (; s->data_ctx.stats.cmd.def.l != NULL;
s->data_ctx.stats.cmd.def.l = l->next) {
if (buffer_almost_full(rep))
return 0;
- l = s->data_ctx.stats.l;
+ l = s->data_ctx.stats.cmd.def.l;
if (!l->counters)
continue;
if (s->data_ctx.stats.flags & STAT_BOUND) {
- if (!(s->data_ctx.stats.type & (1 <<
STATS_TYPE_SO)))
+ if (!(s->data_ctx.stats.cmd.def.type & (1 <<
STATS_TYPE_SO)))
break;
- if (s->data_ctx.stats.sid != -1 && l->luid !=
s->data_ctx.stats.sid)
+ if (s->data_ctx.stats.cmd.def.sid != -1 &&
l->luid != s->data_ctx.stats.cmd.def.sid)
continue;
}
@@ -1995,25 +2270,25 @@ int stats_dump_proxy(struct session *s, struct proxy
*px, struct uri_auth *uri)
return 0;
}
- s->data_ctx.stats.sv = px->srv; /* may be NULL */
+ s->data_ctx.stats.cmd.def.sv = px->srv; /* may be NULL */
s->data_ctx.stats.px_st = DATA_ST_PX_SV;
/* fall through */
case DATA_ST_PX_SV:
- /* stats.sv has been initialized above */
- for (; s->data_ctx.stats.sv != NULL; s->data_ctx.stats.sv =
sv->next) {
+ /* stats.cmd.def.sv has been initialized above */
+ for (; s->data_ctx.stats.cmd.def.sv != NULL;
s->data_ctx.stats.cmd.def.sv = sv->next) {
int sv_state; /* 0=DOWN, 1=going up, 2=going down,
3=UP, 4,5=NOLB, 6=unchecked */
if (buffer_almost_full(rep))
return 0;
- sv = s->data_ctx.stats.sv;
+ sv = s->data_ctx.stats.cmd.def.sv;
if (s->data_ctx.stats.flags & STAT_BOUND) {
- if (!(s->data_ctx.stats.type & (1 <<
STATS_TYPE_SV)))
+ if (!(s->data_ctx.stats.cmd.def.type & (1 <<
STATS_TYPE_SV)))
break;
- if (s->data_ctx.stats.sid != -1 && sv->puid !=
s->data_ctx.stats.sid)
+ if (s->data_ctx.stats.cmd.def.sid != -1 &&
sv->puid != s->data_ctx.stats.cmd.def.sid)
continue;
}
@@ -2042,7 +2317,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px,
struct uri_auth *uri)
if (((sv_state == 0) || (sv->state & SRV_MAINTAIN)) &&
(s->data_ctx.stats.flags & STAT_HIDE_DOWN)) {
/* do not report servers which are DOWN */
- s->data_ctx.stats.sv = sv->next;
+ s->data_ctx.stats.cmd.def.sv = sv->next;
continue;
}
@@ -2400,7 +2675,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px,
struct uri_auth *uri)
case DATA_ST_PX_BE:
/* print the backend */
if ((px->cap & PR_CAP_BE) &&
- (!(s->data_ctx.stats.flags & STAT_BOUND) ||
(s->data_ctx.stats.type & (1 << STATS_TYPE_BE)))) {
+ (!(s->data_ctx.stats.flags & STAT_BOUND) ||
(s->data_ctx.stats.cmd.def.type & (1 << STATS_TYPE_BE)))) {
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg, "<tr class=\"backend\">");
if (px->cap & PR_CAP_BE && px->srv &&
(s->data_ctx.stats.flags & STAT_ADMIN)) {
--
1.7.1