master
c 314 lines 12.4 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define PULSE_INTERNALS 1
4 #include "pulse-sqlite3.h"
5
6 static struct sqlite3_statistics {
7 bool enabled;
8
9 PAD64(uint64_t) sqlite3_queries_made;
10 PAD64(uint64_t) sqlite3_queries_ok;
11 PAD64(uint64_t) sqlite3_queries_failed;
12 PAD64(uint64_t) sqlite3_queries_failed_busy;
13 PAD64(uint64_t) sqlite3_queries_failed_locked;
14 PAD64(uint64_t) sqlite3_rows;
15 PAD64(uint64_t) sqlite3_metadata_cache_hit;
16 PAD64(uint64_t) sqlite3_context_cache_hit;
17 PAD64(uint64_t) sqlite3_metadata_cache_miss;
18 PAD64(uint64_t) sqlite3_context_cache_miss;
19 PAD64(uint64_t) sqlite3_metadata_cache_spill;
20 PAD64(uint64_t) sqlite3_context_cache_spill;
21 PAD64(uint64_t) sqlite3_metadata_cache_write;
22 PAD64(uint64_t) sqlite3_context_cache_write;
23 } sqlite3_statistics = { 0 };
24
25 void pulse_sqlite3_query_completed(bool success, bool busy, bool locked) {
26 if(!sqlite3_statistics.enabled) return;
27
28 __atomic_fetch_add(&sqlite3_statistics.sqlite3_queries_made, 1, __ATOMIC_RELAXED);
29
30 if(success) {
31 __atomic_fetch_add(&sqlite3_statistics.sqlite3_queries_ok, 1, __ATOMIC_RELAXED);
32 }
33 else {
34 __atomic_fetch_add(&sqlite3_statistics.sqlite3_queries_failed, 1, __ATOMIC_RELAXED);
35
36 if(busy)
37 __atomic_fetch_add(&sqlite3_statistics.sqlite3_queries_failed_busy, 1, __ATOMIC_RELAXED);
38
39 if(locked)
40 __atomic_fetch_add(&sqlite3_statistics.sqlite3_queries_failed_locked, 1, __ATOMIC_RELAXED);
41 }
42 }
43
44 void pulse_sqlite3_row_completed(void) {
45 if(!sqlite3_statistics.enabled) return;
46
47 __atomic_fetch_add(&sqlite3_statistics.sqlite3_rows, 1, __ATOMIC_RELAXED);
48 }
49
50 static inline void sqlite3_statistics_copy(struct sqlite3_statistics *gs) {
51 static usec_t last_run = 0;
52
53 gs->sqlite3_queries_made = __atomic_load_n(&sqlite3_statistics.sqlite3_queries_made, __ATOMIC_RELAXED);
54 gs->sqlite3_queries_ok = __atomic_load_n(&sqlite3_statistics.sqlite3_queries_ok, __ATOMIC_RELAXED);
55 gs->sqlite3_queries_failed = __atomic_load_n(&sqlite3_statistics.sqlite3_queries_failed, __ATOMIC_RELAXED);
56 gs->sqlite3_queries_failed_busy = __atomic_load_n(&sqlite3_statistics.sqlite3_queries_failed_busy, __ATOMIC_RELAXED);
57 gs->sqlite3_queries_failed_locked = __atomic_load_n(&sqlite3_statistics.sqlite3_queries_failed_locked, __ATOMIC_RELAXED);
58 gs->sqlite3_rows = __atomic_load_n(&sqlite3_statistics.sqlite3_rows, __ATOMIC_RELAXED);
59
60 usec_t timeout = nd_profile.update_every * USEC_PER_SEC + nd_profile.update_every * USEC_PER_SEC / 3;
61 usec_t now = now_monotonic_usec();
62 if(!last_run)
63 last_run = now;
64 usec_t delta = now - last_run;
65 bool query_sqlite3 = delta < timeout;
66
67 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
68 gs->sqlite3_metadata_cache_hit = (uint64_t) sql_metadata_cache_stats(SQLITE_DBSTATUS_CACHE_HIT);
69 else {
70 gs->sqlite3_metadata_cache_hit = UINT64_MAX;
71 query_sqlite3 = false;
72 }
73
74 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
75 gs->sqlite3_context_cache_hit = (uint64_t) sql_context_cache_stats(SQLITE_DBSTATUS_CACHE_HIT);
76 else {
77 gs->sqlite3_context_cache_hit = UINT64_MAX;
78 query_sqlite3 = false;
79 }
80
81 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
82 gs->sqlite3_metadata_cache_miss = (uint64_t) sql_metadata_cache_stats(SQLITE_DBSTATUS_CACHE_MISS);
83 else {
84 gs->sqlite3_metadata_cache_miss = UINT64_MAX;
85 query_sqlite3 = false;
86 }
87
88 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
89 gs->sqlite3_context_cache_miss = (uint64_t) sql_context_cache_stats(SQLITE_DBSTATUS_CACHE_MISS);
90 else {
91 gs->sqlite3_context_cache_miss = UINT64_MAX;
92 query_sqlite3 = false;
93 }
94
95 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
96 gs->sqlite3_metadata_cache_spill = (uint64_t) sql_metadata_cache_stats(SQLITE_DBSTATUS_CACHE_SPILL);
97 else {
98 gs->sqlite3_metadata_cache_spill = UINT64_MAX;
99 query_sqlite3 = false;
100 }
101
102 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
103 gs->sqlite3_context_cache_spill = (uint64_t) sql_context_cache_stats(SQLITE_DBSTATUS_CACHE_SPILL);
104 else {
105 gs->sqlite3_context_cache_spill = UINT64_MAX;
106 query_sqlite3 = false;
107 }
108
109 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
110 gs->sqlite3_metadata_cache_write = (uint64_t) sql_metadata_cache_stats(SQLITE_DBSTATUS_CACHE_WRITE);
111 else {
112 gs->sqlite3_metadata_cache_write = UINT64_MAX;
113 query_sqlite3 = false;
114 }
115
116 if(query_sqlite3 && now_monotonic_usec() - last_run < timeout)
117 gs->sqlite3_context_cache_write = (uint64_t) sql_context_cache_stats(SQLITE_DBSTATUS_CACHE_WRITE);
118 else {
119 gs->sqlite3_context_cache_write = UINT64_MAX;
120 query_sqlite3 = false;
121 }
122
123 last_run = now_monotonic_usec();
124 }
125
126 void pulse_sqlite3_do(bool extended) {
127 if(!extended) return;
128 sqlite3_statistics.enabled = true;
129
130 struct sqlite3_statistics gs;
131 sqlite3_statistics_copy(&gs);
132
133 if(gs.sqlite3_queries_made) {
134 static RRDSET *st_sqlite3_queries = NULL;
135 static RRDDIM *rd_queries = NULL;
136
137 if (unlikely(!st_sqlite3_queries)) {
138 st_sqlite3_queries = rrdset_create_localhost(
139 "netdata"
140 , "sqlite3_queries"
141 , NULL
142 , "sqlite3"
143 , NULL
144 , "Netdata SQLite3 Queries"
145 , "queries/s"
146 , "netdata"
147 , "pulse"
148 , 131100
149 , localhost->rrd_update_every
150 , RRDSET_TYPE_LINE
151 );
152
153 rd_queries = rrddim_add(st_sqlite3_queries, "queries", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
154 }
155
156 rrddim_set_by_pointer(st_sqlite3_queries, rd_queries, (collected_number)gs.sqlite3_queries_made);
157
158 rrdset_done(st_sqlite3_queries);
159 }
160
161 // ----------------------------------------------------------------
162
163 if(gs.sqlite3_queries_ok || gs.sqlite3_queries_failed) {
164 static RRDSET *st_sqlite3_queries_by_status = NULL;
165 static RRDDIM *rd_ok = NULL, *rd_failed = NULL, *rd_busy = NULL, *rd_locked = NULL;
166
167 if (unlikely(!st_sqlite3_queries_by_status)) {
168 st_sqlite3_queries_by_status = rrdset_create_localhost(
169 "netdata"
170 , "sqlite3_queries_by_status"
171 , NULL
172 , "sqlite3"
173 , NULL
174 , "Netdata SQLite3 Queries by status"
175 , "queries/s"
176 , "netdata"
177 , "pulse"
178 , 131101
179 , localhost->rrd_update_every
180 , RRDSET_TYPE_LINE
181 );
182
183 rd_ok = rrddim_add(st_sqlite3_queries_by_status, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
184 rd_failed = rrddim_add(st_sqlite3_queries_by_status, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
185 rd_busy = rrddim_add(st_sqlite3_queries_by_status, "busy", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
186 rd_locked = rrddim_add(st_sqlite3_queries_by_status, "locked", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
187 }
188
189 rrddim_set_by_pointer(st_sqlite3_queries_by_status, rd_ok, (collected_number)gs.sqlite3_queries_made);
190 rrddim_set_by_pointer(st_sqlite3_queries_by_status, rd_failed, (collected_number)gs.sqlite3_queries_failed);
191 rrddim_set_by_pointer(st_sqlite3_queries_by_status, rd_busy, (collected_number)gs.sqlite3_queries_failed_busy);
192 rrddim_set_by_pointer(st_sqlite3_queries_by_status, rd_locked, (collected_number)gs.sqlite3_queries_failed_locked);
193
194 rrdset_done(st_sqlite3_queries_by_status);
195 }
196
197 // ----------------------------------------------------------------
198
199 if(gs.sqlite3_rows) {
200 static RRDSET *st_sqlite3_rows = NULL;
201 static RRDDIM *rd_rows = NULL;
202
203 if (unlikely(!st_sqlite3_rows)) {
204 st_sqlite3_rows = rrdset_create_localhost(
205 "netdata"
206 , "sqlite3_rows"
207 , NULL
208 , "sqlite3"
209 , NULL
210 , "Netdata SQLite3 Rows"
211 , "rows/s"
212 , "netdata"
213 , "pulse"
214 , 131102
215 , localhost->rrd_update_every
216 , RRDSET_TYPE_LINE
217 );
218
219 rd_rows = rrddim_add(st_sqlite3_rows, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
220 }
221
222 rrddim_set_by_pointer(st_sqlite3_rows, rd_rows, (collected_number)gs.sqlite3_rows);
223
224 rrdset_done(st_sqlite3_rows);
225 }
226
227 if(gs.sqlite3_metadata_cache_hit) {
228 static RRDSET *st_sqlite3_cache = NULL;
229 static RRDDIM *rd_cache_hit = NULL;
230 static RRDDIM *rd_cache_miss= NULL;
231 static RRDDIM *rd_cache_spill= NULL;
232 static RRDDIM *rd_cache_write= NULL;
233
234 if (unlikely(!st_sqlite3_cache)) {
235 st_sqlite3_cache = rrdset_create_localhost(
236 "netdata"
237 , "sqlite3_metatada_cache"
238 , NULL
239 , "sqlite3"
240 , NULL
241 , "Netdata SQLite3 metadata cache"
242 , "ops/s"
243 , "netdata"
244 , "pulse"
245 , 131103
246 , localhost->rrd_update_every
247 , RRDSET_TYPE_LINE
248 );
249
250 rd_cache_hit = rrddim_add(st_sqlite3_cache, "cache_hit", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
251 rd_cache_miss = rrddim_add(st_sqlite3_cache, "cache_miss", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
252 rd_cache_spill = rrddim_add(st_sqlite3_cache, "cache_spill", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
253 rd_cache_write = rrddim_add(st_sqlite3_cache, "cache_write", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
254 }
255
256 if(gs.sqlite3_metadata_cache_hit != UINT64_MAX)
257 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_hit, (collected_number)gs.sqlite3_metadata_cache_hit);
258
259 if(gs.sqlite3_metadata_cache_miss != UINT64_MAX)
260 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_miss, (collected_number)gs.sqlite3_metadata_cache_miss);
261
262 if(gs.sqlite3_metadata_cache_spill != UINT64_MAX)
263 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_spill, (collected_number)gs.sqlite3_metadata_cache_spill);
264
265 if(gs.sqlite3_metadata_cache_write != UINT64_MAX)
266 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_write, (collected_number)gs.sqlite3_metadata_cache_write);
267
268 rrdset_done(st_sqlite3_cache);
269 }
270
271 if(gs.sqlite3_context_cache_hit) {
272 static RRDSET *st_sqlite3_cache = NULL;
273 static RRDDIM *rd_cache_hit = NULL;
274 static RRDDIM *rd_cache_miss= NULL;
275 static RRDDIM *rd_cache_spill= NULL;
276 static RRDDIM *rd_cache_write= NULL;
277
278 if (unlikely(!st_sqlite3_cache)) {
279 st_sqlite3_cache = rrdset_create_localhost(
280 "netdata"
281 , "sqlite3_context_cache"
282 , NULL
283 , "sqlite3"
284 , NULL
285 , "Netdata SQLite3 context cache"
286 , "ops/s"
287 , "netdata"
288 , "pulse"
289 , 131104
290 , localhost->rrd_update_every
291 , RRDSET_TYPE_LINE
292 );
293
294 rd_cache_hit = rrddim_add(st_sqlite3_cache, "cache_hit", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
295 rd_cache_miss = rrddim_add(st_sqlite3_cache, "cache_miss", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
296 rd_cache_spill = rrddim_add(st_sqlite3_cache, "cache_spill", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
297 rd_cache_write = rrddim_add(st_sqlite3_cache, "cache_write", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
298 }
299
300 if(gs.sqlite3_context_cache_hit != UINT64_MAX)
301 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_hit, (collected_number)gs.sqlite3_context_cache_hit);
302
303 if(gs.sqlite3_context_cache_miss != UINT64_MAX)
304 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_miss, (collected_number)gs.sqlite3_context_cache_miss);
305
306 if(gs.sqlite3_context_cache_spill != UINT64_MAX)
307 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_spill, (collected_number)gs.sqlite3_context_cache_spill);
308
309 if(gs.sqlite3_context_cache_write != UINT64_MAX)
310 rrddim_set_by_pointer(st_sqlite3_cache, rd_cache_write, (collected_number)gs.sqlite3_context_cache_write);
311
312 rrdset_done(st_sqlite3_cache);
313 }
314 }