Skip to content
This repository was archived by the owner on Nov 28, 2022. It is now read-only.

Commit 321a059

Browse files
committed
Add backends by user and client address metric
1 parent f6367f4 commit 321a059

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

gauges/backends.go

+46
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,52 @@ func (g *Gauges) BackendsByState() *prometheus.GaugeVec {
7171
return gauge
7272
}
7373

74+
type backendsByUserAndClientAddress struct {
75+
Total float64 `db:"total"`
76+
User string `db:"usename"`
77+
ClientAddr string `db:"client_addr"`
78+
}
79+
80+
// BackendsByUserAndClientAddress returns the number of backends currently connected
81+
// to database by user and client address
82+
func (g *Gauges) BackendsByUserAndClientAddress() *prometheus.GaugeVec {
83+
var gauge = prometheus.NewGaugeVec(
84+
prometheus.GaugeOpts{
85+
Name: "postgresql_backends_by_state_total",
86+
Help: "Number of backends currently connected to database by user and client address",
87+
ConstLabels: g.labels,
88+
},
89+
[]string{"user", "client_addr"},
90+
)
91+
92+
const backendsByUserAndClientAddressQuery = `
93+
SELECT
94+
COUNT(*) AS total,
95+
usename,
96+
COALESCE(client_addr, '127.0.0.1') AS client_addr
97+
FROM pg_stat_activity
98+
WHERE datname = current_database()
99+
GROUP BY usename, client_addr
100+
`
101+
102+
go func() {
103+
for {
104+
gauge.Reset()
105+
var backendsByUserAndClientAddress []backendsByUserAndClientAddress
106+
if err := g.query(backendsByUserAndClientAddressQuery, &backendsByUserAndClientAddress, emptyParams); err == nil {
107+
for _, row := range backendsByUserAndClientAddress {
108+
gauge.With(prometheus.Labels{
109+
"user": row.User,
110+
"client_addr": row.ClientAddr,
111+
}).Set(row.Total)
112+
}
113+
}
114+
time.Sleep(g.interval)
115+
}
116+
}()
117+
return gauge
118+
}
119+
74120
type backendsByWaitEventType struct {
75121
Total float64 `db:"total"`
76122
WaitEventType string `db:"wait_event_type"`

gauges/backends_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ func TestBackendsByState(t *testing.T) {
3838
assertNoErrs(t, gauges)
3939
}
4040

41+
func TestBackendsByUserAndClientAddress(t *testing.T) {
42+
var assert = assert.New(t)
43+
_, gauges, close := prepare(t)
44+
defer close()
45+
var metrics = evaluate(t, gauges.BackendsByUserAndClientAddress())
46+
assert.True(len(metrics) > 0)
47+
for _, m := range metrics {
48+
assertGreaterThan(t, 0, m)
49+
}
50+
assertNoErrs(t, gauges)
51+
}
52+
4153
// TODO: somehow set a waiting connections to proper test this
4254
func TestBackendsByWaitEventType(t *testing.T) {
4355
var assert = assert.New(t)

main.go

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func watch(db *sql.DB, reg prometheus.Registerer, name string) {
7878
reg.MustRegister(gauges.ConnectedBackends())
7979
reg.MustRegister(gauges.MaxBackends())
8080
reg.MustRegister(gauges.BackendsByState())
81+
reg.MustRegister(gauges.BackendsByUserAndClientAddress())
8182
reg.MustRegister(gauges.BackendsByWaitEventType())
8283
reg.MustRegister(gauges.RequestedCheckpoints())
8384
reg.MustRegister(gauges.ScheduledCheckpoints())

0 commit comments

Comments
 (0)