]> granicus.if.org Git - pgbouncer/commitdiff
Add SHOW STATS_TOTALS / STATS_AVERAGES as admin commands
authorTomas Vondra <tomas.vondra@2ndquadrant.com>
Sun, 24 Sep 2017 16:49:35 +0000 (18:49 +0200)
committerTomas Vondra <tomas.vondra@2ndquadrant.com>
Sun, 24 Sep 2017 17:01:07 +0000 (19:01 +0200)
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
include/stats.h
src/admin.c
src/stats.c

index 266b8c839d2b883073b5a63940e65404903a43b7..edccf5770109a52688499e672b4994531af723db 100644 (file)
@@ -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;
 -------------
 
index cd7c8029e682f9e7436749c0de5e3e3677028a22..9ed838618bcb8fbabc74b309ee3ff69bca251c2b 100644 (file)
@@ -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;
 
index 6db49726bf03f939bb17d369a204172627eff82f..6e46ad5c92a67d793ecc9e20faf1eb63b65cf264 100644 (file)
@@ -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},
index ba27e49c862c1f5535b7b1044b3b758d6d18bf82..54bb0312e2bc8c15aa8e0ac125bb6264c9185aeb 100644 (file)
@@ -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;