Skip to content

Commit 5507ace

Browse files
committed
Delay database connection until scrape
This no longer returns an error when creating a collector.instance when the database cannot be reached for the version query. This will resolve the entire postgresCollector not being registered for metrics collection when a database is not available. If the version query fails, the scrape will fail. Resolves prometheus-community#880 Signed-off-by: Joe Adams <[email protected]>
1 parent 04bb60c commit 5507ace

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

Diff for: collector/collector.go

+8
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ func (p PostgresCollector) Describe(ch chan<- *prometheus.Desc) {
166166
// Collect implements the prometheus.Collector interface.
167167
func (p PostgresCollector) Collect(ch chan<- prometheus.Metric) {
168168
ctx := context.TODO()
169+
170+
// Set up the database connection for the collector.
171+
err := p.instance.setup()
172+
if err != nil {
173+
level.Error(p.logger).Log("msg", "Error opening connection to database", "err", err)
174+
return
175+
}
176+
169177
wg := sync.WaitGroup{}
170178
wg.Add(len(p.Collectors))
171179
for name, c := range p.Collectors {

Diff for: collector/instance.go

+22-8
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,43 @@ import (
2222
)
2323

2424
type instance struct {
25+
dsn string
2526
db *sql.DB
2627
version semver.Version
2728
}
2829

2930
func newInstance(dsn string) (*instance, error) {
30-
i := &instance{}
31+
i := &instance{
32+
dsn: dsn,
33+
}
34+
35+
// "Create" a database handle to verify the DSN provided is valid.
36+
// Open is not guaranteed to create a connection.
3137
db, err := sql.Open("postgres", dsn)
3238
if err != nil {
3339
return nil, err
3440
}
41+
db.Close()
42+
43+
return i, nil
44+
}
45+
46+
func (i *instance) setup() error {
47+
db, err := sql.Open("postgres", i.dsn)
48+
if err != nil {
49+
return err
50+
}
3551
db.SetMaxOpenConns(1)
3652
db.SetMaxIdleConns(1)
3753
i.db = db
3854

39-
version, err := queryVersion(db)
55+
version, err := queryVersion(i.db)
4056
if err != nil {
41-
db.Close()
42-
return nil, err
57+
return fmt.Errorf("error querying postgresql version: %w", err)
58+
} else {
59+
i.version = version
4360
}
44-
45-
i.version = version
46-
47-
return i, nil
61+
return nil
4862
}
4963

5064
func (i *instance) getDB() *sql.DB {

Diff for: collector/probe.go

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"sync"
1919

2020
"github.com/go-kit/log"
21+
"github.com/go-kit/log/level"
2122
"github.com/prometheus-community/postgres_exporter/config"
2223
"github.com/prometheus/client_golang/prometheus"
2324
)
@@ -74,6 +75,13 @@ func (pc *ProbeCollector) Describe(ch chan<- *prometheus.Desc) {
7475
}
7576

7677
func (pc *ProbeCollector) Collect(ch chan<- prometheus.Metric) {
78+
// Set up the database connection for the collector.
79+
err := pc.instance.setup()
80+
if err != nil {
81+
level.Error(pc.logger).Log("msg", "Error opening connection to database", "err", err)
82+
return
83+
}
84+
7785
wg := sync.WaitGroup{}
7886
wg.Add(len(pc.collectors))
7987
for name, c := range pc.collectors {

0 commit comments

Comments
 (0)