Skip to content

Commit 4a65b8c

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

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

collector/pg_database.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,22 @@ 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;"
58-
pgDatabaseSizeQuery = "SELECT pg_database_size($1)"
66+
pgDatabaseQuery = "SELECT pg_database.datname FROM pg_database;"
67+
pgDatabaseSizeQuery = "SELECT pg_database_size($1)"
68+
pgDatabaseConnectionLimitsQuery = "select pg_database.datconnlimit FROM pg_database WHERE pg_database.datname = $1"
5969
)
6070

61-
// Update implements Collector and exposes database size.
71+
// Update implements Collector and exposes database size and connection limits.
6272
// It is called by the Prometheus registry when collecting metrics.
6373
// The list of databases is retrieved from pg_database and filtered
6474
// by the excludeDatabase config parameter. The tradeoff here is that
@@ -114,6 +124,20 @@ func (c PGDatabaseCollector) Update(ctx context.Context, instance *instance, ch
114124
pgDatabaseSizeDesc,
115125
prometheus.GaugeValue, sizeMetric, datname,
116126
)
127+
128+
var connLimit sql.NullInt64
129+
err = db.QueryRowContext(ctx, pgDatabaseConnectionLimitsQuery, datname).Scan(&connLimit)
130+
if err != nil {
131+
return err
132+
}
133+
connLimitMetric := 0.0
134+
if connLimit.Valid {
135+
connLimitMetric = float64(connLimit.Int64)
136+
}
137+
ch <- prometheus.MustNewConstMetric(
138+
pgDatabaseConnectionLimitsDesc,
139+
prometheus.GaugeValue, connLimitMetric, datname,
140+
)
117141
}
118142
return rows.Err()
119143
}

collector/pg_database_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func TestPGDatabaseCollector(t *testing.T) {
3737
mock.ExpectQuery(sanitizeQuery(pgDatabaseSizeQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"pg_database_size"}).
3838
AddRow(1024))
3939

40+
mock.ExpectQuery(sanitizeQuery(pgDatabaseConnectionLimitsQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"datconnlimit"}).
41+
AddRow(15))
42+
4043
ch := make(chan prometheus.Metric)
4144
go func() {
4245
defer close(ch)
@@ -48,6 +51,7 @@ func TestPGDatabaseCollector(t *testing.T) {
4851

4952
expected := []MetricResult{
5053
{labels: labelMap{"datname": "postgres"}, value: 1024, metricType: dto.MetricType_GAUGE},
54+
{labels: labelMap{"datname": "postgres"}, value: 15, metricType: dto.MetricType_GAUGE},
5155
}
5256
convey.Convey("Metrics comparison", t, func() {
5357
for _, expect := range expected {
@@ -77,6 +81,9 @@ func TestPGDatabaseCollectorNullMetric(t *testing.T) {
7781
mock.ExpectQuery(sanitizeQuery(pgDatabaseSizeQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"pg_database_size"}).
7882
AddRow(nil))
7983

84+
mock.ExpectQuery(sanitizeQuery(pgDatabaseConnectionLimitsQuery)).WithArgs("postgres").WillReturnRows(sqlmock.NewRows([]string{"datconnlimit"}).
85+
AddRow(nil))
86+
8087
ch := make(chan prometheus.Metric)
8188
go func() {
8289
defer close(ch)
@@ -88,6 +95,7 @@ func TestPGDatabaseCollectorNullMetric(t *testing.T) {
8895

8996
expected := []MetricResult{
9097
{labels: labelMap{"datname": "postgres"}, value: 0, metricType: dto.MetricType_GAUGE},
98+
{labels: labelMap{"datname": "postgres"}, value: 0, metricType: dto.MetricType_GAUGE},
9199
}
92100
convey.Convey("Metrics comparison", t, func() {
93101
for _, expect := range expected {

0 commit comments

Comments
 (0)