diff --git a/include/types/stats.h b/include/types/stats.h index 52ea18db4..4d2a933fc 100644 --- a/include/types/stats.h +++ b/include/types/stats.h @@ -430,6 +430,10 @@ enum stat_field { ST_F_CACHE_HITS, ST_F_SRV_ICUR, ST_F_SRV_ILIM, + ST_F_QT_MAX, + ST_F_CT_MAX, + ST_F_RT_MAX, + ST_F_TT_MAX, /* must always be the last one */ ST_F_TOTAL_FIELDS diff --git a/src/stats.c b/src/stats.c index c68ab63e7..02057c592 100644 --- a/src/stats.c +++ b/src/stats.c @@ -246,6 +246,10 @@ const struct name_desc stat_fields[ST_F_TOTAL_FIELDS] = { [ST_F_CACHE_HITS] = { .name = "cache_hits", .desc = "Total number of HTTP requests not found in the cache on this frontend/backend since the worker process started" }, [ST_F_SRV_ICUR] = { .name = "srv_icur", .desc = "Current number of idle connections available for reuse on this server" }, [ST_F_SRV_ILIM] = { .name = "src_ilim", .desc = "Limit on the number of available idle connections on this server (server 'pool_max_conn' directive)" }, + [ST_F_QT_MAX] = { .name = "qtime_max", .desc = "Maximum observed time spent in the queue, in milliseconds (backend/server)" }, + [ST_F_CT_MAX] = { .name = "ctime_max", .desc = "Maximum observed time spent waiting for a connection to complete, in milliseconds (backend/server)" }, + [ST_F_RT_MAX] = { .name = "rtime_max", .desc = "Maximum observed time spent waiting for a server response, in milliseconds (backend/server)" }, + [ST_F_TT_MAX] = { .name = "ttime_max", .desc = "Maximum observed total request+response time (request+queue+connect+response+processing), in milliseconds (backend/server)" }, }; /* one line of info */ @@ -1041,12 +1045,16 @@ static int stats_dump_fields_html(struct buffer *out, U2H(stats[ST_F_WREW].u.u64)); } - chunk_appendf(out, "Avg over last 1024 success. conn."); - chunk_appendf(out, "- Queue time:%sms", U2H(stats[ST_F_QTIME].u.u32)); - chunk_appendf(out, "- Connect time:%sms", U2H(stats[ST_F_CTIME].u.u32)); + chunk_appendf(out, "Max / Avg over last 1024 success. conn."); + chunk_appendf(out, "- Queue time:%s / %sms", + U2H(stats[ST_F_QT_MAX].u.u32), U2H(stats[ST_F_QTIME].u.u32)); + chunk_appendf(out, "- Connect time:%s / %sms", + U2H(stats[ST_F_CT_MAX].u.u32), U2H(stats[ST_F_CTIME].u.u32)); if (strcmp(field_str(stats, ST_F_MODE), "http") == 0) - chunk_appendf(out, "- Response time:%sms", U2H(stats[ST_F_RTIME].u.u32)); - chunk_appendf(out, "- Total time:%sms", U2H(stats[ST_F_TTIME].u.u32)); + chunk_appendf(out, "- Responses time:%s / %sms", + U2H(stats[ST_F_RT_MAX].u.u32), U2H(stats[ST_F_RTIME].u.u32)); + chunk_appendf(out, "- Total time:%s / %sms", + U2H(stats[ST_F_TT_MAX].u.u32), U2H(stats[ST_F_TTIME].u.u32)); chunk_appendf(out, "" @@ -1255,8 +1263,7 @@ static int stats_dump_fields_html(struct buffer *out, "Cache lookups:%s" "Cache hits:%s(%d%%)" "Failed hdr rewrites:%s" - "Avg over last 1024 success. conn." - "", + "", U2H(stats[ST_F_CONNECT].u.u64), U2H(stats[ST_F_REUSE].u.u64), (stats[ST_F_CONNECT].u.u64 + stats[ST_F_REUSE].u.u64) ? @@ -1278,11 +1285,16 @@ static int stats_dump_fields_html(struct buffer *out, U2H(stats[ST_F_WREW].u.u64)); } - chunk_appendf(out, "- Queue time:%sms", U2H(stats[ST_F_QTIME].u.u32)); - chunk_appendf(out, "- Connect time:%sms", U2H(stats[ST_F_CTIME].u.u32)); + chunk_appendf(out, "Max / Avg over last 1024 success. conn."); + chunk_appendf(out, "- Queue time:%s / %sms", + U2H(stats[ST_F_QT_MAX].u.u32), U2H(stats[ST_F_QTIME].u.u32)); + chunk_appendf(out, "- Connect time:%s / %sms", + U2H(stats[ST_F_CT_MAX].u.u32), U2H(stats[ST_F_CTIME].u.u32)); if (strcmp(field_str(stats, ST_F_MODE), "http") == 0) - chunk_appendf(out, "- Response time:%sms", U2H(stats[ST_F_RTIME].u.u32)); - chunk_appendf(out, "- Total time:%sms", U2H(stats[ST_F_TTIME].u.u32)); + chunk_appendf(out, "- Responses time:%s / %sms", + U2H(stats[ST_F_RT_MAX].u.u32), U2H(stats[ST_F_RTIME].u.u32)); + chunk_appendf(out, "- Total time:%s / %sms", + U2H(stats[ST_F_TT_MAX].u.u32), U2H(stats[ST_F_TTIME].u.u32)); chunk_appendf(out, "" @@ -1791,6 +1803,11 @@ int stats_fill_sv_stats(struct proxy *px, struct server *sv, int flags, stats[ST_F_RTIME] = mkf_u32(FN_AVG, swrate_avg(sv->counters.d_time, TIME_STATS_SAMPLES)); stats[ST_F_TTIME] = mkf_u32(FN_AVG, swrate_avg(sv->counters.t_time, TIME_STATS_SAMPLES)); + stats[ST_F_QT_MAX] = mkf_u32(FN_MAX, sv->counters.qtime_max); + stats[ST_F_CT_MAX] = mkf_u32(FN_MAX, sv->counters.ctime_max); + stats[ST_F_RT_MAX] = mkf_u32(FN_MAX, sv->counters.dtime_max); + stats[ST_F_TT_MAX] = mkf_u32(FN_MAX, sv->counters.ttime_max); + if (flags & STAT_SHLGNDS) { switch (addr_to_str(&sv->addr, str, sizeof(str))) { case AF_INET: @@ -1918,6 +1935,11 @@ int stats_fill_be_stats(struct proxy *px, int flags, struct field *stats, int le stats[ST_F_RTIME] = mkf_u32(FN_AVG, swrate_avg(px->be_counters.d_time, TIME_STATS_SAMPLES)); stats[ST_F_TTIME] = mkf_u32(FN_AVG, swrate_avg(px->be_counters.t_time, TIME_STATS_SAMPLES)); + stats[ST_F_QT_MAX] = mkf_u32(FN_MAX, px->be_counters.qtime_max); + stats[ST_F_CT_MAX] = mkf_u32(FN_MAX, px->be_counters.ctime_max); + stats[ST_F_RT_MAX] = mkf_u32(FN_MAX, px->be_counters.dtime_max); + stats[ST_F_TT_MAX] = mkf_u32(FN_MAX, px->be_counters.ttime_max); + return 1; }