Hello, Following up on the comments from the previous patch
"me realize that we could possibly do exactly the same with them : having per-listener and per-frontend last accept could be useful to detect the ones which are never used in some environment" I have added additional fields to the stats. I looked into the comments on using the stats listener but found it easier to implement last activity using bytes transferred time Summary: Added fields for last activity/session to stats page. Last session for front end tracks the last accept time where as for backends tracks the last lb connection time. Last activity on all (be/fe/listener) tracks the time of last byte. Thanks Bhaskar
From 331c995f64afac6d7b722e8658b2a15bb5cc91b8 Mon Sep 17 00:00:00 2001 From: Bhaskar Maddala <[email protected]> Date: Sun, 9 Feb 2014 03:13:22 -0500 Subject: [PATCH] Add last activity/session enhancements to stats page Summary: Added fields for last activity/session to stats page. Last session for front end tracks the last accept time where as for backends tracks the last lb connection time. Last activity on all (be/fe/listener) tracks the time of last bytes. --- include/proto/backend.h | 1 + include/proto/frontend.h | 2 ++ include/proto/listener.h | 6 +++++ include/proto/proxy.h | 8 ++++++ include/proto/server.h | 1 + include/types/counters.h | 9 +++++-- src/backend.c | 10 ++++++++ src/dumpstats.c | 63 ++++++++++++++++++++++++++-------------------- src/frontend.c | 19 ++++++++++++++ src/listener.c | 18 +++++++++++++ src/server.c | 9 +++++++ src/session.c | 21 +++++++++++++--- 12 files changed, 134 insertions(+), 33 deletions(-) diff --git a/include/proto/backend.h b/include/proto/backend.h index 68ba3d6..cc7338b 100644 --- a/include/proto/backend.h +++ b/include/proto/backend.h @@ -45,6 +45,7 @@ void update_backend_weight(struct proxy *px); struct server *get_server_sh(struct proxy *px, const char *addr, int len); struct server *get_server_uh(struct proxy *px, char *uri, int uri_len); int be_lastsession(const struct proxy *be); +int be_lastactv(const struct proxy *be); /* set the time of last session on the backend */ static void inline be_set_sess_last(struct proxy *be) diff --git a/include/proto/frontend.h b/include/proto/frontend.h index 77d3206..c44ec47 100644 --- a/include/proto/frontend.h +++ b/include/proto/frontend.h @@ -25,6 +25,8 @@ #include <common/config.h> #include <types/session.h> +int fe_lastactv(const struct proxy *fe); +int fe_lastsession(const struct proxy *fe); int frontend_accept(struct session *s); diff --git a/include/proto/listener.h b/include/proto/listener.h index 1473bfd..a8bbfff 100644 --- a/include/proto/listener.h +++ b/include/proto/listener.h @@ -26,6 +26,12 @@ #include <types/listener.h> +/* time since last activity/byte */ +int li_lastactv(const struct listener *li); + +/* time since last accepted connection */ +int li_lastsession(const struct listener *li); + /* This function adds the specified listener's file descriptor to the polling * lists if it is in the LI_LISTEN state. The listener enters LI_READY or * LI_FULL state depending on its number of connections. diff --git a/include/proto/proxy.h b/include/proto/proxy.h index 4a4b285..5eb5f0f 100644 --- a/include/proto/proxy.h +++ b/include/proto/proxy.h @@ -85,6 +85,14 @@ static void inline proxy_inc_fe_conn_ctr(struct listener *l, struct proxy *fe) fe->fe_counters.cps_max = fe->fe_conn_per_sec.curr_ctr; } +/* set the last accept time on the designated frontend */ +static void inline proxy_set_fe_conn_last(struct listener *l, struct proxy *fe) +{ + fe->fe_counters.last_sess = now.tv_sec; + if (l->counters) + l->counters->last_sess = now.tv_sec; +} + /* increase the number of cumulated connections accepted by the designated frontend */ static void inline proxy_inc_fe_sess_ctr(struct listener *l, struct proxy *fe) { diff --git a/include/proto/server.h b/include/proto/server.h index 750d8d5..d7ae9d4 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -35,6 +35,7 @@ #include <proto/freq_ctr.h> int srv_downtime(const struct server *s); +int srv_lastactv(const struct server *s); int srv_lastsession(const struct server *s); int srv_getinter(const struct check *check); diff --git a/include/types/counters.h b/include/types/counters.h index ecdc7cb..6a517c2 100644 --- a/include/types/counters.h +++ b/include/types/counters.h @@ -23,13 +23,14 @@ #ifndef _TYPES_COUNTERS_H #define _TYPES_COUNTERS_H -/* maybe later we might thing about having a different struct for FE and BE */ +/* maybe later we might think about having a different struct for FE and BE */ struct pxcounters { unsigned int conn_max; /* max # of active sessions */ long long cum_conn; /* cumulated number of received connections */ long long cum_sess; /* cumulated number of accepted connections */ long long cum_lbconn; /* cumulated number of sessions processed by load balancing (BE only) */ - unsigned long last_sess; /* last session time */ + unsigned long last_sess; /* last session time (on BE tracks the last LB connection) */ + /* (on FE tracks the last accepted connection) */ unsigned int cps_max; /* maximum of new connections received per second */ unsigned int sps_max; /* maximum of new connections accepted per second (sessions) */ @@ -37,6 +38,7 @@ struct pxcounters { long long bytes_in; /* number of bytes transferred from the client to the server */ long long bytes_out; /* number of bytes transferred from the server to the client */ + unsigned long last_actv; /* last activity - tracked as last time of bytes transferred */ long long comp_in; /* input bytes fed to the compressor */ long long comp_out; /* output bytes emitted by the compressor */ @@ -70,9 +72,11 @@ struct licounters { long long cum_conn; /* cumulated number of received connections */ long long cum_sess; /* cumulated number of accepted sessions */ + unsigned long last_sess; /* last accepted connection time on the listener */ long long bytes_in; /* number of bytes transferred from the client to the server */ long long bytes_out; /* number of bytes transferred from the server to the client */ + unsigned long last_actv; /* last activity - tracked as last time of bytes transferred */ long long denied_req, denied_resp; /* blocked requests/responses because of security concerns */ long long failed_req; /* failed requests (eg: invalid or timeout) */ @@ -90,6 +94,7 @@ struct srvcounters { long long bytes_in; /* number of bytes transferred from the client to the server */ long long bytes_out; /* number of bytes transferred from the server to the client */ + unsigned long last_actv; /* last activity - tracked as last time of bytes transferred */ long long failed_conns, failed_resp; /* failed connect() and responses */ long long cli_aborts, srv_aborts; /* aborted responses during DATA phase due to client or server */ diff --git a/src/backend.c b/src/backend.c index e561919..45e78f2 100644 --- a/src/backend.c +++ b/src/backend.c @@ -52,6 +52,16 @@ #include <proto/stream_interface.h> #include <proto/task.h> +/* time since last activity/byte */ +int be_lastactv(const struct proxy *be) +{ + if (be->be_counters.last_actv) + return now.tv_sec - be->be_counters.last_actv; + + return -1; +} + +/* time since last lb connection */ int be_lastsession(const struct proxy *be) { if (be->be_counters.last_sess) diff --git a/src/dumpstats.c b/src/dumpstats.c index 0b7dc08..c701c97 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -39,6 +39,7 @@ #include <types/global.h> #include <proto/backend.h> +#include <proto/frontend.h> #include <proto/channel.h> #include <proto/checks.h> #include <proto/compression.h> @@ -434,7 +435,7 @@ static void stats_dump_csv_header() "# pxname,svname," "qcur,qmax," "scur,smax,slim,stot,lastsess," - "bin,bout," + "bin,bout,lastactv," "dreq,dresp," "ereq,econ,eresp," "wretr,wredis," @@ -2468,10 +2469,11 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) chunk_appendf(&trash, "</table></div></u></td>" /* sessions: lbtot, lastsess */ - "<td></td><td></td>" + "<td></td><td>%s</td>" /* bytes : in */ "<td>%s</td>" "", + human_time(fe_lastsession(px), 1), U2H(px->fe_counters.bytes_in)); chunk_appendf(&trash, @@ -2485,6 +2487,8 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) (px->fe_counters.comp_in || px->fe_counters.comp_byp) ? "</u>":""); chunk_appendf(&trash, + /* last byte */ + "<td>%s</td>" /* denied: req, resp */ "<td>%s</td><td>%s</td>" /* errors : request, connect, response */ @@ -2496,6 +2500,7 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) /* rest of server: nothing */ "<td class=ac colspan=8></td></tr>" "", + human_time(fe_lastactv(px), 1), U2H(px->fe_counters.denied_req), U2H(px->fe_counters.denied_resp), U2H(px->fe_counters.failed_req), px->state == PR_STREADY ? "OPEN" : @@ -2506,9 +2511,9 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) /* pxid, name, queue cur, queue max, */ "%s,FRONTEND,,," /* sessions : current, max, limit, total, lastsess */ - "%d,%d,%d,%lld,," - /* bytes : in, out */ - "%lld,%lld," + "%d,%d,%d,%lld,%d," + /* bytes : in, out, lastactv */ + "%lld,%lld,%d," /* denied: req, resp */ "%lld,%lld," /* errors : request, connect, response */ @@ -2526,8 +2531,8 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) /* check_status, check_code, check_duration */ ",,,", px->id, - px->feconn, px->fe_counters.conn_max, px->maxconn, px->fe_counters.cum_sess, - px->fe_counters.bytes_in, px->fe_counters.bytes_out, + px->feconn, px->fe_counters.conn_max, px->maxconn, px->fe_counters.cum_sess, fe_lastsession(px), + px->fe_counters.bytes_in, px->fe_counters.bytes_out, fe_lastactv(px), px->fe_counters.denied_req, px->fe_counters.denied_resp, px->fe_counters.failed_req, px->state == PR_STREADY ? "OPEN" : @@ -2627,13 +2632,14 @@ static int stats_dump_li_stats(struct stream_interface *si, struct proxy *px, st "<td colspan=3> </td>" /* sessions: current, max, limit, total, lbtot, lastsess */ "<td>%s</td><td>%s</td><td>%s</td>" - "<td>%s</td><td> </td><td> </td>" - /* bytes: in, out */ - "<td>%s</td><td>%s</td>" + "<td>%s</td><td> </td><td>%s</td>" + /* bytes: in, out, last */ + "<td>%s</td><td>%s</td><td>%s</td>" "", (flags & ST_SHLGNDS)?"</u>":"", U2H(l->nbconn), U2H(l->counters->conn_max), U2H(l->maxconn), - U2H(l->counters->cum_conn), U2H(l->counters->bytes_in), U2H(l->counters->bytes_out)); + U2H(l->counters->cum_conn), human_time(li_lastsession(l), 1), + U2H(l->counters->bytes_in), U2H(l->counters->bytes_out), human_time(li_lastactv(l), 1)); chunk_appendf(&trash, /* denied: req, resp */ @@ -2656,9 +2662,9 @@ static int stats_dump_li_stats(struct stream_interface *si, struct proxy *px, st /* pxid, name, queue cur, queue max, */ "%s,%s,,," /* sessions: current, max, limit, total, lastsess */ - "%d,%d,%d,%lld,," - /* bytes: in, out */ - "%lld,%lld," + "%d,%d,%d,%lld,%d," + /* bytes: in, out, last */ + "%lld,%lld,%d," /* denied: req, resp */ "%lld,%lld," /* errors: request, connect, response */ @@ -2688,8 +2694,8 @@ static int stats_dump_li_stats(struct stream_interface *si, struct proxy *px, st "\n", px->id, l->name, l->nbconn, l->counters->conn_max, - l->maxconn, l->counters->cum_conn, - l->counters->bytes_in, l->counters->bytes_out, + l->maxconn, l->counters->cum_conn, li_lastsession(l), + l->counters->bytes_in, l->counters->bytes_out, li_lastactv(l), l->counters->denied_req, l->counters->denied_resp, l->counters->failed_req, (l->nbconn < l->maxconn) ? "OPEN" : "FULL", @@ -2835,8 +2841,8 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in human_time(srv_lastsession(sv), 1)); chunk_appendf(&trash, - /* bytes : in, out */ - "<td>%s</td><td>%s</td>" + /* bytes : in, out, last */ + "<td>%s</td><td>%s</td><td>%s</td>" /* denied: req, resp */ "<td></td><td>%s</td>" /* errors : request, connect */ @@ -2846,7 +2852,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in /* warnings: retries, redispatches */ "<td>%lld</td><td>%lld</td>" "", - U2H(sv->counters.bytes_in), U2H(sv->counters.bytes_out), + U2H(sv->counters.bytes_in), U2H(sv->counters.bytes_out), human_time(srv_lastactv(sv), 1), U2H(sv->counters.failed_secu), U2H(sv->counters.failed_conns), U2H(sv->counters.failed_resp), @@ -2960,8 +2966,8 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in "%d,%d," /* sessions : current, max, limit, total, lastsess */ "%d,%d,%s,%lld,%d," - /* bytes : in, out */ - "%lld,%lld," + /* bytes : in, out, last */ + "%lld,%lld,%d," /* denied: req, resp */ ",%lld," /* errors : request, connect, response */ @@ -2973,7 +2979,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in sv->nbpend, sv->counters.nbpend_max, sv->cur_sess, sv->counters.cur_sess_max, LIM2A(sv->maxconn, ""), sv->counters.cum_sess, srv_lastsession(sv), - sv->counters.bytes_in, sv->counters.bytes_out, + sv->counters.bytes_in, sv->counters.bytes_out, srv_lastactv(sv), sv->counters.failed_secu, sv->counters.failed_conns, sv->counters.failed_resp, sv->counters.retries, sv->counters.redispatches); @@ -3199,6 +3205,8 @@ static int stats_dump_be_stats(struct stream_interface *si, struct proxy *px, in (px->be_counters.comp_in || px->be_counters.comp_byp) ? "</u>":""); chunk_appendf(&trash, + /* last activity/byte */ + "<td>%s</td>" /* denied: req, resp */ "<td>%s</td><td>%s</td>" /* errors : request, connect */ @@ -3214,6 +3222,7 @@ static int stats_dump_be_stats(struct stream_interface *si, struct proxy *px, in "<td class=ac>%s %s</td><td class=ac> </td><td class=ac>%d</td>" "<td class=ac>%d</td><td class=ac>%d</td>" "", + human_time(be_lastactv(px), 1), U2H(px->be_counters.denied_req), U2H(px->be_counters.denied_resp), U2H(px->be_counters.failed_conns), U2H(px->be_counters.failed_resp), @@ -3243,8 +3252,8 @@ static int stats_dump_be_stats(struct stream_interface *si, struct proxy *px, in "%d,%d," /* sessions : current, max, limit, total, lastsess */ "%d,%d,%d,%lld,%d," - /* bytes : in, out */ - "%lld,%lld," + /* bytes : in, out, last */ + "%lld,%lld,%d," /* denied: req, resp */ "%lld,%lld," /* errors : request, connect, response */ @@ -3269,7 +3278,7 @@ static int stats_dump_be_stats(struct stream_interface *si, struct proxy *px, in px->nbpend /* or px->totpend ? */, px->be_counters.nbpend_max, px->beconn, px->be_counters.conn_max, px->fullconn, px->be_counters.cum_conn, be_lastsession(px), - px->be_counters.bytes_in, px->be_counters.bytes_out, + px->be_counters.bytes_in, px->be_counters.bytes_out, be_lastactv(px), px->be_counters.denied_req, px->be_counters.denied_resp, px->be_counters.failed_conns, px->be_counters.failed_resp, px->be_counters.retries, px->be_counters.redispatches, @@ -3383,14 +3392,14 @@ static void stats_dump_html_px_hdr(struct stream_interface *si, struct proxy *px "<th rowspan=2></th>" "<th colspan=3>Queue</th>" "<th colspan=3>Session rate</th><th colspan=6>Sessions</th>" - "<th colspan=2>Bytes</th><th colspan=2>Denied</th>" + "<th colspan=3>Bytes</th><th colspan=2>Denied</th>" "<th colspan=3>Errors</th><th colspan=2>Warnings</th>" "<th colspan=9>Server</th>" "</tr>\n" "<tr class=\"titre\">" "<th>Cur</th><th>Max</th><th>Limit</th>" "<th>Cur</th><th>Max</th><th>Limit</th><th>Cur</th><th>Max</th>" - "<th>Limit</th><th>Total</th><th>LbTot</th><th>Last</th><th>In</th><th>Out</th>" + "<th>Limit</th><th>Total</th><th>LbTot</th><th>Last</th><th>In</th><th>Out</th><th>Last</th>" "<th>Req</th><th>Resp</th><th>Req</th><th>Conn</th>" "<th>Resp</th><th>Retr</th><th>Redis</th>" "<th>Status</th><th>LastChk</th><th>Wght</th><th>Act</th>" diff --git a/src/frontend.c b/src/frontend.c index f94c6ab..bee7f7a 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -46,6 +46,25 @@ #include <proto/stream_interface.h> #include <proto/task.h> +/* time since last byte */ +int fe_lastactv(const struct proxy *fe) +{ + if (fe->fe_counters.last_actv) + return now.tv_sec - fe->fe_counters.last_actv; + + return -1; + +} + +/* time since last accepted connection */ +int fe_lastsession(const struct proxy *fe) +{ + if (fe->fe_counters.last_sess) + return now.tv_sec - fe->fe_counters.last_sess; + + return -1; +} + /* Finish a session accept() for a proxy (TCP or HTTP). It returns a negative * value in case of a critical failure which must cause the listener to be * disabled, a positive value in case of success, or zero if it is a success diff --git a/src/listener.c b/src/listener.c index 7ab1a87..288636f 100644 --- a/src/listener.c +++ b/src/listener.c @@ -39,6 +39,24 @@ static struct bind_kw_list bind_keywords = { .list = LIST_HEAD_INIT(bind_keywords.list) }; +/* last activity/byte time */ +int li_lastactv(const struct listener *li) +{ + if (li->counters->last_actv) + return now.tv_sec - li->counters->last_actv; + + return -1; +} + +/* time since last accepted connection */ +int li_lastsession(const struct listener *li) +{ + if (li->counters->last_sess) + return now.tv_sec - li->counters->last_sess; + + return -1; +} + /* This function adds the specified listener's file descriptor to the polling * lists if it is in the LI_LISTEN state. The listener enters LI_READY or * LI_FULL state depending on its number of connections. diff --git a/src/server.c b/src/server.c index ccae58b..3c4f101 100644 --- a/src/server.c +++ b/src/server.c @@ -30,6 +30,15 @@ int srv_downtime(const struct server *s) return now.tv_sec - s->last_change + s->down_time; } +/* time since last activity/byte */ +int srv_lastactv(const struct server *s) +{ + if (s->counters.last_actv) + return now.tv_sec - s->counters.last_actv; + + return -1; +} + int srv_lastsession(const struct server *s) { if (s->counters.last_sess) diff --git a/src/session.c b/src/session.c index 4768fd3..634d06b 100644 --- a/src/session.c +++ b/src/session.c @@ -126,6 +126,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) p->fe_counters.conn_max = p->feconn; proxy_inc_fe_conn_ctr(l, p); + proxy_set_fe_conn_last(l, p); /* Add the minimum callbacks to prepare the connection's control layer. * We need this so that we can safely execute the ACLs used by the @@ -689,14 +690,20 @@ void session_process_counters(struct session *s) s->logs.bytes_in = s->req->total; if (bytes) { s->fe->fe_counters.bytes_in += bytes; + s->fe->fe_counters.last_actv += now.tv_sec; s->be->be_counters.bytes_in += bytes; + s->be->be_counters.last_actv = now.tv_sec; - if (objt_server(s->target)) + if (objt_server(s->target)) { objt_server(s->target)->counters.bytes_in += bytes; + objt_server(s->target)->counters.last_actv = now.tv_sec; + } - if (s->listener->counters) + if (s->listener->counters) { s->listener->counters->bytes_in += bytes; + s->listener->counters->last_actv += now.tv_sec; + } for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!stkctr_entry(&s->stkctr[i])) @@ -723,14 +730,20 @@ void session_process_counters(struct session *s) s->logs.bytes_out = s->rep->total; if (bytes) { s->fe->fe_counters.bytes_out += bytes; + s->fe->fe_counters.last_actv = now.tv_sec; s->be->be_counters.bytes_out += bytes; + s->be->be_counters.last_actv = now.tv_sec; - if (objt_server(s->target)) + if (objt_server(s->target)) { objt_server(s->target)->counters.bytes_out += bytes; + objt_server(s->target)->counters.last_actv = now.tv_sec; + } - if (s->listener->counters) + if (s->listener->counters) { s->listener->counters->bytes_out += bytes; + s->listener->counters->last_actv = now.tv_sec; + } for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!stkctr_entry(&s->stkctr[i])) -- 1.7.10.4

