Skip to content

Commit 03527dc

Browse files
authored
Merge pull request #214 from prometheus-community/superq/refactor_connection
Make connections per-scrape
2 parents 7972027 + b5a1200 commit 03527dc

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

collector.go

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import (
1919
"fmt"
2020
"log/slog"
2121
"math"
22-
"os"
2322
"strconv"
2423
"time"
2524
"unicode/utf8"
2625

27-
_ "github.com/lib/pq"
26+
"github.com/lib/pq"
27+
2828
"github.com/prometheus/client_golang/prometheus"
2929
)
3030

@@ -137,17 +137,15 @@ var (
137137
)
138138

139139
func NewExporter(connectionString string, namespace string, logger *slog.Logger) *Exporter {
140-
141-
db, err := getDB(connectionString)
142-
140+
conn, err := pq.NewConnector(connectionString)
143141
if err != nil {
144-
logger.Error("error setting up DB connection", "err", err.Error())
145-
os.Exit(1)
142+
logger.Error("failed to create connector", "error", err)
143+
return nil
146144
}
147145

148146
return &Exporter{
147+
conn: conn,
149148
metricMap: makeDescMap(metricMaps, namespace, logger),
150-
db: db,
151149
logger: logger,
152150
}
153151
}
@@ -335,10 +333,10 @@ func queryNamespaceMapping(ch chan<- prometheus.Metric, db *sql.DB, namespace st
335333
return nonfatalErrors, nil
336334
}
337335

338-
func getDB(conn string) (*sql.DB, error) {
339-
db, err := sql.Open("postgres", conn)
340-
if err != nil {
341-
return nil, err
336+
func getDB(conn *pq.Connector) (*sql.DB, error) {
337+
db := sql.OpenDB(conn)
338+
if db == nil {
339+
return nil, errors.New("error opening DB")
342340
}
343341
rows, err := db.Query("SHOW STATS")
344342
if err != nil {
@@ -472,36 +470,47 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
472470

473471
// Collect implements prometheus.Collector.
474472
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
475-
e.logger.Info("Starting scrape")
473+
e.logger.Debug("Starting scrape")
476474

477475
var up = 1.0
478476

479-
err := queryVersion(ch, e.db)
477+
defer func() {
478+
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, up)
479+
}()
480+
481+
db, err := getDB(e.conn)
482+
if err != nil {
483+
e.logger.Warn("error setting up DB connection", "err", err.Error())
484+
up = 0
485+
return
486+
}
487+
defer db.Close()
488+
489+
err = queryVersion(ch, db)
480490
if err != nil {
481-
e.logger.Error("error getting version", "err", err.Error())
491+
e.logger.Warn("error getting version", "err", err.Error())
482492
up = 0
483493
}
484494

485-
if err = queryShowLists(ch, e.db, e.logger); err != nil {
486-
e.logger.Error("error getting SHOW LISTS", "err", err.Error())
495+
if err = queryShowLists(ch, db, e.logger); err != nil {
496+
e.logger.Warn("error getting SHOW LISTS", "err", err.Error())
487497
up = 0
488498
}
489499

490-
if err = queryShowConfig(ch, e.db, e.logger); err != nil {
491-
e.logger.Error("error getting SHOW CONFIG", "err", err.Error())
500+
if err = queryShowConfig(ch, db, e.logger); err != nil {
501+
e.logger.Warn("error getting SHOW CONFIG", "err", err.Error())
492502
up = 0
493503
}
494504

495-
errMap := queryNamespaceMappings(ch, e.db, e.metricMap, e.logger)
505+
errMap := queryNamespaceMappings(ch, db, e.metricMap, e.logger)
496506
if len(errMap) > 0 {
497-
e.logger.Error("error querying namespace mappings", "err", errMap)
507+
e.logger.Warn("error querying namespace mappings", "err", errMap)
498508
up = 0
499509
}
500510

501511
if len(errMap) == len(e.metricMap) {
502512
up = 0
503513
}
504-
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, up)
505514
}
506515

507516
// Turn the MetricMap column mapping into a prometheus descriptor mapping.

pgbouncer_exporter.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,18 @@ func main() {
5858

5959
logger := promslog.New(promslogConfig)
6060

61+
logger.Info("Starting pgbouncer_exporter", "version", version.Info())
62+
logger.Info("Build context", "build_context", version.BuildContext())
63+
6164
connectionString := *connectionStringPointer
6265
exporter := NewExporter(connectionString, namespace, logger)
66+
if exporter == nil {
67+
logger.Error("Failed to create exporter")
68+
os.Exit(1)
69+
}
6370
prometheus.MustRegister(exporter)
6471
prometheus.MustRegister(versioncollector.NewCollector("pgbouncer_exporter"))
6572

66-
logger.Info("Starting pgbouncer_exporter", "version", version.Info())
67-
logger.Info("Build context", "build_context", version.BuildContext())
68-
6973
if *pidFilePath != "" {
7074
procExporter := collectors.NewProcessCollector(
7175
collectors.ProcessCollectorOpts{

struct.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ package main
1515

1616
// Elasticsearch Node Stats Structs
1717
import (
18-
"database/sql"
1918
"fmt"
2019
"log/slog"
2120

21+
"github.com/lib/pq"
22+
2223
"github.com/prometheus/client_golang/prometheus"
2324
)
2425

@@ -102,9 +103,7 @@ type ColumnMapping struct {
102103
// Exporter collects PgBouncer stats from the given server and exports
103104
// them using the prometheus metrics package.
104105
type Exporter struct {
106+
conn *pq.Connector
105107
metricMap map[string]MetricMapNamespace
106-
107-
db *sql.DB
108-
109-
logger *slog.Logger
108+
logger *slog.Logger
110109
}

0 commit comments

Comments
 (0)