master
go 247 lines 7.08 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package pgbouncer
4
5 import (
6 "fmt"
7 "strings"
8
9 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
10 )
11
12 const (
13 prioClientConnectionsUtilization = collectorapi.Priority + iota
14 prioDBClientConnections
15 prioDBServerConnections
16 prioDBServerConnectionsUtilization
17 prioDBClientsWaitTime
18 prioDBClientsWaitMaxTime
19 prioDBTransactions
20 prioDBTransactionsTime
21 prioDBTransactionsAvgTime
22 prioDBQueries
23 prioDBQueriesTime
24 prioDBQueryAvgTime
25 prioDBNetworkIO
26 )
27
28 var (
29 globalCharts = collectorapi.Charts{
30 clientConnectionsUtilization.Copy(),
31 }
32
33 clientConnectionsUtilization = collectorapi.Chart{
34 ID: "client_connections_utilization",
35 Title: "Client connections utilization",
36 Units: "percentage",
37 Fam: "client connections",
38 Ctx: "pgbouncer.client_connections_utilization",
39 Priority: prioClientConnectionsUtilization,
40 Dims: collectorapi.Dims{
41 {ID: "cl_conns_utilization", Name: "used"},
42 },
43 }
44 )
45
46 var (
47 dbChartsTmpl = collectorapi.Charts{
48 dbClientConnectionsTmpl.Copy(),
49
50 dbServerConnectionsUtilizationTmpl.Copy(),
51 dbServerConnectionsTmpl.Copy(),
52
53 dbClientsWaitTimeChartTmpl.Copy(),
54 dbClientMaxWaitTimeChartTmpl.Copy(),
55
56 dbTransactionsChartTmpl.Copy(),
57 dbTransactionsTimeChartTmpl.Copy(),
58 dbTransactionAvgTimeChartTmpl.Copy(),
59
60 dbQueriesChartTmpl.Copy(),
61 dbQueriesTimeChartTmpl.Copy(),
62 dbQueryAvgTimeChartTmpl.Copy(),
63
64 dbNetworkIOChartTmpl.Copy(),
65 }
66
67 dbClientConnectionsTmpl = collectorapi.Chart{
68 ID: "db_%s_client_connections",
69 Title: "Database client connections",
70 Units: "connections",
71 Fam: "client connections",
72 Ctx: "pgbouncer.db_client_connections",
73 Priority: prioDBClientConnections,
74 Type: collectorapi.Stacked,
75 Dims: collectorapi.Dims{
76 {ID: "db_%s_cl_active", Name: "active"},
77 {ID: "db_%s_cl_waiting", Name: "waiting"},
78 {ID: "db_%s_cl_cancel_req", Name: "cancel_req"},
79 },
80 }
81
82 dbServerConnectionsTmpl = collectorapi.Chart{
83 ID: "db_%s_server_connections",
84 Title: "Database server connections",
85 Units: "connections",
86 Fam: "server connections",
87 Ctx: "pgbouncer.db_server_connections",
88 Priority: prioDBServerConnections,
89 Type: collectorapi.Stacked,
90 Dims: collectorapi.Dims{
91 {ID: "db_%s_sv_active", Name: "active"},
92 {ID: "db_%s_sv_idle", Name: "idle"},
93 {ID: "db_%s_sv_used", Name: "used"},
94 {ID: "db_%s_sv_tested", Name: "tested"},
95 {ID: "db_%s_sv_login", Name: "login"},
96 },
97 }
98
99 dbServerConnectionsUtilizationTmpl = collectorapi.Chart{
100 ID: "db_%s_server_connections_utilization",
101 Title: "Database server connections utilization",
102 Units: "percentage",
103 Fam: "server connections limit",
104 Ctx: "pgbouncer.db_server_connections_utilization",
105 Priority: prioDBServerConnectionsUtilization,
106 Dims: collectorapi.Dims{
107 {ID: "db_%s_sv_conns_utilization", Name: "used"},
108 },
109 }
110
111 dbClientsWaitTimeChartTmpl = collectorapi.Chart{
112 ID: "db_%s_clients_wait_time",
113 Title: "Database clients wait time",
114 Units: "seconds",
115 Fam: "clients wait time",
116 Ctx: "pgbouncer.db_clients_wait_time",
117 Priority: prioDBClientsWaitTime,
118 Dims: collectorapi.Dims{
119 {ID: "db_%s_total_wait_time", Name: "time", Algo: collectorapi.Incremental, Div: 1e6},
120 },
121 }
122 dbClientMaxWaitTimeChartTmpl = collectorapi.Chart{
123 ID: "db_%s_client_max_wait_time",
124 Title: "Database client max wait time",
125 Units: "seconds",
126 Fam: "client max wait time",
127 Ctx: "pgbouncer.db_client_max_wait_time",
128 Priority: prioDBClientsWaitMaxTime,
129 Dims: collectorapi.Dims{
130 {ID: "db_%s_maxwait", Name: "time", Div: 1e6},
131 },
132 }
133
134 dbTransactionsChartTmpl = collectorapi.Chart{
135 ID: "db_%s_transactions",
136 Title: "Database pooled SQL transactions",
137 Units: "transactions/s",
138 Fam: "transactions",
139 Ctx: "pgbouncer.db_transactions",
140 Priority: prioDBTransactions,
141 Dims: collectorapi.Dims{
142 {ID: "db_%s_total_xact_count", Name: "transactions", Algo: collectorapi.Incremental},
143 },
144 }
145 dbTransactionsTimeChartTmpl = collectorapi.Chart{
146 ID: "db_%s_transactions_time",
147 Title: "Database transactions time",
148 Units: "seconds",
149 Fam: "transactions time",
150 Ctx: "pgbouncer.db_transactions_time",
151 Priority: prioDBTransactionsTime,
152 Dims: collectorapi.Dims{
153 {ID: "db_%s_total_xact_time", Name: "time", Algo: collectorapi.Incremental, Div: 1e6},
154 },
155 }
156 dbTransactionAvgTimeChartTmpl = collectorapi.Chart{
157 ID: "db_%s_transactions_average_time",
158 Title: "Database transaction average time",
159 Units: "seconds",
160 Fam: "transaction avg time",
161 Ctx: "pgbouncer.db_transaction_avg_time",
162 Priority: prioDBTransactionsAvgTime,
163 Dims: collectorapi.Dims{
164 {ID: "db_%s_avg_xact_time", Name: "time", Algo: collectorapi.Incremental, Div: 1e6},
165 },
166 }
167
168 dbQueriesChartTmpl = collectorapi.Chart{
169 ID: "db_%s_queries",
170 Title: "Database pooled SQL queries",
171 Units: "queries/s",
172 Fam: "queries",
173 Ctx: "pgbouncer.db_queries",
174 Priority: prioDBQueries,
175 Dims: collectorapi.Dims{
176 {ID: "db_%s_total_query_count", Name: "queries", Algo: collectorapi.Incremental},
177 },
178 }
179 dbQueriesTimeChartTmpl = collectorapi.Chart{
180 ID: "db_%s_queries_time",
181 Title: "Database queries time",
182 Units: "seconds",
183 Fam: "queries time",
184 Ctx: "pgbouncer.db_queries_time",
185 Priority: prioDBQueriesTime,
186 Dims: collectorapi.Dims{
187 {ID: "db_%s_total_query_time", Name: "time", Algo: collectorapi.Incremental, Div: 1e6},
188 },
189 }
190 dbQueryAvgTimeChartTmpl = collectorapi.Chart{
191 ID: "db_%s_query_average_time",
192 Title: "Database query average time",
193 Units: "seconds",
194 Fam: "query avg time",
195 Ctx: "pgbouncer.db_query_avg_time",
196 Priority: prioDBQueryAvgTime,
197 Dims: collectorapi.Dims{
198 {ID: "db_%s_avg_query_time", Name: "time", Algo: collectorapi.Incremental, Div: 1e6},
199 },
200 }
201
202 dbNetworkIOChartTmpl = collectorapi.Chart{
203 ID: "db_%s_network_io",
204 Title: "Database traffic",
205 Units: "B/s",
206 Fam: "traffic",
207 Ctx: "pgbouncer.db_network_io",
208 Priority: prioDBNetworkIO,
209 Type: collectorapi.Area,
210 Dims: collectorapi.Dims{
211 {ID: "db_%s_total_received", Name: "received", Algo: collectorapi.Incremental},
212 {ID: "db_%s_total_sent", Name: "sent", Algo: collectorapi.Incremental, Mul: -1},
213 },
214 }
215 )
216
217 func newDatabaseCharts(dbname, pgDBName string) *collectorapi.Charts {
218 charts := dbChartsTmpl.Copy()
219 for _, c := range *charts {
220 c.ID = fmt.Sprintf(c.ID, dbname)
221 c.Labels = []collectorapi.Label{
222 {Key: "database", Value: dbname},
223 {Key: "postgres_database", Value: pgDBName},
224 }
225 for _, d := range c.Dims {
226 d.ID = fmt.Sprintf(d.ID, dbname)
227 }
228 }
229 return charts
230 }
231
232 func (c *Collector) addNewDatabaseCharts(dbname, pgDBName string) {
233 charts := newDatabaseCharts(dbname, pgDBName)
234 if err := c.Charts().Add(*charts...); err != nil {
235 c.Warning(err)
236 }
237 }
238
239 func (c *Collector) removeDatabaseCharts(dbname string) {
240 prefix := fmt.Sprintf("db_%s_", dbname)
241 for _, c := range *c.Charts() {
242 if strings.HasPrefix(c.ID, prefix) {
243 c.MarkRemove()
244 c.MarkNotCreated()
245 }
246 }
247 }