[MINOR]: stats: add show-legends to report additional informations

Supported informations, available via "tr/td title":
  - cap: capabilities (proxy)
  - mode: one of tcp, http or health (proxy)
  - id: SNMP ID (proxy, socket, server)
  - IP (socket, server)
  - cookie (backend, server)
This commit is contained in:
Krzysztof Piotr Oledzki 2010-01-04 16:03:09 +01:00 committed by Willy Tarreau
parent 2ec025d9a5
commit 15514c21a2
6 changed files with 155 additions and 10 deletions

View File

@ -4084,6 +4084,19 @@ stats show-desc [ <description> ]
See also: "show-node", "stats enable", "stats uri" and "description" in global section.
stats show-legends
Enable reporting additional informations on the statistics page :
- cap: capabilities (proxy)
- mode: one of tcp, http or health (proxy)
- id: SNMP ID (proxy, socket, server)
- IP (socket, server)
- cookie (backend, server)
Though this statement alone is enough to enable statistics reporting, it is
recommended to set all other settings in order to avoid relying on default
unobvious parameters.
See also: "stats enable", "stats uri".
stats realm <realm>
Enable statistics and set authentication realm

View File

@ -34,6 +34,7 @@ struct stat_scope {
#define ST_HIDEVER 0x00000001 /* do not report the version and reldate */
#define ST_SHNODE 0x00000002 /* show node name */
#define ST_SHDESC 0x00000004 /* show description */
#define ST_SHLGNDS 0x0000008 /* show legends */
/* later we may link them to support multiple URI matching */
struct uri_auth {

View File

@ -34,6 +34,7 @@ int assign_server_address(struct session *s);
int assign_server_and_queue(struct session *s);
int connect_server(struct session *s);
int srv_redispatch_connect(struct session *t);
const char *backend_lb_algo_str(int algo);
int backend_parse_balance(const char **args, char *err,
int errlen, struct proxy *curproxy);

View File

@ -950,6 +950,33 @@ int be_downtime(struct proxy *px) {
return now.tv_sec - px->last_change + px->down_time;
}
/*
* This function returns a string containing the balancing
* mode of the proxy in a format suitable for stats.
*/
const char *backend_lb_algo_str(int algo) {
if (algo == BE_LB_ALGO_RR)
return "roundrobin";
else if (algo == BE_LB_ALGO_SRR)
return "static-rr";
else if (algo == BE_LB_ALGO_LC)
return "leastconn";
else if (algo == BE_LB_ALGO_SH)
return "source";
else if (algo == BE_LB_ALGO_UH)
return "uri";
else if (algo == BE_LB_ALGO_PH)
return "url_param";
else if (algo == BE_LB_ALGO_HH)
return "hdr";
else if (algo == BE_LB_ALGO_RCH)
return "rdp-cookie";
else
return NULL;
}
/* This function parses a "balance" statement in a backend section describing
* <curproxy>. It returns -1 if there is any error, otherwise zero. If it
* returns -1, it may write an error message into ther <err> buffer, for at

View File

@ -1963,7 +1963,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
curproxy->uri_auth = NULL; /* we must detach from the default config */
if (*(args[1]) == 0) {
Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable', 'hide-version', 'show-node', 'show-desc'.\n", file, linenum, args[0]);
Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'auth', 'scope' or 'enable', 'hide-version', 'show-node', 'show-desc', 'show-legends'.\n", file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
} else if (!strcmp(args[1], "uri")) {
@ -2032,6 +2032,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
} else if (!strcmp(args[1], "show-legends")) {
if (!stats_set_flag(&curproxy->uri_auth, ST_SHLGNDS)) {
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
} else if (!strcmp(args[1], "show-node")) {
if (*args[2]) {

View File

@ -1231,8 +1231,30 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
chunk_printf(&msg,
"<table class=\"tbl\" width=\"100%%\">\n"
"<tr class=\"titre\">"
"<th class=\"pxname\" width=\"10%%\">"
"<a name=\"%s\"></a>"
"<th class=\"pxname\" width=\"10%%\"");
if (uri->flags&ST_SHLGNDS) {
/* cap, mode, id */
chunk_printf(&msg, " title=\"cap: %s, mode: %s, id: %d",
proxy_cap_str(px->cap), proxy_mode_str(px->mode),
px->uuid);
/* cookie */
if (px->cookie_name) {
struct chunk src;
chunk_printf(&msg, ", cookie: '");
chunk_initlen(&src, px->cookie_name, 0, strlen(px->cookie_name));
chunk_htmlencode(&msg, &src);
chunk_printf(&msg, "'");
}
chunk_printf(&msg, "\"");
}
chunk_printf(&msg,
"><a name=\"%s\"></a>"
"<a class=px href=\"#%s\">%s</a></th>"
"<th class=\"%s\" width=\"90%%\">%s</th>"
"</tr>\n"
@ -1404,9 +1426,44 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
}
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg, "<tr class=socket><td class=ac");
if (uri->flags&ST_SHLGNDS) {
char str[INET6_ADDRSTRLEN], *fmt = NULL;
int port;
chunk_printf(&msg, " title=\"IP: ");
port = (l->addr.ss_family == AF_INET6)
? ntohs(((struct sockaddr_in6 *)(&l->addr))->sin6_port)
: ntohs(((struct sockaddr_in *)(&l->addr))->sin_port);
if (l->addr.ss_family == AF_INET) {
if (inet_ntop(AF_INET,
(const void *)&((struct sockaddr_in *)&l->addr)->sin_addr,
str, sizeof(str)))
fmt = "%s:%d";
} else {
if (inet_ntop(AF_INET6,
(const void *)&((struct sockaddr_in6 *)(&l->addr))->sin6_addr,
str, sizeof(str)))
fmt = "[%s]:%d";
}
if (fmt)
chunk_printf(&msg, fmt, str, port);
else
chunk_printf(&msg, "(%s)", strerror(errno));
/* id */
chunk_printf(&msg, ", id: %d", l->luid);
chunk_printf(&msg, "\"");
}
chunk_printf(&msg,
/* name, queue */
"<tr class=socket><td class=ac><a name=\"%s/+%s\"></a>"
"><a name=\"%s/+%s\"></a>"
"<a class=lfsb href=\"#%s/+%s\">%s</a></td><td colspan=3></td>"
/* sessions rate: current, max, limit */
"<td colspan=3>&nbsp;</td>"
@ -1536,8 +1593,40 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
"<i>no check</i>" };
chunk_printf(&msg,
/* name */
"<tr class=\"%s%d\"><td class=ac>"
"<a name=\"%s/%s\"></a>"
"<tr class=\"%s%d\"><td class=ac",
(sv->state & SRV_BACKUP) ? "backup" : "active", sv_state);
if (uri->flags&ST_SHLGNDS) {
char str[INET6_ADDRSTRLEN];
chunk_printf(&msg, " title=\"IP: ");
/* IP */
if (inet_ntop(sv->addr.sin_family, &sv->addr.sin_addr, str, sizeof(str)))
chunk_printf(&msg, "%s:%d", str, htons(sv->addr.sin_port));
else
chunk_printf(&msg, "(%s)", strerror(errno));
/* id */
chunk_printf(&msg, ", id: %d", sv->puid);
/* cookie */
if (sv->cookie) {
struct chunk src;
chunk_printf(&msg, ", cookie: '");
chunk_initlen(&src, sv->cookie, 0, strlen(sv->cookie));
chunk_htmlencode(&msg, &src);
chunk_printf(&msg, "'");
}
chunk_printf(&msg, "\"");
}
chunk_printf(&msg,
"><a name=\"%s/%s\"></a>"
"<a class=lfsb href=\"#%s/%s\">%s</a></td>"
/* queue : current, max, limit */
"<td>%s</td><td>%s</td><td>%s</td>"
@ -1547,8 +1636,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
"<td>%s</td><td>%s</td><td>%s</td>"
"<td"
"",
(sv->state & SRV_BACKUP) ? "backup" : "active",
sv_state, px->id, sv->id, px->id, sv->id, sv->id,
px->id, sv->id, px->id, sv->id, sv->id,
U2H0(sv->nbpend), U2H1(sv->counters.nbpend_max), LIM2A2(sv->maxqueue, "-"),
U2H3(read_freq_ctr(&sv->sess_per_sec)), U2H4(sv->counters.sps_max),
U2H5(sv->cur_sess), U2H6(sv->counters.cur_sess_max), LIM2A7(sv->maxconn, "-"));
@ -1803,8 +1891,17 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg,
/* name */
"<tr class=\"backend\"><td class=ac>"
"<a name=\"%s/Backend\"></a>"
"<tr class=\"backend\"><td class=ac");
if (uri->flags&ST_SHLGNDS) {
/* balancing */
chunk_printf(&msg, " title=\"balancing: %s\"",
backend_lb_algo_str(px->lbprm.algo & BE_LB_ALGO));
}
chunk_printf(&msg,
"><a name=\"%s/Backend\"></a>"
"<a class=lfsb href=\"#%s/Backend\">Backend</a></td>"
/* queue : current, max */
"<td>%s</td><td>%s</td><td></td>"