Skip to content

Commit c20bd79

Browse files
committed
improve metrics structure
Signed-off-by: Mitsuo Heijo <[email protected]>
1 parent c0be446 commit c20bd79

File tree

4 files changed

+100
-154
lines changed

4 files changed

+100
-154
lines changed

prometheus/collectors/dbstats_collector.go

+14-49
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
//go:build go1.15
15-
// +build go1.15
16-
1714
package collectors
1815

1916
import (
@@ -38,100 +35,68 @@ type dbStatsCollector struct {
3835
maxLifetimeClosed *prometheus.Desc
3936
}
4037

41-
// DBStatsCollectorOpts defines the behavior of a db stats collector
42-
// created with NewDBStatsCollector.
43-
type DBStatsCollectorOpts struct {
44-
// DriverName holds the name of driver.
45-
// It will not used for empty strings.
46-
DriverName string
47-
}
48-
4938
// NewDBStatsCollector returns a collector that exports metrics about the given *sql.DB.
5039
// See https://golang.org/pkg/database/sql/#DBStats for more information on stats.
51-
func NewDBStatsCollector(db *sql.DB, opts DBStatsCollectorOpts) prometheus.Collector {
52-
var fqName func(name string) string
53-
if opts.DriverName == "" {
54-
fqName = func(name string) string {
55-
return "go_db_stats_" + name
56-
}
57-
} else {
58-
fqName = func(name string) string {
59-
return "go_" + opts.DriverName + "_db_stats_" + name
60-
}
40+
func NewDBStatsCollector(db *sql.DB, dbName string) prometheus.Collector {
41+
fqName := func(name string) string {
42+
return "go_sql_" + name
6143
}
6244
return &dbStatsCollector{
6345
db: db,
6446
maxOpenConnections: prometheus.NewDesc(
6547
fqName("max_open_connections"),
6648
"Maximum number of open connections to the database.",
67-
nil, nil,
49+
nil, prometheus.Labels{"db_name": dbName},
6850
),
6951
openConnections: prometheus.NewDesc(
7052
fqName("open_connections"),
7153
"The number of established connections both in use and idle.",
72-
nil, nil,
54+
nil, prometheus.Labels{"db_name": dbName},
7355
),
7456
inUseConnections: prometheus.NewDesc(
7557
fqName("in_use_connections"),
7658
"The number of connections currently in use.",
77-
nil, nil,
59+
nil, prometheus.Labels{"db_name": dbName},
7860
),
7961
idleConnections: prometheus.NewDesc(
8062
fqName("idle_connections"),
8163
"The number of idle connections.",
82-
nil, nil,
64+
nil, prometheus.Labels{"db_name": dbName},
8365
),
8466
waitCount: prometheus.NewDesc(
8567
fqName("wait_count_total"),
8668
"The total number of connections waited for.",
87-
nil, nil,
69+
nil, prometheus.Labels{"db_name": dbName},
8870
),
8971
waitDuration: prometheus.NewDesc(
9072
fqName("wait_duration_seconds_total"),
9173
"The total time blocked waiting for a new connection.",
92-
nil, nil,
74+
nil, prometheus.Labels{"db_name": dbName},
9375
),
9476
maxIdleClosed: prometheus.NewDesc(
9577
fqName("max_idle_closed_total"),
9678
"The total number of connections closed due to SetMaxIdleConns.",
97-
nil, nil,
79+
nil, prometheus.Labels{"db_name": dbName},
9880
),
9981
maxIdleTimeClosed: prometheus.NewDesc(
10082
fqName("max_idle_time_closed_total"),
10183
"The total number of connections closed due to SetConnMaxIdleTime.",
102-
nil, nil,
84+
nil, prometheus.Labels{"db_name": dbName},
10385
),
10486
maxLifetimeClosed: prometheus.NewDesc(
10587
fqName("max_lifetime_closed_total"),
10688
"The total number of connections closed due to SetConnMaxLifetime.",
107-
nil, nil,
89+
nil, prometheus.Labels{"db_name": dbName},
10890
),
10991
}
11092
}
11193

11294
// Describe implements Collector.
11395
func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) {
114-
ch <- c.maxOpenConnections
115-
ch <- c.openConnections
116-
ch <- c.inUseConnections
117-
ch <- c.idleConnections
118-
ch <- c.waitCount
119-
ch <- c.waitDuration
120-
ch <- c.maxIdleClosed
121-
ch <- c.maxIdleTimeClosed
122-
ch <- c.maxLifetimeClosed
96+
c.describe(ch)
12397
}
12498

12599
// Collect implements Collector.
126100
func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) {
127-
stats := c.db.Stats()
128-
ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections))
129-
ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections))
130-
ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse))
131-
ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle))
132-
ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount))
133-
ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds())
134-
ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed))
135-
ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed))
136-
ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed))
101+
c.collect(ch)
137102
}

prometheus/collectors/dbstats_collector_go115.go

+6-92
Original file line numberDiff line numberDiff line change
@@ -11,112 +11,25 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
//go:build !go1.15
15-
// +build !go1.15
14+
// +build go1.15
1615

1716
package collectors
1817

19-
import (
20-
"database/sql"
18+
import "github.com/prometheus/client_golang/prometheus"
2119

22-
"github.com/prometheus/client_golang/prometheus"
23-
)
24-
25-
type dbStatsCollector struct {
26-
db *sql.DB
27-
28-
maxOpenConnections *prometheus.Desc
29-
30-
openConnections *prometheus.Desc
31-
inUseConnections *prometheus.Desc
32-
idleConnections *prometheus.Desc
33-
34-
waitCount *prometheus.Desc
35-
waitDuration *prometheus.Desc
36-
maxIdleClosed *prometheus.Desc
37-
maxLifetimeClosed *prometheus.Desc
38-
}
39-
40-
// DBStatsCollectorOpts defines the behavior of a db stats collector
41-
// created with NewDBStatsCollector.
42-
type DBStatsCollectorOpts struct {
43-
// DriverName holds the name of driver.
44-
// It will not used for empty strings.
45-
DriverName string
46-
}
47-
48-
// NewDBStatsCollector returns a collector that exports metrics about the given *sql.DB.
49-
// See https://golang.org/pkg/database/sql/#DBStats for more information on stats.
50-
func NewDBStatsCollector(db *sql.DB, opts DBStatsCollectorOpts) prometheus.Collector {
51-
var fqName func(name string) string
52-
if opts.DriverName == "" {
53-
fqName = func(name string) string {
54-
return "go_db_stats_" + name
55-
}
56-
} else {
57-
fqName = func(name string) string {
58-
return "go_" + opts.DriverName + "_db_stats_" + name
59-
}
60-
}
61-
return &dbStatsCollector{
62-
db: db,
63-
maxOpenConnections: prometheus.NewDesc(
64-
fqName("max_open_connections"),
65-
"Maximum number of open connections to the database.",
66-
nil, nil,
67-
),
68-
openConnections: prometheus.NewDesc(
69-
fqName("open_connections"),
70-
"The number of established connections both in use and idle.",
71-
nil, nil,
72-
),
73-
inUseConnections: prometheus.NewDesc(
74-
fqName("in_use_connections"),
75-
"The number of connections currently in use.",
76-
nil, nil,
77-
),
78-
idleConnections: prometheus.NewDesc(
79-
fqName("idle_connections"),
80-
"The number of idle connections.",
81-
nil, nil,
82-
),
83-
waitCount: prometheus.NewDesc(
84-
fqName("wait_count_total"),
85-
"The total number of connections waited for.",
86-
nil, nil,
87-
),
88-
waitDuration: prometheus.NewDesc(
89-
fqName("wait_duration_seconds_total"),
90-
"The total time blocked waiting for a new connection.",
91-
nil, nil,
92-
),
93-
maxIdleClosed: prometheus.NewDesc(
94-
fqName("max_idle_closed_total"),
95-
"The total number of connections closed due to SetMaxIdleConns.",
96-
nil, nil,
97-
),
98-
maxLifetimeClosed: prometheus.NewDesc(
99-
fqName("max_lifetime_closed_total"),
100-
"The total number of connections closed due to SetConnMaxLifetime.",
101-
nil, nil,
102-
),
103-
}
104-
}
105-
106-
// Describe implements Collector.
107-
func (c *dbStatsCollector) Describe(ch chan<- *prometheus.Desc) {
20+
func (c *dbStatsCollector) describe(ch chan<- *prometheus.Desc) {
10821
ch <- c.maxOpenConnections
10922
ch <- c.openConnections
11023
ch <- c.inUseConnections
11124
ch <- c.idleConnections
11225
ch <- c.waitCount
11326
ch <- c.waitDuration
11427
ch <- c.maxIdleClosed
28+
ch <- c.maxIdleTimeClosed
11529
ch <- c.maxLifetimeClosed
11630
}
11731

118-
// Collect implements Collector.
119-
func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) {
32+
func (c *dbStatsCollector) collect(ch chan<- prometheus.Metric) {
12033
stats := c.db.Stats()
12134
ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections))
12235
ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections))
@@ -125,5 +38,6 @@ func (c *dbStatsCollector) Collect(ch chan<- prometheus.Metric) {
12538
ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount))
12639
ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds())
12740
ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed))
41+
ch <- prometheus.MustNewConstMetric(c.maxIdleTimeClosed, prometheus.CounterValue, float64(stats.MaxIdleTimeClosed))
12842
ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed))
12943
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2021 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// +build !go1.15
15+
16+
package collectors
17+
18+
import "github.com/prometheus/client_golang/prometheus"
19+
20+
func (c *dbStatsCollector) describe(ch chan<- *prometheus.Desc) {
21+
ch <- c.maxOpenConnections
22+
ch <- c.openConnections
23+
ch <- c.inUseConnections
24+
ch <- c.idleConnections
25+
ch <- c.waitCount
26+
ch <- c.waitDuration
27+
ch <- c.maxIdleClosed
28+
ch <- c.maxLifetimeClosed
29+
}
30+
31+
func (c *dbStatsCollector) collect(ch chan<- prometheus.Metric) {
32+
stats := c.db.Stats()
33+
ch <- prometheus.MustNewConstMetric(c.maxOpenConnections, prometheus.GaugeValue, float64(stats.MaxOpenConnections))
34+
ch <- prometheus.MustNewConstMetric(c.openConnections, prometheus.GaugeValue, float64(stats.OpenConnections))
35+
ch <- prometheus.MustNewConstMetric(c.inUseConnections, prometheus.GaugeValue, float64(stats.InUse))
36+
ch <- prometheus.MustNewConstMetric(c.idleConnections, prometheus.GaugeValue, float64(stats.Idle))
37+
ch <- prometheus.MustNewConstMetric(c.waitCount, prometheus.CounterValue, float64(stats.WaitCount))
38+
ch <- prometheus.MustNewConstMetric(c.waitDuration, prometheus.CounterValue, stats.WaitDuration.Seconds())
39+
ch <- prometheus.MustNewConstMetric(c.maxIdleClosed, prometheus.CounterValue, float64(stats.MaxIdleClosed))
40+
ch <- prometheus.MustNewConstMetric(c.maxLifetimeClosed, prometheus.CounterValue, float64(stats.MaxLifetimeClosed))
41+
}

prometheus/collectors/dbstats_collector_test.go

+39-13
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@ import (
2323

2424
func TestDBStatsCollector(t *testing.T) {
2525
reg := prometheus.NewRegistry()
26-
db := new(sql.DB)
27-
opts := DBStatsCollectorOpts{DriverName: "test"}
28-
if err := reg.Register(NewDBStatsCollector(db, opts)); err != nil {
29-
t.Fatal(err)
26+
{
27+
db := new(sql.DB)
28+
if err := reg.Register(NewDBStatsCollector(db, "db_A")); err != nil {
29+
t.Fatal(err)
30+
}
31+
}
32+
{
33+
db := new(sql.DB)
34+
if err := reg.Register(NewDBStatsCollector(db, "db_B")); err != nil {
35+
t.Fatal(err)
36+
}
3037
}
3138

3239
mfs, err := reg.Gather()
@@ -35,17 +42,17 @@ func TestDBStatsCollector(t *testing.T) {
3542
}
3643

3744
names := []string{
38-
"go_test_db_stats_max_open_connections",
39-
"go_test_db_stats_open_connections",
40-
"go_test_db_stats_in_use_connections",
41-
"go_test_db_stats_idle_connections",
42-
"go_test_db_stats_wait_count_total",
43-
"go_test_db_stats_wait_duration_seconds_total",
44-
"go_test_db_stats_max_idle_closed_total",
45-
"go_test_db_stats_max_lifetime_closed_total",
45+
"go_sql_max_open_connections",
46+
"go_sql_open_connections",
47+
"go_sql_in_use_connections",
48+
"go_sql_idle_connections",
49+
"go_sql_wait_count_total",
50+
"go_sql_wait_duration_seconds_total",
51+
"go_sql_max_idle_closed_total",
52+
"go_sql_max_lifetime_closed_total",
4653
}
4754
if runtime.Version() >= "go1.15" {
48-
names = append(names, "go_test_db_stats_max_idle_time_closed_total")
55+
names = append(names, "go_sql_max_idle_time_closed_total")
4956
}
5057
type result struct {
5158
found bool
@@ -55,6 +62,25 @@ func TestDBStatsCollector(t *testing.T) {
5562
results[name] = result{found: false}
5663
}
5764
for _, mf := range mfs {
65+
m := mf.GetMetric()
66+
if len(m) != 2 {
67+
t.Errorf("expected 2 metrics bug got %d", len(m))
68+
}
69+
labelA := m[0].GetLabel()[0]
70+
if name := labelA.GetName(); name != "db_name" {
71+
t.Errorf("expected to get label \"db_name\" but got %s", name)
72+
}
73+
if value := labelA.GetValue(); value != "db_A" {
74+
t.Errorf("expected to get value \"db_A\" but got %s", value)
75+
}
76+
labelB := m[1].GetLabel()[0]
77+
if name := labelB.GetName(); name != "db_name" {
78+
t.Errorf("expected to get label \"db_name\" but got %s", name)
79+
}
80+
if value := labelB.GetValue(); value != "db_B" {
81+
t.Errorf("expected to get value \"db_B\" but got %s", value)
82+
}
83+
5884
for _, name := range names {
5985
if name == mf.GetName() {
6086
results[name] = result{found: true}

0 commit comments

Comments
 (0)