master
c 378 lines 16.1 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define PULSE_INTERNALS 1
4 #include "pulse-dictionary.h"
5
6 struct dictionary_stats dictionary_stats_category_collectors = { .name = "collectors" };
7 struct dictionary_stats dictionary_stats_category_rrdhost = { .name = "rrdhost" };
8 struct dictionary_stats dictionary_stats_category_rrdset = { .name = "rrdset" };
9 struct dictionary_stats dictionary_stats_category_rrddim = { .name = "rrddim" };
10 struct dictionary_stats dictionary_stats_category_rrdcontext = { .name = "context" };
11 struct dictionary_stats dictionary_stats_category_rrdlabels = { .name = "labels" };
12 struct dictionary_stats dictionary_stats_category_rrdhealth = { .name = "health" };
13 struct dictionary_stats dictionary_stats_category_functions = { .name = "functions" };
14 struct dictionary_stats dictionary_stats_category_replication = { .name = "replication" };
15 struct dictionary_stats dictionary_stats_category_dyncfg = { .name = "dyncfg" };
16
17 #ifdef DICT_WITH_STATS
18 struct dictionary_categories {
19 struct dictionary_stats *stats;
20
21 RRDSET *st_dicts;
22 RRDDIM *rd_dicts_active;
23 RRDDIM *rd_dicts_deleted;
24
25 RRDSET *st_items;
26 RRDDIM *rd_items_entries;
27 RRDDIM *rd_items_referenced;
28 RRDDIM *rd_items_pending_deletion;
29
30 RRDSET *st_ops;
31 RRDDIM *rd_ops_creations;
32 RRDDIM *rd_ops_destructions;
33 RRDDIM *rd_ops_flushes;
34 RRDDIM *rd_ops_traversals;
35 RRDDIM *rd_ops_walkthroughs;
36 RRDDIM *rd_ops_garbage_collections;
37 RRDDIM *rd_ops_searches;
38 RRDDIM *rd_ops_inserts;
39 RRDDIM *rd_ops_resets;
40 RRDDIM *rd_ops_deletes;
41
42 RRDSET *st_callbacks;
43 RRDDIM *rd_callbacks_inserts;
44 RRDDIM *rd_callbacks_conflicts;
45 RRDDIM *rd_callbacks_reacts;
46 RRDDIM *rd_callbacks_deletes;
47
48 RRDSET *st_memory;
49 RRDDIM *rd_memory_indexed;
50 RRDDIM *rd_memory_values;
51 RRDDIM *rd_memory_dict;
52
53 RRDSET *st_spins;
54 RRDDIM *rd_spins_use;
55 RRDDIM *rd_spins_search;
56 RRDDIM *rd_spins_insert;
57 RRDDIM *rd_spins_delete;
58
59 } dictionary_categories[] = {
60 { .stats = &dictionary_stats_category_collectors, },
61 { .stats = &dictionary_stats_category_rrdhost, },
62 { .stats = &dictionary_stats_category_rrdset, },
63 { .stats = &dictionary_stats_category_rrdcontext, },
64 { .stats = &dictionary_stats_category_rrdlabels, },
65 { .stats = &dictionary_stats_category_rrdhealth, },
66 { .stats = &dictionary_stats_category_functions, },
67 { .stats = &dictionary_stats_category_replication, },
68 { .stats = &dictionary_stats_category_dyncfg, },
69 { .stats = &dictionary_stats_category_other, },
70
71 // terminator
72 { .stats = NULL, NULL, NULL, 0 },
73 };
74
75 #define load_dictionary_stats_entry(x) total += (size_t)(stats.x = __atomic_load_n(&c->stats->x, __ATOMIC_RELAXED))
76
77 static void update_dictionary_category_charts(struct dictionary_categories *c) {
78 struct dictionary_stats stats;
79 stats.name = c->stats->name;
80 int priority = 900000;
81 const char *family = "dictionaries";
82 const char *context_prefix = "dictionaries";
83
84 // ------------------------------------------------------------------------
85
86 size_t total = 0;
87 load_dictionary_stats_entry(dictionaries.active);
88 load_dictionary_stats_entry(dictionaries.deleted);
89
90 if(c->st_dicts || total != 0) {
91 if (unlikely(!c->st_dicts)) {
92 char id[RRD_ID_LENGTH_MAX + 1];
93 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.dictionaries", context_prefix, stats.name);
94
95 char context[RRD_ID_LENGTH_MAX + 1];
96 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.dictionaries", context_prefix);
97
98 c->st_dicts = rrdset_create_localhost(
99 "netdata"
100 , id
101 , NULL
102 , family
103 , context
104 , "Dictionaries"
105 , "dictionaries"
106 , "netdata"
107 , "pulse"
108 , priority + 0
109 , localhost->rrd_update_every
110 , RRDSET_TYPE_LINE
111 );
112
113 c->rd_dicts_active = rrddim_add(c->st_dicts, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
114 c->rd_dicts_deleted = rrddim_add(c->st_dicts, "deleted", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
115
116 rrdlabels_add(c->st_dicts->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
117 }
118
119 rrddim_set_by_pointer(c->st_dicts, c->rd_dicts_active, (collected_number)stats.dictionaries.active);
120 rrddim_set_by_pointer(c->st_dicts, c->rd_dicts_deleted, (collected_number)stats.dictionaries.deleted);
121 rrdset_done(c->st_dicts);
122 }
123
124 // ------------------------------------------------------------------------
125
126 total = 0;
127 load_dictionary_stats_entry(items.entries);
128 load_dictionary_stats_entry(items.referenced);
129 load_dictionary_stats_entry(items.pending_deletion);
130
131 if(c->st_items || total != 0) {
132 if (unlikely(!c->st_items)) {
133 char id[RRD_ID_LENGTH_MAX + 1];
134 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.items", context_prefix, stats.name);
135
136 char context[RRD_ID_LENGTH_MAX + 1];
137 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.items", context_prefix);
138
139 c->st_items = rrdset_create_localhost(
140 "netdata"
141 , id
142 , NULL
143 , family
144 , context
145 , "Dictionary Items"
146 , "items"
147 , "netdata"
148 , "pulse"
149 , priority + 1
150 , localhost->rrd_update_every
151 , RRDSET_TYPE_LINE
152 );
153
154 c->rd_items_entries = rrddim_add(c->st_items, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
155 c->rd_items_pending_deletion = rrddim_add(c->st_items, "deleted", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
156 c->rd_items_referenced = rrddim_add(c->st_items, "referenced", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
157
158 rrdlabels_add(c->st_items->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
159 }
160
161 rrddim_set_by_pointer(c->st_items, c->rd_items_entries, stats.items.entries);
162 rrddim_set_by_pointer(c->st_items, c->rd_items_pending_deletion, stats.items.pending_deletion);
163 rrddim_set_by_pointer(c->st_items, c->rd_items_referenced, stats.items.referenced);
164 rrdset_done(c->st_items);
165 }
166
167 // ------------------------------------------------------------------------
168
169 total = 0;
170 load_dictionary_stats_entry(ops.creations);
171 load_dictionary_stats_entry(ops.destructions);
172 load_dictionary_stats_entry(ops.flushes);
173 load_dictionary_stats_entry(ops.traversals);
174 load_dictionary_stats_entry(ops.walkthroughs);
175 load_dictionary_stats_entry(ops.garbage_collections);
176 load_dictionary_stats_entry(ops.searches);
177 load_dictionary_stats_entry(ops.inserts);
178 load_dictionary_stats_entry(ops.resets);
179 load_dictionary_stats_entry(ops.deletes);
180
181 if(c->st_ops || total != 0) {
182 if (unlikely(!c->st_ops)) {
183 char id[RRD_ID_LENGTH_MAX + 1];
184 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.ops", context_prefix, stats.name);
185
186 char context[RRD_ID_LENGTH_MAX + 1];
187 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.ops", context_prefix);
188
189 c->st_ops = rrdset_create_localhost(
190 "netdata"
191 , id
192 , NULL
193 , family
194 , context
195 , "Dictionary Operations"
196 , "ops/s"
197 , "netdata"
198 , "pulse"
199 , priority + 2
200 , localhost->rrd_update_every
201 , RRDSET_TYPE_LINE
202 );
203
204 c->rd_ops_creations = rrddim_add(c->st_ops, "creations", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
205 c->rd_ops_destructions = rrddim_add(c->st_ops, "destructions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
206 c->rd_ops_flushes = rrddim_add(c->st_ops, "flushes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
207 c->rd_ops_traversals = rrddim_add(c->st_ops, "traversals", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
208 c->rd_ops_walkthroughs = rrddim_add(c->st_ops, "walkthroughs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
209 c->rd_ops_garbage_collections = rrddim_add(c->st_ops, "garbage_collections", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
210 c->rd_ops_searches = rrddim_add(c->st_ops, "searches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
211 c->rd_ops_inserts = rrddim_add(c->st_ops, "inserts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
212 c->rd_ops_resets = rrddim_add(c->st_ops, "resets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
213 c->rd_ops_deletes = rrddim_add(c->st_ops, "deletes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
214
215 rrdlabels_add(c->st_ops->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
216 }
217
218 rrddim_set_by_pointer(c->st_ops, c->rd_ops_creations, (collected_number)stats.ops.creations);
219 rrddim_set_by_pointer(c->st_ops, c->rd_ops_destructions, (collected_number)stats.ops.destructions);
220 rrddim_set_by_pointer(c->st_ops, c->rd_ops_flushes, (collected_number)stats.ops.flushes);
221 rrddim_set_by_pointer(c->st_ops, c->rd_ops_traversals, (collected_number)stats.ops.traversals);
222 rrddim_set_by_pointer(c->st_ops, c->rd_ops_walkthroughs, (collected_number)stats.ops.walkthroughs);
223 rrddim_set_by_pointer(c->st_ops, c->rd_ops_garbage_collections, (collected_number)stats.ops.garbage_collections);
224 rrddim_set_by_pointer(c->st_ops, c->rd_ops_searches, (collected_number)stats.ops.searches);
225 rrddim_set_by_pointer(c->st_ops, c->rd_ops_inserts, (collected_number)stats.ops.inserts);
226 rrddim_set_by_pointer(c->st_ops, c->rd_ops_resets, (collected_number)stats.ops.resets);
227 rrddim_set_by_pointer(c->st_ops, c->rd_ops_deletes, (collected_number)stats.ops.deletes);
228
229 rrdset_done(c->st_ops);
230 }
231
232 // ------------------------------------------------------------------------
233
234 total = 0;
235 load_dictionary_stats_entry(callbacks.inserts);
236 load_dictionary_stats_entry(callbacks.conflicts);
237 load_dictionary_stats_entry(callbacks.reacts);
238 load_dictionary_stats_entry(callbacks.deletes);
239
240 if(c->st_callbacks || total != 0) {
241 if (unlikely(!c->st_callbacks)) {
242 char id[RRD_ID_LENGTH_MAX + 1];
243 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.callbacks", context_prefix, stats.name);
244
245 char context[RRD_ID_LENGTH_MAX + 1];
246 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.callbacks", context_prefix);
247
248 c->st_callbacks = rrdset_create_localhost(
249 "netdata"
250 , id
251 , NULL
252 , family
253 , context
254 , "Dictionary Callbacks"
255 , "callbacks/s"
256 , "netdata"
257 , "pulse"
258 , priority + 3
259 , localhost->rrd_update_every
260 , RRDSET_TYPE_LINE
261 );
262
263 c->rd_callbacks_inserts = rrddim_add(c->st_callbacks, "inserts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
264 c->rd_callbacks_deletes = rrddim_add(c->st_callbacks, "deletes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
265 c->rd_callbacks_conflicts = rrddim_add(c->st_callbacks, "conflicts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
266 c->rd_callbacks_reacts = rrddim_add(c->st_callbacks, "reacts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
267
268 rrdlabels_add(c->st_callbacks->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
269 }
270
271 rrddim_set_by_pointer(c->st_callbacks, c->rd_callbacks_inserts, (collected_number)stats.callbacks.inserts);
272 rrddim_set_by_pointer(c->st_callbacks, c->rd_callbacks_conflicts, (collected_number)stats.callbacks.conflicts);
273 rrddim_set_by_pointer(c->st_callbacks, c->rd_callbacks_reacts, (collected_number)stats.callbacks.reacts);
274 rrddim_set_by_pointer(c->st_callbacks, c->rd_callbacks_deletes, (collected_number)stats.callbacks.deletes);
275
276 rrdset_done(c->st_callbacks);
277 }
278
279 // ------------------------------------------------------------------------
280
281 total = 0;
282 load_dictionary_stats_entry(memory.index);
283 load_dictionary_stats_entry(memory.values);
284 load_dictionary_stats_entry(memory.dict);
285
286 if(c->st_memory || total != 0) {
287 if (unlikely(!c->st_memory)) {
288 char id[RRD_ID_LENGTH_MAX + 1];
289 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.memory", context_prefix, stats.name);
290
291 char context[RRD_ID_LENGTH_MAX + 1];
292 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.memory", context_prefix);
293
294 c->st_memory = rrdset_create_localhost(
295 "netdata"
296 , id
297 , NULL
298 , family
299 , context
300 , "Dictionary Memory"
301 , "bytes"
302 , "netdata"
303 , "pulse"
304 , priority + 4
305 , localhost->rrd_update_every
306 , RRDSET_TYPE_STACKED
307 );
308
309 c->rd_memory_indexed = rrddim_add(c->st_memory, "index", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
310 c->rd_memory_values = rrddim_add(c->st_memory, "data", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
311 c->rd_memory_dict = rrddim_add(c->st_memory, "structures", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
312
313 rrdlabels_add(c->st_memory->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
314 }
315
316 rrddim_set_by_pointer(c->st_memory, c->rd_memory_indexed, (collected_number)stats.memory.index);
317 rrddim_set_by_pointer(c->st_memory, c->rd_memory_values, (collected_number)stats.memory.values);
318 rrddim_set_by_pointer(c->st_memory, c->rd_memory_dict, (collected_number)stats.memory.dict);
319
320 rrdset_done(c->st_memory);
321 }
322
323 // ------------------------------------------------------------------------
324
325 total = 0;
326 load_dictionary_stats_entry(spin_locks.use_spins);
327 load_dictionary_stats_entry(spin_locks.search_spins);
328 load_dictionary_stats_entry(spin_locks.insert_spins);
329 load_dictionary_stats_entry(spin_locks.delete_spins);
330
331 if(c->st_spins || total != 0) {
332 if (unlikely(!c->st_spins)) {
333 char id[RRD_ID_LENGTH_MAX + 1];
334 snprintfz(id, RRD_ID_LENGTH_MAX, "%s.%s.spins", context_prefix, stats.name);
335
336 char context[RRD_ID_LENGTH_MAX + 1];
337 snprintfz(context, RRD_ID_LENGTH_MAX, "netdata.%s.category.spins", context_prefix);
338
339 c->st_spins = rrdset_create_localhost(
340 "netdata"
341 , id
342 , NULL
343 , family
344 , context
345 , "Dictionary Spins"
346 , "count"
347 , "netdata"
348 , "pulse"
349 , priority + 5
350 , localhost->rrd_update_every
351 , RRDSET_TYPE_LINE
352 );
353
354 c->rd_spins_use = rrddim_add(c->st_spins, "use", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
355 c->rd_spins_search = rrddim_add(c->st_spins, "search", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
356 c->rd_spins_insert = rrddim_add(c->st_spins, "insert", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
357 c->rd_spins_delete = rrddim_add(c->st_spins, "delete", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
358
359 rrdlabels_add(c->st_spins->rrdlabels, "category", stats.name, RRDLABEL_SRC_AUTO);
360 }
361
362 rrddim_set_by_pointer(c->st_spins, c->rd_spins_use, (collected_number)stats.spin_locks.use_spins);
363 rrddim_set_by_pointer(c->st_spins, c->rd_spins_search, (collected_number)stats.spin_locks.search_spins);
364 rrddim_set_by_pointer(c->st_spins, c->rd_spins_insert, (collected_number)stats.spin_locks.insert_spins);
365 rrddim_set_by_pointer(c->st_spins, c->rd_spins_delete, (collected_number)stats.spin_locks.delete_spins);
366
367 rrdset_done(c->st_spins);
368 }
369 }
370
371 void pulse_dictionary_do(bool extended) {
372 if(!extended) return;
373
374 for(int i = 0; dictionary_categories[i].stats ;i++) {
375 update_dictionary_category_charts(&dictionary_categories[i]);
376 }
377 }
378 #endif // DICT_WITH_STATS