From: Willy Tarreau Date: Fri, 8 Jan 2016 16:15:39 +0000 (+0100) Subject: REORG: stats: dump the frontend's HTML stats via a generic function X-Git-Tag: v1.7-dev2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5f66b8138275597b3df2da8ec9332b9f948fc21;p=thirdparty%2Fhaproxy.git REORG: stats: dump the frontend's HTML stats via a generic function This new function stats_dump_fields_html() checks the type of the object being dumped from the stats table, and emits it in HTML format. It uses an argument indicating if the HTML page is also used as an admin page, and for now still takes the proxy in argument as a few entries still need it. The code was simply moved as-is to the new function. There's no functional change. --- diff --git a/src/dumpstats.c b/src/dumpstats.c index 2a445c0212..537c75f563 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -3248,69 +3248,18 @@ static int stats_dump_fields_csv(struct chunk *out, const struct field *stats) return 1; } -/* Dumps a frontend's line to the trash for the current proxy and uses - * the state from stream interface . The caller is responsible for clearing - * the trash if needed. Returns non-zero if it emits anything, zero otherwise. +/* Dump all fields from for proxy into trash using the HTML format. + * A column is reserved for the checkbox is is non-null. The caller's + * flags may be passed in (eg: SHLGNDS to show the legends). */ -static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) +static int stats_dump_fields_html(const struct field *stats, int admin, unsigned int flags, struct proxy *px) { - struct appctx *appctx = __objt_appctx(si->end); - - if (!(px->cap & PR_CAP_FE)) - return 0; - - if ((appctx->ctx.stats.flags & STAT_BOUND) && !(appctx->ctx.stats.type & (1 << STATS_TYPE_FE))) - return 0; - - memset(&stats, 0, sizeof(stats)); - - stats[ST_F_PXNAME] = mkf_str(FO_KEY|FN_NAME|FS_SERVICE, px->id); - stats[ST_F_SVNAME] = mkf_str(FO_KEY|FN_NAME|FS_SERVICE, "FRONTEND"); - stats[ST_F_SCUR] = mkf_u32(0, px->feconn); - stats[ST_F_SMAX] = mkf_u32(FN_MAX, px->fe_counters.conn_max); - stats[ST_F_SLIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->maxconn); - stats[ST_F_STOT] = mkf_u64(FN_COUNTER, px->fe_counters.cum_sess); - stats[ST_F_BIN] = mkf_u64(FN_COUNTER, px->fe_counters.bytes_in); - stats[ST_F_BOUT] = mkf_u64(FN_COUNTER, px->fe_counters.bytes_out); - stats[ST_F_DREQ] = mkf_u64(FN_COUNTER, px->fe_counters.denied_req); - stats[ST_F_DRESP] = mkf_u64(FN_COUNTER, px->fe_counters.denied_resp); - stats[ST_F_EREQ] = mkf_u64(FN_COUNTER, px->fe_counters.failed_req); - stats[ST_F_STATUS] = mkf_str(FO_STATUS, px->state == PR_STREADY ? "OPEN" : px->state == PR_STFULL ? "FULL" : "STOP"); - stats[ST_F_PID] = mkf_u32(FO_KEY, relative_pid); - stats[ST_F_IID] = mkf_u32(FO_KEY|FS_SERVICE, px->uuid); - stats[ST_F_SID] = mkf_u32(FO_KEY|FS_SERVICE, 0); - stats[ST_F_TYPE] = mkf_u32(FO_CONFIG|FS_SERVICE, STATS_TYPE_FE); - stats[ST_F_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_sess_per_sec)); - stats[ST_F_RATE_LIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->fe_sps_lim); - stats[ST_F_RATE_MAX] = mkf_u32(FN_MAX, px->fe_counters.sps_max); - - /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */ - if (px->mode == PR_MODE_HTTP) { - stats[ST_F_HRSP_1XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[1]); - stats[ST_F_HRSP_2XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[2]); - stats[ST_F_HRSP_3XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[3]); - stats[ST_F_HRSP_4XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[4]); - stats[ST_F_HRSP_5XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[5]); - stats[ST_F_HRSP_OTHER] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[0]); - } - - /* requests : req_rate, req_rate_max, req_tot, */ - stats[ST_F_REQ_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_req_per_sec)); - stats[ST_F_REQ_RATE_MAX] = mkf_u32(FN_MAX, px->fe_counters.p.http.rps_max); - stats[ST_F_REQ_TOT] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.cum_req); - - /* compression: in, out, bypassed, responses */ - stats[ST_F_COMP_IN] = mkf_u64(FN_COUNTER, px->fe_counters.comp_in); - stats[ST_F_COMP_OUT] = mkf_u64(FN_COUNTER, px->fe_counters.comp_out); - stats[ST_F_COMP_BYP] = mkf_u64(FN_COUNTER, px->fe_counters.comp_byp); - stats[ST_F_COMP_RSP] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.comp_rsp); - - if (appctx->ctx.stats.flags & STAT_FMT_HTML) { + if (stats[ST_F_TYPE].u.u32 == STATS_TYPE_FE) { chunk_appendf(&trash, /* name, queue */ ""); - if (px->cap & PR_CAP_BE && px->srv && (appctx->ctx.stats.flags & STAT_ADMIN)) { + if (admin) { /* Column sub-heading for Enable or Disable server */ chunk_appendf(&trash, ""); } @@ -3443,6 +3392,72 @@ static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) U2H(stats[ST_F_EREQ].u.u64), field_str(stats, ST_F_STATUS)); } + return 1; +} + +/* Dumps a frontend's line to the trash for the current proxy and uses + * the state from stream interface . The caller is responsible for clearing + * the trash if needed. Returns non-zero if it emits anything, zero otherwise. + */ +static int stats_dump_fe_stats(struct stream_interface *si, struct proxy *px) +{ + struct appctx *appctx = __objt_appctx(si->end); + + if (!(px->cap & PR_CAP_FE)) + return 0; + + if ((appctx->ctx.stats.flags & STAT_BOUND) && !(appctx->ctx.stats.type & (1 << STATS_TYPE_FE))) + return 0; + + memset(&stats, 0, sizeof(stats)); + + stats[ST_F_PXNAME] = mkf_str(FO_KEY|FN_NAME|FS_SERVICE, px->id); + stats[ST_F_SVNAME] = mkf_str(FO_KEY|FN_NAME|FS_SERVICE, "FRONTEND"); + stats[ST_F_SCUR] = mkf_u32(0, px->feconn); + stats[ST_F_SMAX] = mkf_u32(FN_MAX, px->fe_counters.conn_max); + stats[ST_F_SLIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->maxconn); + stats[ST_F_STOT] = mkf_u64(FN_COUNTER, px->fe_counters.cum_sess); + stats[ST_F_BIN] = mkf_u64(FN_COUNTER, px->fe_counters.bytes_in); + stats[ST_F_BOUT] = mkf_u64(FN_COUNTER, px->fe_counters.bytes_out); + stats[ST_F_DREQ] = mkf_u64(FN_COUNTER, px->fe_counters.denied_req); + stats[ST_F_DRESP] = mkf_u64(FN_COUNTER, px->fe_counters.denied_resp); + stats[ST_F_EREQ] = mkf_u64(FN_COUNTER, px->fe_counters.failed_req); + stats[ST_F_STATUS] = mkf_str(FO_STATUS, px->state == PR_STREADY ? "OPEN" : px->state == PR_STFULL ? "FULL" : "STOP"); + stats[ST_F_PID] = mkf_u32(FO_KEY, relative_pid); + stats[ST_F_IID] = mkf_u32(FO_KEY|FS_SERVICE, px->uuid); + stats[ST_F_SID] = mkf_u32(FO_KEY|FS_SERVICE, 0); + stats[ST_F_TYPE] = mkf_u32(FO_CONFIG|FS_SERVICE, STATS_TYPE_FE); + stats[ST_F_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_sess_per_sec)); + stats[ST_F_RATE_LIM] = mkf_u32(FO_CONFIG|FN_LIMIT, px->fe_sps_lim); + stats[ST_F_RATE_MAX] = mkf_u32(FN_MAX, px->fe_counters.sps_max); + + /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */ + if (px->mode == PR_MODE_HTTP) { + stats[ST_F_HRSP_1XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[1]); + stats[ST_F_HRSP_2XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[2]); + stats[ST_F_HRSP_3XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[3]); + stats[ST_F_HRSP_4XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[4]); + stats[ST_F_HRSP_5XX] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[5]); + stats[ST_F_HRSP_OTHER] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.rsp[0]); + } + + /* requests : req_rate, req_rate_max, req_tot, */ + stats[ST_F_REQ_RATE] = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_req_per_sec)); + stats[ST_F_REQ_RATE_MAX] = mkf_u32(FN_MAX, px->fe_counters.p.http.rps_max); + stats[ST_F_REQ_TOT] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.cum_req); + + /* compression: in, out, bypassed, responses */ + stats[ST_F_COMP_IN] = mkf_u64(FN_COUNTER, px->fe_counters.comp_in); + stats[ST_F_COMP_OUT] = mkf_u64(FN_COUNTER, px->fe_counters.comp_out); + stats[ST_F_COMP_BYP] = mkf_u64(FN_COUNTER, px->fe_counters.comp_byp); + stats[ST_F_COMP_RSP] = mkf_u64(FN_COUNTER, px->fe_counters.p.http.comp_rsp); + + if (appctx->ctx.stats.flags & STAT_FMT_HTML) { + int admin; + + admin = (px->cap & PR_CAP_BE) && px->srv && (appctx->ctx.stats.flags & STAT_ADMIN); + stats_dump_fields_html(stats, admin, 0, px); + } else { /* CSV mode */ /* dump everything */ stats_dump_fields_csv(&trash, stats);