@@ -71,6 +71,52 @@ func (g *Gauges) BackendsByState() *prometheus.GaugeVec {
71
71
return gauge
72
72
}
73
73
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
+
74
120
type backendsByWaitEventType struct {
75
121
Total float64 `db:"total"`
76
122
WaitEventType string `db:"wait_event_type"`
0 commit comments