]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR]: stats: add show-legends to report additional informations
authorKrzysztof Piotr Oledzki <ole@ans.pl>
Mon, 4 Jan 2010 15:03:09 +0000 (16:03 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 5 Jan 2010 23:28:06 +0000 (00:28 +0100)
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)

doc/configuration.txt
include/common/uri_auth.h
include/proto/backend.h
src/backend.c
src/cfgparse.c
src/dumpstats.c

index 46787e59dba500d4d3bca039a5cdd3b1d7826567..8652505ed52ae99fe71e8d30597ac32ec64a0fbb 100644 (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
index 3a7fd9c74117321986c93cafba67ebbdfb5ffdb1..64f818b89e22b2cfbd9e017905809d4aa7f44133 100644 (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 {
index 7a248da1fccc88c973c5710c45fdfbea7efe1d73..a6f1c9f4d78c6d6e7e8164b99c5f61eef1066416 100644 (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);
 
index fedac396fa06e12538d9ecefda3b3de9cae5f5e3..34783f51e6899d9670980ee278ba06514daf1879 100644 (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
index 10013fe46bb36e02af0c3b8a9f9656e01b6a7d3a..20fb65721f0d302f10886cceaa054f9bd3287fe1 100644 (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]) {
index 576566de5063c3df7c4a946be5cdbfe937c1c1c8..e51a314bc0c5a1718e8ea1da7db9bbcc662de813 100644 (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>"