[MINOR] stats: add a new node-name setting
The new "node-name" stats setting enables reporting of a node ID on
the stats page. It is possible to return the system's host name as
well as a specific name.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 5aba62a..03f4e7a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -3756,6 +3756,38 @@
See also : "stats auth", "stats realm", "stats uri"
+stats node-name [ <name> ]
+ Enable reporting of a host name on the statistics page.
+ May be used in sections : defaults | frontend | listen | backend
+ yes | no | yes | yes
+ Arguments :
+ <name> is an optional name to be reported. If unspecified, the system's
+ hostname is automatically used instead.
+
+ The node-name is read as a single word, so any spaces in it should be escaped
+ using a backslash ('\'). If it is left unspecified, the system's hostname is
+ used instead.
+
+ This statement is useful in HA configurations where two or more processes or
+ servers share a same IP address. By setting a different node-name on all
+ nodes, it becomes easy to immediately spot what server is handling the
+ traffic.
+
+ 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.
+
+ Example :
+ # internal monitoring access (unlimited)
+ backend private_monitoring
+ stats enable
+ stats node-name master
+ stats uri /admin?stats
+ stats refresh 5s
+
+ See also : "stats enable", "stats uri"
+
+
stats realm <realm>
Enable statistics and set authentication realm
May be used in sections : defaults | frontend | listen | backend
diff --git a/include/common/uri_auth.h b/include/common/uri_auth.h
index e52387c..132be21 100644
--- a/include/common/uri_auth.h
+++ b/include/common/uri_auth.h
@@ -38,6 +38,7 @@
int uri_len; /* the prefix length */
char *uri_prefix; /* the prefix we want to match */
char *auth_realm; /* the realm reported to the client */
+ char *node_name; /* the node name reported to the client */
int refresh; /* refresh interval for the browser (in seconds) */
int flags; /* some flags describing the statistics page */
struct user_auth *users; /* linked list of valid user:passwd couples */
@@ -74,6 +75,7 @@
struct uri_auth *stats_set_flag(struct uri_auth **root, int flag);
struct uri_auth *stats_add_auth(struct uri_auth **root, char *user);
struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope);
+struct uri_auth *stats_set_node_name(struct uri_auth **root, char *name);
#endif /* _COMMON_URI_AUTH_H */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index bd720c6..8b3d3f1 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1725,7 +1725,7 @@
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'.\n", file, linenum, args[0]);
+ Alert("parsing [%s:%d] : '%s' expects 'uri', 'realm', 'node-name', 'auth', 'scope' or 'enable'.\n", file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
} else if (!strcmp(args[1], "uri")) {
@@ -1748,6 +1748,12 @@
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
+ } else if (!strcmp(args[1], "node-name")) {
+ if (!stats_set_node_name(&curproxy->uri_auth, *(args[2]) ? args[2] : hostname)) {
+ Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
} else if (!strcmp(args[1], "refresh")) {
unsigned interval;
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 8452d3b..d7c5110 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -371,7 +371,7 @@
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
/* WARNING! This must fit in the first buffer !!! */
chunk_printf(&msg, sizeof(trash),
- "<html><head><title>Statistics Report for " PRODUCT_NAME "</title>\n"
+ "<html><head><title>Statistics Report for " PRODUCT_NAME "%s%s</title>\n"
"<meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\">\n"
"<style type=\"text/css\"><!--\n"
"body {"
@@ -443,7 +443,10 @@
"table.lgd td { border-width: 1px; border-style: solid solid solid solid; border-color: gray; padding: 2px;}\n"
"table.lgd td.noborder { border-style: none; padding: 2px; white-space: nowrap;}\n"
"-->\n"
- "</style></head>\n");
+ "</style></head>\n",
+ uri->node_name ? " on " : "",
+ uri->node_name ? uri->node_name : ""
+ );
} else {
print_csv_header(&msg, sizeof(trash));
}
@@ -464,7 +467,7 @@
chunk_printf(&msg, sizeof(trash),
"<body><h1><a href=\"" PRODUCT_URL "\" style=\"text-decoration: none;\">"
PRODUCT_NAME "%s</a></h1>\n"
- "<h2>Statistics Report for pid %d</h2>\n"
+ "<h2>Statistics Report for pid %d%s%s</h2>\n"
"<hr width=\"100%%\" class=\"hr\">\n"
"<h3>> General process information</h3>\n"
"<table border=0 cols=4><tr><td align=\"left\" nowrap width=\"1%%\">\n"
@@ -494,7 +497,8 @@
"<b>Display option:</b><ul style=\"margin-top: 0.25em;\">"
"",
(uri->flags&ST_HIDEVER)?"":(STATS_VERSION_STRING),
- pid, pid,
+ pid, uri->node_name ? " on " : "", uri->node_name ? uri->node_name : "",
+ pid,
relative_pid, global.nbproc,
up / 86400, (up % 86400) / 3600,
(up % 3600) / 60, (up % 60),
diff --git a/src/uri_auth.c b/src/uri_auth.c
index 67e237a..ba029a6 100644
--- a/src/uri_auth.c
+++ b/src/uri_auth.c
@@ -110,6 +110,31 @@
}
/*
+ * Returns a default uri_auth with <node-name> set as the node name.
+ * Uses the pointer provided if not NULL and not initialized.
+ */
+struct uri_auth *stats_set_node_name(struct uri_auth **root, char *name)
+{
+ struct uri_auth *u;
+ char *name_copy;
+
+ if ((name_copy = strdup(name)) == NULL)
+ goto out_realm;
+
+ if ((u = stats_check_init_uri_auth(root)) == NULL)
+ goto out_u;
+
+ free(u->node_name);
+ u->node_name = name_copy;
+ return u;
+
+ out_u:
+ free(name_copy);
+ out_realm:
+ return NULL;
+}
+
+/*
* Returns a default uri_auth with the <refresh> refresh interval.
* Uses the pointer provided if not NULL and not initialized.
*/