diff --git a/doc/configuration.txt b/doc/configuration.txt index 5aba62ac2..03f4e7ab7 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -3756,6 +3756,38 @@ stats enable See also : "stats auth", "stats realm", "stats uri" +stats node-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 : + 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 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 e52387c1d..132be218d 100644 --- a/include/common/uri_auth.h +++ b/include/common/uri_auth.h @@ -38,6 +38,7 @@ struct uri_auth { 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_refresh(struct uri_auth **root, int interval); 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 bd720c624..8b3d3f183 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1725,7 +1725,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'.\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 @@ 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], "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 8452d3b7e..d7c5110df 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -371,7 +371,7 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri) if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) { /* WARNING! This must fit in the first buffer !!! */ chunk_printf(&msg, sizeof(trash), - "Statistics Report for " PRODUCT_NAME "\n" + "Statistics Report for " PRODUCT_NAME "%s%s\n" "\n" "\n"); + "\n", + uri->node_name ? " on " : "", + uri->node_name ? uri->node_name : "" + ); } else { print_csv_header(&msg, sizeof(trash)); } @@ -464,7 +467,7 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri) chunk_printf(&msg, sizeof(trash), "

" PRODUCT_NAME "%s

\n" - "

Statistics Report for pid %d

\n" + "

Statistics Report for pid %d%s%s

\n" "
\n" "

> General process information

\n" "
\n" @@ -494,7 +497,8 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri) "Display option:
    " "", (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 67e237a65..ba029a6ba 100644 --- a/src/uri_auth.c +++ b/src/uri_auth.c @@ -109,6 +109,31 @@ struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm) return NULL; } +/* + * Returns a default uri_auth with 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 interval. * Uses the pointer provided if not NULL and not initialized.