Skip to content

Commit 2fbf8d5

Browse files
authored
Merge pull request #2163 from KnutZuidema/feat/extra_redis_prometheus_stat_collector
feat(extra/redisprometheus): prometheus.Collector implementation for redis clients
2 parents 24d4a2d + 43d0cbb commit 2fbf8d5

File tree

4 files changed

+677
-0
lines changed

4 files changed

+677
-0
lines changed

extra/redisprometheus/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Prometheus Metric Collector
2+
3+
This package implements a [`prometheus.Collector`](https://pkg.go.dev/github.com/prometheus/client_golang@v1.12.2/prometheus#Collector)
4+
for collecting metrics about the connection pool used by the various redis clients.
5+
Supported clients are `redis.Client`, `redis.ClusterClient`, `redis.Ring` and `redis.UniversalClient`.
6+
7+
### Example
8+
9+
```go
10+
client := redis.NewClient(options)
11+
collector := redisprometheus.NewCollector(namespace, subsystem, client)
12+
prometheus.MustRegister(collector)
13+
```
14+
15+
### Metrics
16+
17+
| Name | Type | Description |
18+
|---------------------------|----------------|-----------------------------------------------------------------------------|
19+
| `pool_hit_total` | Counter metric | number of times a connection was found in the pool |
20+
| `pool_miss_total` | Counter metric | number of times a connection was not found in the pool |
21+
| `pool_timeout_total` | Counter metric | number of times a timeout occurred when getting a connection from the pool |
22+
| `pool_conn_total_current` | Gauge metric | current number of connections in the pool |
23+
| `pool_conn_idle_current` | Gauge metric | current number of idle connections in the pool |
24+
| `pool_conn_stale_total` | Counter metric | number of times a connection was removed from the pool because it was stale |
25+
26+

extra/redisprometheus/collector.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package redisprometheus
2+
3+
import (
4+
"github.com/prometheus/client_golang/prometheus"
5+
6+
"github.com/go-redis/redis/v9"
7+
)
8+
9+
// StatGetter provides a method to get pool statistics.
10+
type StatGetter interface {
11+
PoolStats() *redis.PoolStats
12+
}
13+
14+
// Collector collects statistics from a redis client.
15+
// It implements the prometheus.Collector interface.
16+
type Collector struct {
17+
getter StatGetter
18+
hitDesc *prometheus.Desc
19+
missDesc *prometheus.Desc
20+
timeoutDesc *prometheus.Desc
21+
totalDesc *prometheus.Desc
22+
idleDesc *prometheus.Desc
23+
staleDesc *prometheus.Desc
24+
}
25+
26+
var _ prometheus.Collector = (*Collector)(nil)
27+
28+
// NewCollector returns a new Collector based on the provided StatGetter.
29+
// The given namespace and subsystem are used to build the fully qualified metric name,
30+
// i.e. "{namespace}_{subsystem}_{metric}".
31+
// The provided metrics are:
32+
// * pool_hit_total
33+
// * pool_miss_total
34+
// * pool_timeout_total
35+
// * pool_conn_total_current
36+
// * pool_conn_idle_current
37+
// * pool_conn_stale_total
38+
func NewCollector(namespace, subsystem string, getter StatGetter) *Collector {
39+
return &Collector{
40+
getter: getter,
41+
hitDesc: prometheus.NewDesc(
42+
prometheus.BuildFQName(namespace, subsystem, "pool_hit_total"),
43+
"Number of times a connection was found in the pool",
44+
nil, nil,
45+
),
46+
missDesc: prometheus.NewDesc(
47+
prometheus.BuildFQName(namespace, subsystem, "pool_miss_total"),
48+
"Number of times a connection was not found in the pool",
49+
nil, nil,
50+
),
51+
timeoutDesc: prometheus.NewDesc(
52+
prometheus.BuildFQName(namespace, subsystem, "pool_timeout_total"),
53+
"Number of times a timeout occurred when looking for a connection in the pool",
54+
nil, nil,
55+
),
56+
totalDesc: prometheus.NewDesc(
57+
prometheus.BuildFQName(namespace, subsystem, "pool_conn_total_current"),
58+
"Current number of connections in the pool",
59+
nil, nil,
60+
),
61+
idleDesc: prometheus.NewDesc(
62+
prometheus.BuildFQName(namespace, subsystem, "pool_conn_idle_current"),
63+
"Current number of idle connections in the pool",
64+
nil, nil,
65+
),
66+
staleDesc: prometheus.NewDesc(
67+
prometheus.BuildFQName(namespace, subsystem, "pool_conn_stale_total"),
68+
"Number of times a connection was removed from the pool because it was stale",
69+
nil, nil,
70+
),
71+
}
72+
}
73+
74+
// Describe implements the prometheus.Collector interface.
75+
func (s *Collector) Describe(descs chan<- *prometheus.Desc) {
76+
descs <- s.hitDesc
77+
descs <- s.missDesc
78+
descs <- s.timeoutDesc
79+
descs <- s.totalDesc
80+
descs <- s.idleDesc
81+
descs <- s.staleDesc
82+
}
83+
84+
// Collect implements the prometheus.Collector interface.
85+
func (s *Collector) Collect(metrics chan<- prometheus.Metric) {
86+
stats := s.getter.PoolStats()
87+
metrics <- prometheus.MustNewConstMetric(
88+
s.hitDesc,
89+
prometheus.CounterValue,
90+
float64(stats.Hits),
91+
)
92+
metrics <- prometheus.MustNewConstMetric(
93+
s.missDesc,
94+
prometheus.CounterValue,
95+
float64(stats.Misses),
96+
)
97+
metrics <- prometheus.MustNewConstMetric(
98+
s.timeoutDesc,
99+
prometheus.CounterValue,
100+
float64(stats.Timeouts),
101+
)
102+
metrics <- prometheus.MustNewConstMetric(
103+
s.totalDesc,
104+
prometheus.GaugeValue,
105+
float64(stats.TotalConns),
106+
)
107+
metrics <- prometheus.MustNewConstMetric(
108+
s.idleDesc,
109+
prometheus.GaugeValue,
110+
float64(stats.IdleConns),
111+
)
112+
metrics <- prometheus.MustNewConstMetric(
113+
s.staleDesc,
114+
prometheus.CounterValue,
115+
float64(stats.StaleConns),
116+
)
117+
}

extra/redisprometheus/go.mod

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module github.com/go-redis/redis/extra/redisprometheus/v9
2+
3+
go 1.17
4+
5+
replace github.com/go-redis/redis/v9 => ../..
6+
7+
require (
8+
github.com/go-redis/redis/v9 v9.0.0-beta.1
9+
github.com/prometheus/client_golang v1.12.2
10+
)
11+
12+
require (
13+
github.com/beorn7/perks v1.0.1 // indirect
14+
github.com/cespare/xxhash/v2 v2.1.2 // indirect
15+
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
16+
github.com/golang/protobuf v1.5.2 // indirect
17+
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
18+
github.com/prometheus/client_model v0.2.0 // indirect
19+
github.com/prometheus/common v0.32.1 // indirect
20+
github.com/prometheus/procfs v0.7.3 // indirect
21+
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
22+
google.golang.org/protobuf v1.26.0 // indirect
23+
)

0 commit comments

Comments
 (0)