-
Notifications
You must be signed in to change notification settings - Fork 0
/
stats.go
133 lines (123 loc) · 4.92 KB
/
stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// Package gorm
// @Author: feymanlee@gmail.com
// @Description:
// @File: stat
// @Date: 2023/8/9 20:28
//
package gorm
import (
"log"
"time"
"github.com/feymanlee/monitorit"
"github.com/prometheus/client_golang/prometheus"
"gorm.io/gorm"
)
type DBStats struct {
options *Options
maxOpenConnections prometheus.Gauge // Maximum number of open connections to the database.
// Pool status
openConnections prometheus.Gauge // The number of established connections both in use and idle.
inUse prometheus.Gauge // The number of connections currently in use.
idle prometheus.Gauge // The number of idle connections.
// Counters
waitCount prometheus.Gauge // The total number of connections waited for.
waitDuration prometheus.Gauge // The total time blocked waiting for a new connection.
maxIdleClosed prometheus.Gauge // The total number of connections closed due to SetMaxIdleConns.
maxLifetimeClosed prometheus.Gauge // The total number of connections closed due to SetConnMaxLifetime.
maxIdleTimeClosed prometheus.Gauge // The total number of connections closed due to SetConnMaxIdleTime.
}
func NewStats(dbName string, opts ...Option) *DBStats {
statLabelNames := prometheus.Labels{
"db_name": dbName,
}
options := DefaultOptions()
options.Merge(opts...)
stats := &DBStats{
options: options,
maxOpenConnections: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_max_open_connections",
Help: "Maximum number of open connections to the database.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
openConnections: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_open_connections",
Help: "The number of established connections both in use and idle.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
inUse: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_in_use",
Help: "The number of connections currently in use.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
idle: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_idle",
Help: "The number of idle connections.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
waitCount: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_wait_count",
Help: "The total number of connections waited for.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
waitDuration: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_wait_duration",
Help: "The total time blocked waiting for a new connection.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
maxIdleClosed: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_max_idle_closed",
Help: "The total number of connections closed due to SetMaxIdleConns.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
maxLifetimeClosed: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_max_lifetime_closed",
Help: "The total number of connections closed due to SetConnMaxLifetime.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
maxIdleTimeClosed: monitorit.Register(prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: options.Namespace,
Subsystem: options.Subsystem,
Name: "dbstats_max_idletime_closed",
Help: "The total number of connections closed due to SetConnMaxIdleTime.",
ConstLabels: statLabelNames,
})).(prometheus.Gauge),
}
return stats
}
func (s *DBStats) StartStats(db *gorm.DB) {
go func() {
for range time.Tick(s.options.StatInterval) {
if dba, err := db.DB(); err == nil {
dbStats := dba.Stats()
s.maxOpenConnections.Set(float64(dbStats.MaxOpenConnections))
s.openConnections.Set(float64(dbStats.OpenConnections))
s.inUse.Set(float64(dbStats.InUse))
s.idle.Set(float64(dbStats.Idle))
s.waitCount.Set(float64(dbStats.WaitCount))
s.waitDuration.Set(float64(dbStats.WaitDuration))
s.maxIdleClosed.Set(float64(dbStats.MaxIdleClosed))
s.maxLifetimeClosed.Set(float64(dbStats.MaxLifetimeClosed))
s.maxIdleTimeClosed.Set(float64(dbStats.MaxIdleTimeClosed))
} else {
log.Printf("gorm:prometheus failed to collect db status, got error: %v", err)
}
}
}()
}