mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-11 14:05:12 +00:00
[CLEANUP] stats: make all dump functions only rely on the stream interface
This will be needed to move the applet-specific data out of the session.
This commit is contained in:
parent
75581aebb0
commit
5ec29ffa42
@ -67,12 +67,12 @@ extern struct si_applet cli_applet;
|
||||
int stats_accept(struct session *s);
|
||||
int stats_sock_parse_request(struct stream_interface *si, char *line);
|
||||
void stats_io_handler(struct stream_interface *si);
|
||||
int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep);
|
||||
int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri);
|
||||
int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri);
|
||||
int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep);
|
||||
int stats_dump_table_to_buffer(struct session *s, struct buffer *rep);
|
||||
int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
|
||||
int stats_dump_raw_to_buffer(struct stream_interface *si);
|
||||
int stats_dump_http(struct stream_interface *si, struct uri_auth *uri);
|
||||
int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struct uri_auth *uri);
|
||||
int stats_dump_sess_to_buffer(struct stream_interface *si);
|
||||
int stats_dump_table_to_buffer(struct stream_interface *si);
|
||||
int stats_dump_errors_to_buffer(struct stream_interface *si);
|
||||
|
||||
|
||||
#endif /* _PROTO_DUMPSTATS_H */
|
||||
|
136
src/dumpstats.c
136
src/dumpstats.c
@ -953,19 +953,19 @@ static void cli_io_handler(struct stream_interface *si)
|
||||
si->applet.st0 = STAT_CLI_PROMPT;
|
||||
break;
|
||||
case STAT_CLI_O_INFO:
|
||||
if (stats_dump_raw_to_buffer(s, res))
|
||||
if (stats_dump_raw_to_buffer(si))
|
||||
si->applet.st0 = STAT_CLI_PROMPT;
|
||||
break;
|
||||
case STAT_CLI_O_SESS:
|
||||
if (stats_dump_sess_to_buffer(s, res))
|
||||
if (stats_dump_sess_to_buffer(si))
|
||||
si->applet.st0 = STAT_CLI_PROMPT;
|
||||
break;
|
||||
case STAT_CLI_O_ERR: /* errors dump */
|
||||
if (stats_dump_errors_to_buffer(s, res))
|
||||
if (stats_dump_errors_to_buffer(si))
|
||||
si->applet.st0 = STAT_CLI_PROMPT;
|
||||
break;
|
||||
case STAT_CLI_O_TAB:
|
||||
if (stats_dump_table_to_buffer(s, res))
|
||||
if (stats_dump_table_to_buffer(si))
|
||||
si->applet.st0 = STAT_CLI_PROMPT;
|
||||
break;
|
||||
default: /* abnormal state */
|
||||
@ -1038,15 +1038,15 @@ static void cli_io_handler(struct stream_interface *si)
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called to send output to the response buffer.
|
||||
* It dumps statistics onto the output buffer <rep> owned by session <s>.
|
||||
* s->data_ctx must have been zeroed first, and the flags properly set.
|
||||
/* This function dumps statistics onto the stream interface's read buffer.
|
||||
* The data_ctx must have been zeroed first, and the flags properly set.
|
||||
* It returns 0 as long as it does not complete, non-zero upon completion.
|
||||
* Some states are not used but it makes the code more similar to other
|
||||
* functions which handle stats too.
|
||||
*/
|
||||
int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep)
|
||||
int stats_dump_raw_to_buffer(struct stream_interface *si)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct proxy *px;
|
||||
struct chunk msg;
|
||||
unsigned int up;
|
||||
@ -1062,7 +1062,7 @@ int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep)
|
||||
case DATA_ST_HEAD:
|
||||
if (s->data_ctx.stats.flags & STAT_SHOW_STAT) {
|
||||
print_csv_header(&msg);
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1106,7 +1106,7 @@ int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep)
|
||||
nb_tasks_cur, run_queue_cur,
|
||||
global.node, global.desc?global.desc:""
|
||||
);
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1127,7 +1127,7 @@ int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep)
|
||||
/* skip the disabled proxies and non-networked ones */
|
||||
if (px->state != PR_STSTOPPED &&
|
||||
(px->cap & (PR_CAP_FE | PR_CAP_BE))) {
|
||||
if (stats_dump_proxy(s, px, NULL) == 0)
|
||||
if (stats_dump_proxy(si, px, NULL) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1159,8 +1159,9 @@ int stats_dump_raw_to_buffer(struct session *s, struct buffer *rep)
|
||||
* repost the data. We don't want this to happen on accident so we redirect
|
||||
* the browse to the stats page with a GET.
|
||||
*/
|
||||
int stats_http_redir(struct session *s, struct buffer *rep, struct uri_auth *uri)
|
||||
int stats_http_redir(struct stream_interface *si, struct uri_auth *uri)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct chunk msg;
|
||||
|
||||
chunk_init(&msg, trash, sizeof(trash));
|
||||
@ -1176,7 +1177,7 @@ int stats_http_redir(struct session *s, struct buffer *rep, struct uri_auth *uri
|
||||
uri->uri_prefix, s->data_ctx.stats.st_code);
|
||||
chunk_printf(&msg, "\r\n\r\n");
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
|
||||
s->txn.status = 303;
|
||||
@ -1213,12 +1214,12 @@ static void http_stats_io_handler(struct stream_interface *si)
|
||||
|
||||
if (!si->applet.st0) {
|
||||
if (s->txn.meth == HTTP_METH_POST) {
|
||||
if (stats_http_redir(s, res, s->be->uri_auth)) {
|
||||
if (stats_http_redir(si, s->be->uri_auth)) {
|
||||
si->applet.st0 = 1;
|
||||
si->shutw(si);
|
||||
}
|
||||
} else {
|
||||
if (stats_dump_http(s, res, s->be->uri_auth)) {
|
||||
if (stats_dump_http(si, s->be->uri_auth)) {
|
||||
si->applet.st0 = 1;
|
||||
si->shutw(si);
|
||||
}
|
||||
@ -1248,18 +1249,16 @@ static void http_stats_io_handler(struct stream_interface *si)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Produces statistics data for the session <s>. Expects to be called with
|
||||
* client socket shut down on input. It stops by itself by unsetting the
|
||||
* BF_HIJACK flag from the buffer, which it uses to keep on being called
|
||||
* when there is free space in the buffer, of simply by letting an empty buffer
|
||||
* upon return.s->data_ctx must have been zeroed before the first call, and the
|
||||
* flags set. It returns 0 if it had to stop writing data and an I/O is needed,
|
||||
* 1 if the dump is finished and the session must be closed, or -1 in case of
|
||||
* any error.
|
||||
/* This function dumps statistics in HTTP format onto the stream interface's
|
||||
* read buffer. The data_ctx must have been zeroed first, and the flags
|
||||
* properly set. It returns 0 if it had to stop writing data and an I/O is
|
||||
* needed, 1 if the dump is finished and the session must be closed, or -1
|
||||
* in case of any error.
|
||||
*/
|
||||
int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri)
|
||||
int stats_dump_http(struct stream_interface *si, struct uri_auth *uri)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct buffer *rep = si->ib;
|
||||
struct proxy *px;
|
||||
struct chunk msg;
|
||||
unsigned int up;
|
||||
@ -1568,7 +1567,7 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri)
|
||||
px = s->data_ctx.stats.px;
|
||||
/* skip the disabled proxies and non-networked ones */
|
||||
if (px->state != PR_STSTOPPED && (px->cap & (PR_CAP_FE | PR_CAP_BE)))
|
||||
if (stats_dump_proxy(s, px, uri) == 0)
|
||||
if (stats_dump_proxy(si, px, uri) == 0)
|
||||
return 0;
|
||||
|
||||
s->data_ctx.stats.px = px->next;
|
||||
@ -1605,9 +1604,10 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri)
|
||||
* Returns 0 if it had to stop dumping data because of lack of buffer space,
|
||||
* ot non-zero if everything completed.
|
||||
*/
|
||||
int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
int stats_dump_proxy(struct stream_interface *si, struct proxy *px, struct uri_auth *uri)
|
||||
{
|
||||
struct buffer *rep = s->rep;
|
||||
struct session *s = si->applet.private;
|
||||
struct buffer *rep = si->ib;
|
||||
struct server *sv, *svs; /* server and server-state, server-state=server or server->tracked */
|
||||
struct listener *l;
|
||||
struct chunk msg;
|
||||
@ -2647,16 +2647,15 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called to send output to the response buffer. It dumps a
|
||||
* complete session state onto the output buffer <rep>. The session has to be
|
||||
* set in data_ctx.sess.target. It returns 0 if the output buffer is full and
|
||||
* it needs to be called again, otherwise non-zero. It is designed to be called
|
||||
* from stats_dump_sess_to_buffer() below.
|
||||
/* This function dumps a complete session state onto the stream intreface's
|
||||
* read buffer. The data_ctx must have been zeroed first, and the flags
|
||||
* properly set. The session has to be set in data_ctx.sess.target. It returns
|
||||
* 0 if the output buffer is full and it needs to be called again, otherwise
|
||||
* non-zero. It is designed to be called from stats_dump_sess_to_buffer() below.
|
||||
*/
|
||||
|
||||
/* returns 1 if dump is not complete */
|
||||
int stats_dump_full_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
int stats_dump_full_sess_to_buffer(struct stream_interface *si)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct tm tm;
|
||||
struct chunk msg;
|
||||
struct session *sess;
|
||||
@ -2669,7 +2668,7 @@ int stats_dump_full_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
if (s->data_ctx.sess.section > 0 && s->data_ctx.sess.uid != sess->uniq_id) {
|
||||
/* session changed, no need to go any further */
|
||||
chunk_printf(&msg, " *** session terminated while we were watching it ***\n");
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
s->data_ctx.sess.target = NULL;
|
||||
s->data_ctx.sess.uid = 0;
|
||||
@ -2844,7 +2843,7 @@ int stats_dump_full_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
(int)(sess->rep->lr - sess->rep->data),
|
||||
sess->rep->total);
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
|
||||
/* use other states to dump the contents */
|
||||
@ -2854,17 +2853,18 @@ int stats_dump_full_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function is called to send output to the response buffer.
|
||||
* It dumps the sessions states onto the output buffer <rep>.
|
||||
* Expects to be called with client socket shut down on input.
|
||||
* s->data_ctx must have been zeroed first, and the flags properly set.
|
||||
* It returns 0 as long as it does not complete, non-zero upon completion.
|
||||
/* This function dumps all sessions' states onto the stream intreface's
|
||||
* read buffer. The data_ctx must have been zeroed first, and the flags
|
||||
* properly set. It returns 0 if the output buffer is full and it needs
|
||||
* to be called again, otherwise non-zero. It is designed to be called
|
||||
* from stats_dump_sess_to_buffer() below.
|
||||
*/
|
||||
int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
int stats_dump_sess_to_buffer(struct stream_interface *si)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct chunk msg;
|
||||
|
||||
if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
|
||||
if (unlikely(si->ib->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
|
||||
/* If we're forced to shut down, we might have to remove our
|
||||
* reference to the last session being dumped.
|
||||
*/
|
||||
@ -2913,7 +2913,7 @@ int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
|
||||
LIST_ADDQ(&curr_sess->back_refs, &s->data_ctx.sess.bref.users);
|
||||
/* call the proper dump() function and return if we're missing space */
|
||||
if (!stats_dump_full_sess_to_buffer(s, rep))
|
||||
if (!stats_dump_full_sess_to_buffer(si))
|
||||
return 0;
|
||||
|
||||
/* session dump complete */
|
||||
@ -3045,7 +3045,7 @@ int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
|
||||
chunk_printf(&msg, "\n");
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0) {
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0) {
|
||||
/* let's try again later from this session. We add ourselves into
|
||||
* this session's users so that it can remove us upon termination.
|
||||
*/
|
||||
@ -3064,7 +3064,7 @@ int stats_dump_sess_to_buffer(struct session *s, struct buffer *rep)
|
||||
else
|
||||
chunk_printf(&msg, "Session not found.\n");
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
|
||||
s->data_ctx.sess.target = NULL;
|
||||
@ -3150,14 +3150,14 @@ static int dump_binary(struct chunk *out, const char *buf, int bsize)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* This function is called to send output to the response buffer.
|
||||
* It dumps the tables states onto the output buffer <rep>.
|
||||
* Expects to be called with client socket shut down on input.
|
||||
* s->data_ctx must have been zeroed first, and the flags properly set.
|
||||
* It returns 0 as long as it does not complete, non-zero upon completion.
|
||||
/* This function dumps all tables' states onto the stream intreface's
|
||||
* read buffer. The data_ctx must have been zeroed first, and the flags
|
||||
* properly set. It returns 0 if the output buffer is full and it needs
|
||||
* to be called again, otherwise non-zero.
|
||||
*/
|
||||
int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
|
||||
int stats_dump_table_to_buffer(struct stream_interface *si)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
struct chunk msg;
|
||||
struct ebmb_node *eb;
|
||||
int dt;
|
||||
@ -3174,7 +3174,7 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
|
||||
* data though.
|
||||
*/
|
||||
|
||||
if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
|
||||
if (unlikely(si->ib->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
|
||||
/* in case of abort, remove any refcount we might have set on an entry */
|
||||
if (s->data_state == DATA_ST_LIST) {
|
||||
s->data_ctx.table.entry->ref_cnt--;
|
||||
@ -3217,7 +3217,7 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
|
||||
s->listener->perm.ux.level < ACCESS_LVL_OPER)
|
||||
chunk_printf(&msg, "# contents not dumped due to insufficient privileges\n");
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
|
||||
if (s->data_ctx.table.target &&
|
||||
@ -3338,7 +3338,7 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
|
||||
}
|
||||
chunk_printf(&msg, "\n");
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
|
||||
skip_entry:
|
||||
@ -3424,18 +3424,18 @@ static int dump_text_line(struct chunk *out, const char *buf, int bsize, int len
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* This function is called to send output to the response buffer.
|
||||
* It dumps the errors logged in proxies onto the output buffer <rep>.
|
||||
* Expects to be called with client socket shut down on input.
|
||||
* s->data_ctx must have been zeroed first, and the flags properly set.
|
||||
* It returns 0 as long as it does not complete, non-zero upon completion.
|
||||
/* This function dumps all captured errors onto the stream intreface's
|
||||
* read buffer. The data_ctx must have been zeroed first, and the flags
|
||||
* properly set. It returns 0 if the output buffer is full and it needs
|
||||
* to be called again, otherwise non-zero.
|
||||
*/
|
||||
int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
|
||||
int stats_dump_errors_to_buffer(struct stream_interface *si)
|
||||
{
|
||||
struct session *s = si->applet.private;
|
||||
extern const char *monthname[12];
|
||||
struct chunk msg;
|
||||
|
||||
if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW)))
|
||||
if (unlikely(si->ib->flags & (BF_WRITE_ERROR|BF_SHUTW)))
|
||||
return 1;
|
||||
|
||||
chunk_init(&msg, trash, sizeof(trash));
|
||||
@ -3452,7 +3452,7 @@ int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(date.tv_usec/1000),
|
||||
error_snapshot_id);
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0) {
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0) {
|
||||
/* Socket buffer full. Let's try again later from the same point */
|
||||
return 0;
|
||||
}
|
||||
@ -3533,7 +3533,7 @@ int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0) {
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0) {
|
||||
/* Socket buffer full. Let's try again later from the same point */
|
||||
return 0;
|
||||
}
|
||||
@ -3545,7 +3545,7 @@ int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
|
||||
/* the snapshot changed while we were dumping it */
|
||||
chunk_printf(&msg,
|
||||
" WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0)
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0)
|
||||
return 0;
|
||||
goto next;
|
||||
}
|
||||
@ -3560,7 +3560,7 @@ int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
|
||||
if (newptr == s->data_ctx.errors.ptr)
|
||||
return 0;
|
||||
|
||||
if (buffer_feed_chunk(rep, &msg) >= 0) {
|
||||
if (buffer_feed_chunk(si->ib, &msg) >= 0) {
|
||||
/* Socket buffer full. Let's try again later from the same point */
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user