mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
[STATS] add support for "show info" on the unix socket
It is sometimes required to know some informations such as the process uptime when consulting statistics. This patch adds the "show info" command to query those informations on the UNIX socket.
This commit is contained in:
parent
9f2b73064b
commit
a8efd362b2
@ -145,14 +145,16 @@ stats socket <path> [{uid | user} <uid>] [{gid | group} <gid>] [mode <mode>]
|
|||||||
Creates a UNIX socket in stream mode at location <path>. Any previously
|
Creates a UNIX socket in stream mode at location <path>. Any previously
|
||||||
existing socket will be backed up then replaced. Connections to this socket
|
existing socket will be backed up then replaced. Connections to this socket
|
||||||
will get a CSV-formated output of the process statistics in response to the
|
will get a CSV-formated output of the process statistics in response to the
|
||||||
"show stat" command followed by a line feed. On platforms which support it,
|
"show stat" command followed by a line feed, and more general process
|
||||||
it is possible to restrict access to this socket by specifying numerical IDs
|
information in response to the "show info" command followed by a line feed.
|
||||||
after "uid" and "gid", or valid user and group names after the "user" and
|
|
||||||
"group" keywords. It is also possible to restrict permissions on the socket
|
On platforms which support it, it is possible to restrict access to this
|
||||||
by passing an octal value after the "mode" keyword (same syntax as chmod).
|
socket by specifying numerical IDs after "uid" and "gid", or valid user and
|
||||||
Depending on the platform, the permissions on the socket will be inherited
|
group names after the "user" and "group" keywords. It is also possible to
|
||||||
from the directory which hosts it, or from the user the process is started
|
restrict permissions on the socket by passing an octal value after the "mode"
|
||||||
with.
|
keyword (same syntax as chmod). Depending on the platform, the permissions on
|
||||||
|
the socket will be inherited from the directory which hosts it, or from the
|
||||||
|
user the process is started with.
|
||||||
|
|
||||||
stats timeout <timeout, in milliseconds>
|
stats timeout <timeout, in milliseconds>
|
||||||
The default timeout on the stats socket is set to 10 seconds. It is possible
|
The default timeout on the stats socket is set to 10 seconds. It is possible
|
||||||
|
@ -27,7 +27,9 @@
|
|||||||
#include <types/buffers.h>
|
#include <types/buffers.h>
|
||||||
#include <types/session.h>
|
#include <types/session.h>
|
||||||
|
|
||||||
#define STAT_FMT_HTML 0x1
|
#define STAT_FMT_HTML 0x1
|
||||||
|
#define STAT_SHOW_STAT 0x2
|
||||||
|
#define STAT_SHOW_INFO 0x4
|
||||||
|
|
||||||
int stats_parse_global(const char **args, char *err, int errlen);
|
int stats_parse_global(const char **args, char *err, int errlen);
|
||||||
int stats_dump_raw(struct session *s, struct uri_auth *uri, int flags);
|
int stats_dump_raw(struct session *s, struct uri_auth *uri, int flags);
|
||||||
|
@ -187,6 +187,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri, int flags)
|
|||||||
struct buffer *rep = s->rep;
|
struct buffer *rep = s->rep;
|
||||||
struct proxy *px;
|
struct proxy *px;
|
||||||
struct chunk msg;
|
struct chunk msg;
|
||||||
|
unsigned int up;
|
||||||
|
|
||||||
msg.len = 0;
|
msg.len = 0;
|
||||||
msg.str = trash;
|
msg.str = trash;
|
||||||
@ -201,16 +202,50 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri, int flags)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DATA_ST_HEAD:
|
case DATA_ST_HEAD:
|
||||||
print_csv_header(&msg, sizeof(trash));
|
if (flags & STAT_SHOW_STAT) {
|
||||||
if (buffer_write_chunk(rep, &msg) != 0)
|
print_csv_header(&msg, sizeof(trash));
|
||||||
return 0;
|
if (buffer_write_chunk(rep, &msg) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s->data_state = DATA_ST_INFO;
|
s->data_state = DATA_ST_INFO;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DATA_ST_INFO:
|
case DATA_ST_INFO:
|
||||||
|
up = (now.tv_sec - start_date.tv_sec);
|
||||||
memset(&s->data_ctx, 0, sizeof(s->data_ctx));
|
memset(&s->data_ctx, 0, sizeof(s->data_ctx));
|
||||||
|
|
||||||
|
if (flags & STAT_SHOW_INFO) {
|
||||||
|
chunk_printf(&msg, sizeof(trash),
|
||||||
|
"Name: " PRODUCT_NAME "\n"
|
||||||
|
"Version: " HAPROXY_VERSION "\n"
|
||||||
|
"Release_date: " HAPROXY_DATE "\n"
|
||||||
|
"Nbproc: %d\n"
|
||||||
|
"Process_num: %d\n"
|
||||||
|
"Pid: %d\n"
|
||||||
|
"Uptime: %dd %dh%02dm%02ds\n"
|
||||||
|
"Uptime_sec: %d\n"
|
||||||
|
"Memmax_MB: %d\n"
|
||||||
|
"Ulimit-n: %d\n"
|
||||||
|
"Maxsock: %d\n"
|
||||||
|
"Maxconn: %d\n"
|
||||||
|
"CurrConns: %d\n"
|
||||||
|
"",
|
||||||
|
global.nbproc,
|
||||||
|
relative_pid,
|
||||||
|
pid,
|
||||||
|
up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60),
|
||||||
|
up,
|
||||||
|
global.rlimit_memmax,
|
||||||
|
global.rlimit_nofile,
|
||||||
|
global.maxsock,
|
||||||
|
global.maxconn,
|
||||||
|
actconn
|
||||||
|
);
|
||||||
|
if (buffer_write_chunk(rep, &msg) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s->data_ctx.stats.px = proxy;
|
s->data_ctx.stats.px = proxy;
|
||||||
s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
|
s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
|
||||||
s->data_state = DATA_ST_LIST;
|
s->data_state = DATA_ST_LIST;
|
||||||
@ -218,17 +253,20 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri, int flags)
|
|||||||
|
|
||||||
case DATA_ST_LIST:
|
case DATA_ST_LIST:
|
||||||
/* dump proxies */
|
/* dump proxies */
|
||||||
while (s->data_ctx.stats.px) {
|
if (flags & STAT_SHOW_STAT) {
|
||||||
px = s->data_ctx.stats.px;
|
while (s->data_ctx.stats.px) {
|
||||||
/* skip the disabled proxies and non-networked ones */
|
px = s->data_ctx.stats.px;
|
||||||
if (px->state != PR_STSTOPPED && (px->cap & (PR_CAP_FE | PR_CAP_BE)))
|
/* skip the disabled proxies and non-networked ones */
|
||||||
if (stats_dump_proxy(s, px, NULL, 0) == 0)
|
if (px->state != PR_STSTOPPED &&
|
||||||
return 0;
|
(px->cap & (PR_CAP_FE | PR_CAP_BE)))
|
||||||
|
if (stats_dump_proxy(s, px, NULL, 0) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
s->data_ctx.stats.px = px->next;
|
s->data_ctx.stats.px = px->next;
|
||||||
s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
|
s->data_ctx.stats.px_st = DATA_ST_PX_INIT;
|
||||||
|
}
|
||||||
|
/* here, we just have reached the last proxy */
|
||||||
}
|
}
|
||||||
/* here, we just have reached the last proxy */
|
|
||||||
|
|
||||||
s->data_state = DATA_ST_END;
|
s->data_state = DATA_ST_END;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -402,7 +440,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri, int flags)
|
|||||||
"<hr width=\"100%%\" class=\"hr\">\n"
|
"<hr width=\"100%%\" class=\"hr\">\n"
|
||||||
"<h3>> General process information</h3>\n"
|
"<h3>> General process information</h3>\n"
|
||||||
"<table border=0 cols=4><tr><td align=\"left\" nowrap width=\"1%%\">\n"
|
"<table border=0 cols=4><tr><td align=\"left\" nowrap width=\"1%%\">\n"
|
||||||
"<p><b>pid = </b> %d (nbproc = %d)<br>\n"
|
"<p><b>pid = </b> %d (process #%d, nbproc = %d)<br>\n"
|
||||||
"<b>uptime = </b> %dd %dh%02dm%02ds<br>\n"
|
"<b>uptime = </b> %dd %dh%02dm%02ds<br>\n"
|
||||||
"<b>system limits :</b> memmax = %s%s ; ulimit-n = %d<br>\n"
|
"<b>system limits :</b> memmax = %s%s ; ulimit-n = %d<br>\n"
|
||||||
"<b>maxsock = </b> %d<br>\n"
|
"<b>maxsock = </b> %d<br>\n"
|
||||||
@ -427,7 +465,8 @@ int stats_dump_http(struct session *s, struct uri_auth *uri, int flags)
|
|||||||
"<b>Display option:</b><ul style=\"margin-top: 0.25em;\">"
|
"<b>Display option:</b><ul style=\"margin-top: 0.25em;\">"
|
||||||
"",
|
"",
|
||||||
(uri->flags&ST_HIDEVER)?"":(STATS_VERSION_STRING),
|
(uri->flags&ST_HIDEVER)?"":(STATS_VERSION_STRING),
|
||||||
pid, pid, global.nbproc,
|
pid, pid,
|
||||||
|
relative_pid, global.nbproc,
|
||||||
up / 86400, (up % 86400) / 3600,
|
up / 86400, (up % 86400) / 3600,
|
||||||
(up % 3600) / 60, (up % 60),
|
(up % 3600) / 60, (up % 60),
|
||||||
global.rlimit_memmax ? ultoa(global.rlimit_memmax) : "unlimited",
|
global.rlimit_memmax ? ultoa(global.rlimit_memmax) : "unlimited",
|
||||||
|
@ -1386,7 +1386,15 @@ void process_uxst_stats(struct task *t, struct timeval *next)
|
|||||||
if (s->data_state == DATA_ST_INIT) {
|
if (s->data_state == DATA_ST_INIT) {
|
||||||
if ((s->req->l >= 10) && (memcmp(s->req->data, "show stat\n", 10) == 0)) {
|
if ((s->req->l >= 10) && (memcmp(s->req->data, "show stat\n", 10) == 0)) {
|
||||||
/* send the stats, and changes the data_state */
|
/* send the stats, and changes the data_state */
|
||||||
if (stats_dump_raw(s, NULL, 0) != 0) {
|
if (stats_dump_raw(s, NULL, STAT_SHOW_STAT) != 0) {
|
||||||
|
s->srv_state = SV_STCLOSE;
|
||||||
|
fsm_resync |= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((s->req->l >= 10) && (memcmp(s->req->data, "show info\n", 10) == 0)) {
|
||||||
|
/* send the stats, and changes the data_state */
|
||||||
|
if (stats_dump_raw(s, NULL, STAT_SHOW_INFO) != 0) {
|
||||||
s->srv_state = SV_STCLOSE;
|
s->srv_state = SV_STCLOSE;
|
||||||
fsm_resync |= 1;
|
fsm_resync |= 1;
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user