Skip to content

Commit 4a43f54

Browse files
committed
Add database connection limits metrics
Signed-off-by: Jocelyn Thode <[email protected]>
1 parent 9cfa132 commit 4a43f54

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

collector/pg_database.go

+26-5
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,21 @@ var (
5353
"Disk space used by the database",
5454
[]string{"datname"}, nil,
5555
)
56+
pgDatabaseConnectionLimitsDesc = prometheus.NewDesc(
57+
prometheus.BuildFQName(
58+
namespace,
59+
databaseSubsystem,
60+
"connection_limit",
61+
),
62+
"Connection limit set for the database",
63+
[]string{"datname"}, nil,
64+
)
5665

57-
pgDatabaseQuery = "SELECT pg_database.datname FROM pg_database;"
66+
pgDatabaseQuery = "select pg_database.datname,pg_database.datconnlimit FROM pg_database"
5867
pgDatabaseSizeQuery = "SELECT pg_database_size($1)"
5968
)
6069

61-
// Update implements Collector and exposes database size.
70+
// Update implements Collector and exposes database size and connection limits.
6271
// It is called by the Prometheus registry when collecting metrics.
6372
// The list of databases is retrieved from pg_database and filtered
6473
// by the excludeDatabase config parameter. The tradeoff here is that
@@ -81,21 +90,32 @@ func (c PGDatabaseCollector) Update(ctx context.Context, instance *instance, ch
8190

8291
for rows.Next() {
8392
var datname sql.NullString
84-
if err := rows.Scan(&datname); err != nil {
93+
var connLimit sql.NullInt64
94+
if err := rows.Scan(&datname, &connLimit); err != nil {
8595
return err
8696
}
8797

8898
if !datname.Valid {
8999
continue
90100
}
101+
database := datname.String
91102
// Ignore excluded databases
92103
// Filtering is done here instead of in the query to avoid
93104
// a complicated NOT IN query with a variable number of parameters
94-
if sliceContains(c.excludedDatabases, datname.String) {
105+
if sliceContains(c.excludedDatabases, database) {
95106
continue
96107
}
97108

98-
databases = append(databases, datname.String)
109+
databases = append(databases, database)
110+
111+
connLimitMetric := 0.0
112+
if connLimit.Valid {
113+
connLimitMetric = float64(connLimit.Int64)
114+
}
115+
ch <- prometheus.MustNewConstMetric(
116+
pgDatabaseConnectionLimitsDesc,
117+
prometheus.GaugeValue, connLimitMetric, database,
118+
)
99119
}
100120

101121
// Query the size of the databases
@@ -114,6 +134,7 @@ func (c PGDatabaseCollector) Update(ctx context.Context, instance *instance, ch
114134
pgDatabaseSizeDesc,
115135
prometheus.GaugeValue, sizeMetric, datname,
116136
)
137+
117138
}
118139
return rows.Err()
119140
}

collector/pg_database_test.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ func TestPGDatabaseCollector(t *testing.T) {
3131

3232
inst := &instance{db: db}
3333

34-
mock.ExpectQuery(sanitizeQuery(pgDatabaseQuery)).WillReturnRows(sqlmock.NewRows([]string{"datname"}).
35-
AddRow("postgres"))
34+
mock.ExpectQuery(sanitizeQuery(pgDatabaseQuery)).WillReturnRows(sqlmock.NewRows([]string{"datname", "datconnlimit"}).
35+
AddRow("postgres", 15))
3636

3737
mock.ExpectQuery(sanitizeQuery(pgDatabaseSizeQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"pg_database_size"}).
3838
AddRow(1024))
@@ -47,6 +47,7 @@ func TestPGDatabaseCollector(t *testing.T) {
4747
}()
4848

4949
expected := []MetricResult{
50+
{labels: labelMap{"datname": "postgres"}, value: 15, metricType: dto.MetricType_GAUGE},
5051
{labels: labelMap{"datname": "postgres"}, value: 1024, metricType: dto.MetricType_GAUGE},
5152
}
5253
convey.Convey("Metrics comparison", t, func() {
@@ -71,8 +72,8 @@ func TestPGDatabaseCollectorNullMetric(t *testing.T) {
7172

7273
inst := &instance{db: db}
7374

74-
mock.ExpectQuery(sanitizeQuery(pgDatabaseQuery)).WillReturnRows(sqlmock.NewRows([]string{"datname"}).
75-
AddRow("postgres"))
75+
mock.ExpectQuery(sanitizeQuery(pgDatabaseQuery)).WillReturnRows(sqlmock.NewRows([]string{"datname", "datconnlimit"}).
76+
AddRow("postgres", nil))
7677

7778
mock.ExpectQuery(sanitizeQuery(pgDatabaseSizeQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"pg_database_size"}).
7879
AddRow(nil))
@@ -88,6 +89,7 @@ func TestPGDatabaseCollectorNullMetric(t *testing.T) {
8889

8990
expected := []MetricResult{
9091
{labels: labelMap{"datname": "postgres"}, value: 0, metricType: dto.MetricType_GAUGE},
92+
{labels: labelMap{"datname": "postgres"}, value: 0, metricType: dto.MetricType_GAUGE},
9193
}
9294
convey.Convey("Metrics comparison", t, func() {
9395
for _, expect := range expected {

0 commit comments

Comments
 (0)