From 12d8a3d43caac141641696bfc18863b18cdf9d4d Mon Sep 17 00:00:00 2001 From: Juraj Bubniak Date: Thu, 10 Oct 2024 21:40:39 +0200 Subject: [PATCH] Expose database server_lifetime metric. --- internal/collector/metrics.go | 16 ++++++++++++ internal/domain/domain.go | 1 + internal/sqlstore/sql.go | 9 ++++--- internal/sqlstore/sql_test.go | 46 ++++++++++++++++++++--------------- 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/internal/collector/metrics.go b/internal/collector/metrics.go index 20f32c7..f893d6b 100644 --- a/internal/collector/metrics.go +++ b/internal/collector/metrics.go @@ -280,6 +280,22 @@ func buildMetrics(cfg config.Config) []metric { return results }, }, + { + enabled: cfg.ExportDatabases, + name: fqName(SubsystemDatabases, "server_lifetime"), + help: "The maximum lifetime of a server connection for this database.", + labels: []string{"name", "pool_mode"}, + valType: prometheus.GaugeValue, + eval: func(res *storeResult) (results []metricResult) { + for _, database := range res.databases { + results = append(results, metricResult{ + labels: []string{database.Name, database.PoolMode}, + value: float64(database.ServerLifetime), + }) + } + return results + }, + }, { enabled: cfg.ExportLists, name: fqName(SubsystemLists, "items"), diff --git a/internal/domain/domain.go b/internal/domain/domain.go index e6c3bc1..13dfe73 100644 --- a/internal/domain/domain.go +++ b/internal/domain/domain.go @@ -61,6 +61,7 @@ type Database struct { CurrentConnections int64 Paused int64 Disabled int64 + ServerLifetime int64 } // List represents list row. diff --git a/internal/sqlstore/sql.go b/internal/sqlstore/sql.go index fb4ae32..4a46146 100644 --- a/internal/sqlstore/sql.go +++ b/internal/sqlstore/sql.go @@ -72,7 +72,7 @@ func (s *Store) GetStats(ctx context.Context) ([]domain.Stat, error) { var stats []domain.Stat for rows.Next() { - dest := make([]interface{}, 0, len(columns)) + dest := make([]any, 0, len(columns)) for _, column := range columns { switch column { @@ -145,7 +145,7 @@ func (s *Store) GetPools(ctx context.Context) ([]domain.Pool, error) { var pools []pool for rows.Next() { - dest := make([]interface{}, 0, len(columns)) + dest := make([]any, 0, len(columns)) for _, column := range columns { switch column { @@ -237,7 +237,7 @@ func (s *Store) GetDatabases(ctx context.Context) ([]domain.Database, error) { var databases []database for rows.Next() { - dest := make([]interface{}, 0, len(columns)) + dest := make([]any, 0, len(columns)) for _, column := range columns { switch column { @@ -300,6 +300,7 @@ func (s *Store) GetDatabases(ctx context.Context) ([]domain.Database, error) { CurrentConnections: row.CurrentConnections, Paused: row.Paused, Disabled: row.Disabled, + ServerLifetime: row.ServerLifetime, }) } @@ -323,7 +324,7 @@ func (s *Store) GetLists(ctx context.Context) ([]domain.List, error) { var lists []domain.List for rows.Next() { - dest := make([]interface{}, 0, len(columns)) + dest := make([]any, 0, len(columns)) for _, column := range columns { switch column { diff --git a/internal/sqlstore/sql_test.go b/internal/sqlstore/sql_test.go index 06bcbc9..fa12525 100644 --- a/internal/sqlstore/sql_test.go +++ b/internal/sqlstore/sql_test.go @@ -18,22 +18,24 @@ func TestGetStats(t *testing.T) { st := New(db) - data := map[string]interface{}{ - "database": "pgbouncer", - "total_xact_count": 1, - "total_query_count": 2, - "total_received": 3, - "total_sent": 4, - "total_xact_time": 5, - "total_query_time": 6, - "total_wait_time": 7, - "avg_xact_count": 8, - "avg_query_count": 9, - "avg_recv": 10, - "avg_sent": 11, - "avg_xact_time": 12, - "avg_query_time": 13, - "avg_wait_time": 14, + data := map[string]any{ + "database": "pgbouncer", + "total_xact_count": 1, + "total_query_count": 2, + "total_received": 3, + "total_sent": 4, + "total_xact_time": 5, + "total_query_time": 6, + "total_wait_time": 7, + "total_server_assignment_count": 8, + "avg_xact_count": 9, + "avg_query_count": 10, + "avg_recv": 11, + "avg_sent": 12, + "avg_xact_time": 13, + "avg_query_time": 14, + "avg_wait_time": 15, + "avg_server_assignment_count": 16, } mock.ExpectQuery("SHOW STATS").WillReturnRows(mapToRows(data)) @@ -51,6 +53,7 @@ func TestGetStats(t *testing.T) { require.Equal(t, int64(data["total_xact_time"].(int)), stat.TotalXactTime) require.Equal(t, int64(data["total_query_time"].(int)), stat.TotalQueryTime) require.Equal(t, int64(data["total_wait_time"].(int)), stat.TotalWaitTime) + require.Equal(t, int64(data["total_server_assignment_count"].(int)), stat.TotalServerAssignmentCount) require.Equal(t, int64(data["avg_xact_count"].(int)), stat.AverageXactCount) require.Equal(t, int64(data["avg_query_count"].(int)), stat.AverageQueryCount) require.Equal(t, int64(data["avg_recv"].(int)), stat.AverageReceived) @@ -58,6 +61,7 @@ func TestGetStats(t *testing.T) { require.Equal(t, int64(data["avg_xact_time"].(int)), stat.AverageXactTime) require.Equal(t, int64(data["avg_query_time"].(int)), stat.AverageQueryTime) require.Equal(t, int64(data["avg_wait_time"].(int)), stat.AverageWaitTime) + require.Equal(t, int64(data["avg_server_assignment_count"].(int)), stat.AverageServerAssignmentCount) } func TestGetPools(t *testing.T) { @@ -69,7 +73,7 @@ func TestGetPools(t *testing.T) { st := New(db) - data := map[string]interface{}{ + data := map[string]any{ "database": "pgbouncer", "user": "myuser", "cl_active": 1, @@ -114,7 +118,7 @@ func TestGetDatabases(t *testing.T) { st := New(db) - data := map[string]interface{}{ + data := map[string]any{ "database": "pgbouncer", "name": "myname", "host": "localhost", @@ -127,6 +131,7 @@ func TestGetDatabases(t *testing.T) { "current_connections": 8, "paused": 9, "disabled": 10, + "server_lifetime": 11, } mock.ExpectQuery("SHOW DATABASES").WillReturnRows(mapToRows(data)) @@ -148,6 +153,7 @@ func TestGetDatabases(t *testing.T) { require.Equal(t, int64(data["current_connections"].(int)), database.CurrentConnections) require.Equal(t, int64(data["paused"].(int)), database.Paused) require.Equal(t, int64(data["disabled"].(int)), database.Disabled) + require.Equal(t, int64(data["server_lifetime"].(int)), database.ServerLifetime) } func TestGetLists(t *testing.T) { @@ -159,7 +165,7 @@ func TestGetLists(t *testing.T) { st := New(db) - data := map[string]interface{}{ + data := map[string]any{ "list": "mylist", "items": 6, } @@ -175,7 +181,7 @@ func TestGetLists(t *testing.T) { require.Equal(t, int64(data["items"].(int)), list.Items) } -func mapToRows(data map[string]interface{}) *sqlmock.Rows { +func mapToRows(data map[string]any) *sqlmock.Rows { columns := make([]string, 0, len(data)) values := make([]driver.Value, 0, len(data)) for k, v := range data {