@@ -13,6 +13,7 @@ import { GameServerNodeService } from "src/game-server-node/game-server-node.ser
1313import { LoggingService } from "src/k8s/logging/logging.service" ;
1414import { isRoleAbove } from "src/utilities/isRoleAbove" ;
1515import { PassThrough } from "stream" ;
16+ import { PostgresService } from "src/postgres/postgres.service" ;
1617
1718@Controller ( "system" )
1819export class SystemController {
@@ -22,13 +23,72 @@ export class SystemController {
2223 private readonly notifications : NotificationsService ,
2324 private readonly gameServerNodeService : GameServerNodeService ,
2425 private readonly loggingService : LoggingService ,
26+ private readonly postgres : PostgresService ,
2527 ) { }
2628
2729 @Get ( "healthz" )
2830 public async status ( ) {
2931 return ;
3032 }
3133
34+ @HasuraAction ( )
35+ public async dbStats ( ) {
36+ // Define a type for the result rows
37+ type DbStatRow = {
38+ queryid : string | number ;
39+ query : string ;
40+ calls : number ;
41+ total_exec_time : number ;
42+ mean_exec_time : number ;
43+ max_exec_time : number ;
44+ min_exec_time : number ;
45+ total_rows : number ;
46+ shared_blks_hit : number ;
47+ shared_blks_read : number ;
48+ local_blks_hit : number ;
49+ local_blks_read : number ;
50+ } ;
51+
52+ const result = await this . postgres . query < DbStatRow > ( `
53+ SELECT
54+ queryid,
55+ query,
56+ SUM(calls) AS calls,
57+ SUM(total_exec_time) AS total_exec_time,
58+ AVG(mean_exec_time) AS mean_exec_time,
59+ MAX(max_exec_time) AS max_exec_time,
60+ MIN(min_exec_time) AS min_exec_time,
61+ SUM(rows) AS total_rows,
62+ SUM(shared_blks_hit) AS shared_blks_hit,
63+ SUM(shared_blks_read) AS shared_blks_read,
64+ SUM(local_blks_hit) AS local_blks_hit,
65+ SUM(local_blks_read) AS local_blks_read
66+ FROM pg_stat_statements
67+ WHERE query NOT LIKE '/* pgbouncer */%'
68+ GROUP BY queryid, query
69+ HAVING SUM(calls) > 5
70+ ORDER BY mean_exec_time DESC
71+ LIMIT 50;
72+ ` ) ;
73+
74+ return ( result as unknown as any [ ] ) . map (
75+ ( row ) : DbStatRow => ( {
76+ queryid : row . queryid ,
77+ query : row . query ,
78+ calls : Number ( row . calls ) ,
79+ total_exec_time : Number ( row . total_exec_time ) ,
80+ mean_exec_time : Number ( row . mean_exec_time ) ,
81+ max_exec_time : Number ( row . max_exec_time ) ,
82+ min_exec_time : Number ( row . min_exec_time ) ,
83+ total_rows : Number ( row . total_rows ) ,
84+ shared_blks_hit : Number ( row . shared_blks_hit ) ,
85+ shared_blks_read : Number ( row . shared_blks_read ) ,
86+ local_blks_hit : Number ( row . local_blks_hit ) ,
87+ local_blks_read : Number ( row . local_blks_read ) ,
88+ } ) ,
89+ ) ;
90+ }
91+
3292 @Post ( "logs/download" )
3393 public async logs (
3494 @Req ( ) request : Request ,
0 commit comments