From 656844e56a2683eb8f347cda90ae8aa335f16814 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sun, 24 Sep 2017 18:49:35 +0200 Subject: [PATCH] Add SHOW STATS_TOTALS / STATS_AVERAGES as admin commands We already had SHOW STATS, but after adding the wait_time colums it got a bit too wide for regular screens. That's incovenient, as the admin interface does not selecting only some of the columns. But in most cases we're only interested either in totals or averages, not both at the same time. So let's add commands showing only the relevant subset of columns. --- doc/usage.rst | 12 +++++ include/stats.h | 2 + src/admin.c | 12 +++++ src/stats.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) diff --git a/doc/usage.rst b/doc/usage.rst index 266b8c8..edccf57 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -220,6 +220,18 @@ avg_wait_time Time spent by clients waiting for a server in microseconds (average per second). +SHOW STATS_TOTALS; +------------------ + +Subset of **SHOW STATS** showing the total values (**total_**). + + +SHOW STATS_AVERAGES; +-------------------- + +Subset of **SHOW STATS** showing the average values (**avg_**). + + SHOW SERVERS; ------------- diff --git a/include/stats.h b/include/stats.h index cd7c802..9ed8386 100644 --- a/include/stats.h +++ b/include/stats.h @@ -19,5 +19,7 @@ void stats_setup(void); bool admin_database_stats(PgSocket *client, struct StatList *pool_list) _MUSTCHECK; +bool admin_database_stats_totals(PgSocket *client, struct StatList *pool_list) _MUSTCHECK; +bool admin_database_stats_averages(PgSocket *client, struct StatList *pool_list) _MUSTCHECK; bool show_stat_totals(PgSocket *client, struct StatList *pool_list) _MUSTCHECK; diff --git a/src/admin.c b/src/admin.c index 6db4972..6e46ad5 100644 --- a/src/admin.c +++ b/src/admin.c @@ -1226,6 +1226,16 @@ static bool admin_show_stats(PgSocket *admin, const char *arg) return admin_database_stats(admin, &pool_list); } +static bool admin_show_stats_totals(PgSocket *admin, const char *arg) +{ + return admin_database_stats_totals(admin, &pool_list); +} + +static bool admin_show_stats_averages(PgSocket *admin, const char *arg) +{ + return admin_database_stats_averages(admin, &pool_list); +} + static bool admin_show_totals(PgSocket *admin, const char *arg) { return show_stat_totals(admin, &pool_list); @@ -1244,6 +1254,8 @@ static struct cmd_lookup show_map [] = { {"sockets", admin_show_sockets}, {"active_sockets", admin_show_active_sockets}, {"stats", admin_show_stats}, + {"stats_totals", admin_show_stats_totals}, + {"stats_averages", admin_show_stats_averages}, {"users", admin_show_users}, {"version", admin_show_version}, {"totals", admin_show_totals}, diff --git a/src/stats.c b/src/stats.c index ba27e49..54bb031 100644 --- a/src/stats.c +++ b/src/stats.c @@ -148,6 +148,140 @@ bool admin_database_stats(PgSocket *client, struct StatList *pool_list) return true; } +static void write_stats_totals(PktBuf *buf, PgStats *stat, PgStats *old, char *dbname) +{ + PgStats avg; + calc_average(&avg, stat, old); + pktbuf_write_DataRow(buf, "sqqqqqqq", dbname, + stat->xact_count, stat->query_count, + stat->client_bytes, stat->server_bytes, + stat->xact_time, stat->query_time, + stat->wait_time); +} + +bool admin_database_stats_totals(PgSocket *client, struct StatList *pool_list) +{ + PgPool *pool; + struct List *item; + PgDatabase *cur_db = NULL; + PgStats st_total, st_db, old_db, old_total; + int rows = 0; + PktBuf *buf; + + reset_stats(&st_total); + reset_stats(&st_db); + reset_stats(&old_db); + reset_stats(&old_total); + + buf = pktbuf_dynamic(512); + if (!buf) { + admin_error(client, "no mem"); + return true; + } + + pktbuf_write_RowDescription(buf, "sqqqqqqq", "database", + "xact_count", "query_count", + "bytes_received", "bytes_sent", + "xact_time", "query_time", + "wait_time"); + statlist_for_each(item, pool_list) { + pool = container_of(item, PgPool, head); + + if (!cur_db) + cur_db = pool->db; + + if (pool->db != cur_db) { + write_stats_totals(buf, &st_db, &old_db, cur_db->name); + + rows ++; + cur_db = pool->db; + stat_add(&st_total, &st_db); + stat_add(&old_total, &old_db); + reset_stats(&st_db); + reset_stats(&old_db); + } + + stat_add(&st_db, &pool->stats); + stat_add(&old_db, &pool->older_stats); + } + if (cur_db) { + write_stats_totals(buf, &st_db, &old_db, cur_db->name); + stat_add(&st_total, &st_db); + stat_add(&old_total, &old_db); + rows ++; + } + admin_flush(client, buf, "SHOW"); + + return true; +} + +static void write_stats_averages(PktBuf *buf, PgStats *stat, PgStats *old, char *dbname) +{ + PgStats avg; + calc_average(&avg, stat, old); + pktbuf_write_DataRow(buf, "sqqqqqqq", dbname, + avg.xact_count, avg.query_count, + avg.client_bytes, avg.server_bytes, + avg.xact_time, avg.query_time, + avg.wait_time); +} + +bool admin_database_stats_averages(PgSocket *client, struct StatList *pool_list) +{ + PgPool *pool; + struct List *item; + PgDatabase *cur_db = NULL; + PgStats st_total, st_db, old_db, old_total; + int rows = 0; + PktBuf *buf; + + reset_stats(&st_total); + reset_stats(&st_db); + reset_stats(&old_db); + reset_stats(&old_total); + + buf = pktbuf_dynamic(512); + if (!buf) { + admin_error(client, "no mem"); + return true; + } + + pktbuf_write_RowDescription(buf, "sqqqqqqq", "database", + "xact_count", "query_count", + "bytes_received", "bytes_sent", + "xact_time", "query_time", + "wait_time"); + statlist_for_each(item, pool_list) { + pool = container_of(item, PgPool, head); + + if (!cur_db) + cur_db = pool->db; + + if (pool->db != cur_db) { + write_stats_averages(buf, &st_db, &old_db, cur_db->name); + + rows ++; + cur_db = pool->db; + stat_add(&st_total, &st_db); + stat_add(&old_total, &old_db); + reset_stats(&st_db); + reset_stats(&old_db); + } + + stat_add(&st_db, &pool->stats); + stat_add(&old_db, &pool->older_stats); + } + if (cur_db) { + write_stats_averages(buf, &st_db, &old_db, cur_db->name); + stat_add(&st_total, &st_db); + stat_add(&old_total, &old_db); + rows ++; + } + admin_flush(client, buf, "SHOW"); + + return true; +} + bool show_stat_totals(PgSocket *client, struct StatList *pool_list) { PgPool *pool; -- 2.40.0