@cryptotaxi247 / netdata-1 / commits / 73212e3a8

self-cleaning obsolete cgroups and network interfaces from memory; fixes #1163; fixes #1358

Costa Tsaousis (ktsaou) committed Mar 1, 2017 at 00:47 UTC 73212e3a8731012fee476e373f4a5b647f5126e5
16 files changed +1452 -920
CMakeLists.txt
+1 -1
@@ -124,7 +124,7 @@ set(NETDATA_SOURCE_FILES
124 src/web_client.h
125 src/web_server.c
126 src/web_server.h
127 - src/rrdhost.c src/rrdfamily.c src/rrdset.c src/rrddim.c src/health_log.c src/health_config.c src/health_json.c src/rrdcalc.c src/rrdcalctemplate.c src/rrdvar.c src/rrddimvar.c src/rrdsetvar.c src/rrdpush.c src/rrdpush.h src/web_api_old.c src/web_api_old.h src/web_api_v1.c src/web_api_v1.h)
127 + src/rrdhost.c src/rrdfamily.c src/rrdset.c src/rrddim.c src/health_log.c src/health_config.c src/health_json.c src/rrdcalc.c src/rrdcalctemplate.c src/rrdvar.c src/rrddimvar.c src/rrdsetvar.c src/rrdpush.c src/rrdpush.h src/web_api_old.c src/web_api_old.h src/web_api_v1.c src/web_api_v1.h src/rrd2json_api_old.c src/rrd2json_api_old.h)
128
129 set(APPS_PLUGIN_SOURCE_FILES
130 src/appconfig.c
conf.d/health.d/net.conf
-15
@@ -1,18 +1,3 @@
1 -# -----------------------------------------------------------------------------
2 -# make sure we collect values for each interface
3 -
4 -template: interface_last_collected_secs
5 - on: net.net
6 -families: *
7 - calc: $now - $last_collected_t
8 - units: seconds ago
9 - every: 10s
10 - warn: $this > (($status >= $WARNING) ? ($update_every) : ( 5 * $update_every))
11 - crit: $this > (($status == $CRITICAL) ? ($update_every) : (60 * $update_every))
12 - delay: down 5m multiplier 1.5 max 1h
13 - info: number of seconds since the last successful data collection
14 - to: sysadmin
15 -
1
2 # -----------------------------------------------------------------------------
3 # dropped packets
src/Makefile.am
+1
@@ -75,6 +75,7 @@ netdata_SOURCES = \
75 rrddimvar.c \
76 rrdsetvar.c \
77 rrd2json.c rrd2json.h \
78 + rrd2json_api_old.c rrd2json_api_old.h \
79 rrdpush.c rrdpush.h \
80 storage_number.c storage_number.h \
81 unit_test.c unit_test.h \
src/common.h
+1
@@ -206,6 +206,7 @@
206 #include "plugin_tc.h"
207 #include "plugins_d.h"
208 #include "rrd2json.h"
209 +#include "rrd2json_api_old.h"
210 #include "web_client.h"
211 #include "web_server.h"
212 #include "registry.h"
src/health.c
+22 -12
@@ -281,6 +281,16 @@ static inline int rrdcalc_isrunnable(RRDCALC *rc, time_t now, time_t *next_run)
281 return 0;
282 }
283
284 + if(unlikely(rrdset_flag_check(rc->rrdset, RRDSET_FLAG_OBSOLETE))) {
285 + debug(D_HEALTH, "Health not running alarm '%s.%s'. The chart has been marked as obsolete", rc->chart?rc->chart:"NOCHART", rc->name);
286 + return 0;
287 + }
288 +
289 + if(unlikely(!rrdset_flag_check(rc->rrdset, RRDSET_FLAG_ENABLED))) {
290 + debug(D_HEALTH, "Health not running alarm '%s.%s'. The chart is not enabled", rc->chart?rc->chart:"NOCHART", rc->name);
291 + return 0;
292 + }
293 +
294 if(unlikely(!rc->rrdset->last_collected_time.tv_sec || rc->rrdset->counter_done < 2)) {
295 debug(D_HEALTH, "Health not running alarm '%s.%s'. Chart is not fully collected yet.", rc->chart?rc->chart:"NOCHART", rc->name);
296 return 0;
@@ -398,18 +408,18 @@ void *health_main(void *ptr) {
408 /* time_t old_db_timestamp = rc->db_before; */
409 int value_is_null = 0;
410
401 - int ret = rrd2value(rc->rrdset
402 - , wb
403 - , &rc->value
404 - , rc->dimensions
405 - , 1
406 - , rc->after
407 - , rc->before
408 - , rc->group
409 - , rc->options
410 - , &rc->db_after
411 - , &rc->db_before
412 - , &value_is_null
411 + int ret = rrdset2value_api_v1(rc->rrdset
412 + , wb
413 + , &rc->value
414 + , rc->dimensions
415 + , 1
416 + , rc->after
417 + , rc->before
418 + , rc->group
419 + , rc->options
420 + , &rc->db_after
421 + , &rc->db_before
422 + , &value_is_null
423 );
424
425 if(unlikely(ret != 200)) {
src/proc_net_dev.c
+161 -56
@@ -8,6 +8,7 @@ struct netdev {
8 // flags
9 int configured;
10 int enabled;
11 + int updated;
12
13 int do_bandwidth;
14 int do_packets;
@@ -67,26 +68,70 @@ struct netdev {
68 struct netdev *next;
69 };
70
70 -static struct netdev *netdev_root = NULL;
71 +static struct netdev *netdev_root = NULL, *netdev_last_used = NULL;
72 +
73 +static size_t netdev_added = 0, netdev_found = 0;
74 +
75 +static void netdev_free(struct netdev *d) {
76 + if(d->st_bandwidth) rrdset_flag_set(d->st_bandwidth, RRDSET_FLAG_OBSOLETE);
77 + if(d->st_packets) rrdset_flag_set(d->st_packets, RRDSET_FLAG_OBSOLETE);
78 + if(d->st_errors) rrdset_flag_set(d->st_errors, RRDSET_FLAG_OBSOLETE);
79 + if(d->st_drops) rrdset_flag_set(d->st_drops, RRDSET_FLAG_OBSOLETE);
80 + if(d->st_fifo) rrdset_flag_set(d->st_fifo, RRDSET_FLAG_OBSOLETE);
81 + if(d->st_compressed) rrdset_flag_set(d->st_compressed, RRDSET_FLAG_OBSOLETE);
82 + if(d->st_events) rrdset_flag_set(d->st_events, RRDSET_FLAG_OBSOLETE);
83 +
84 + freez(d->name);
85 + freez(d);
86 +}
87 +
88 +static void netdev_cleanup() {
89 + if(likely(netdev_found == netdev_added)) return;
90 +
91 + struct netdev *d = netdev_root, *last = NULL;
92 + while(d) {
93 + if(unlikely(!d->updated)) {
94 + // info("Removing network device '%s', linked after '%s'", d->name, last?last->name:"ROOT");
95 +
96 + if(netdev_last_used == d)
97 + netdev_last_used = last;
98 +
99 + struct netdev *t = d;
100 +
101 + if(d == netdev_root || !last)
102 + netdev_root = d = d->next;
103 +
104 + else
105 + last->next = d = d->next;
106 +
107 + t->next = NULL;
108 + netdev_free(t);
109 + }
110 + else {
111 + last = d;
112 + d->updated = 0;
113 + d = d->next;
114 + }
115 + }
116 +}
117
118 static struct netdev *get_netdev(const char *name) {
73 - static struct netdev *last = NULL;
119 struct netdev *d;
120
121 uint32_t hash = simple_hash(name);
122
123 // search it, from the last position to the end
79 - for(d = last ; d ; d = d->next) {
124 + for(d = netdev_last_used ; d ; d = d->next) {
125 if(unlikely(hash == d->hash && !strcmp(name, d->name))) {
81 - last = d->next;
126 + netdev_last_used = d->next;
127 return d;
128 }
129 }
130
131 // search it from the beginning to the last position we used
87 - for(d = netdev_root ; d != last ; d = d->next) {
132 + for(d = netdev_root ; d != netdev_last_used ; d = d->next) {
133 if(unlikely(hash == d->hash && !strcmp(name, d->name))) {
89 - last = d->next;
134 + netdev_last_used = d->next;
135 return d;
136 }
137 }
@@ -96,6 +141,7 @@ static struct netdev *get_netdev(const char *name) {
141 d->name = strdupz(name);
142 d->hash = simple_hash(d->name);
143 d->len = strlen(d->name);
144 + netdev_added++;
145
146 // link it to the end
147 if(netdev_root) {
@@ -142,12 +188,16 @@ int do_proc_net_dev(int update_every, usec_t dt) {
188 ff = procfile_readall(ff);
189 if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
190
191 + netdev_found = 0;
192 +
193 size_t lines = procfile_lines(ff), l;
194 for(l = 2; l < lines ;l++) {
195 // require 17 words on each line
196 if(unlikely(procfile_linewords(ff, l) < 17)) continue;
197
198 struct netdev *d = get_netdev(procfile_lineword(ff, l, 0));
199 + d->updated = 1;
200 + netdev_found++;
201
202 if(unlikely(!d->configured)) {
203 // this is the first time we see this interface
@@ -223,19 +273,27 @@ int do_proc_net_dev(int update_every, usec_t dt) {
273
274 if(d->do_bandwidth == CONFIG_BOOLEAN_YES) {
275 if(unlikely(!d->st_bandwidth)) {
226 - d->st_bandwidth = rrdset_find_bytype_localhost("net", d->name);
276
228 - if(!d->st_bandwidth)
229 - d->st_bandwidth = rrdset_create_localhost("net", d->name, NULL, d->name, "net.net", "Bandwidth"
230 - , "kilobits/s", 7000, update_every, RRDSET_TYPE_AREA);
277 + d->st_bandwidth = rrdset_create_localhost(
278 + "net"
279 + , d->name
280 + , NULL
281 + , d->name
282 + , "net.net"
283 + , "Bandwidth"
284 + , "kilobits/s"
285 + , 7000
286 + , update_every
287 + , RRDSET_TYPE_AREA
288 + );
289
290 d->rd_rbytes = rrddim_add(d->st_bandwidth, "received", NULL, 8, 1024, RRD_ALGORITHM_INCREMENTAL);
291 d->rd_tbytes = rrddim_add(d->st_bandwidth, "sent", NULL, -8, 1024, RRD_ALGORITHM_INCREMENTAL);
292 }
293 else rrdset_next(d->st_bandwidth);
294
237 - rrddim_set_by_pointer(d->st_bandwidth, d->rd_rbytes, d->rbytes);
238 - rrddim_set_by_pointer(d->st_bandwidth, d->rd_tbytes, d->tbytes);
295 + rrddim_set_by_pointer(d->st_bandwidth, d->rd_rbytes, (collected_number)d->rbytes);
296 + rrddim_set_by_pointer(d->st_bandwidth, d->rd_tbytes, (collected_number)d->tbytes);
297 rrdset_done(d->st_bandwidth);
298 }
299
@@ -246,12 +304,20 @@ int do_proc_net_dev(int update_every, usec_t dt) {
304
305 if(d->do_packets == CONFIG_BOOLEAN_YES) {
306 if(unlikely(!d->st_packets)) {
249 - d->st_packets = rrdset_find_bytype_localhost("net_packets", d->name);
307
251 - if(!d->st_packets)
252 - d->st_packets = rrdset_create_localhost("net_packets", d->name, NULL, d->name, "net.packets"
253 - , "Packets", "packets/s", 7001, update_every
254 - , RRDSET_TYPE_LINE);
308 + d->st_packets = rrdset_create_localhost(
309 + "net_packets"
310 + , d->name
311 + , NULL
312 + , d->name
313 + , "net.packets"
314 + , "Packets"
315 + , "packets/s"
316 + , 7001
317 + , update_every
318 + , RRDSET_TYPE_LINE
319 + );
320 +
321 rrdset_flag_set(d->st_packets, RRDSET_FLAG_DETAIL);
322
323 d->rd_rpackets = rrddim_add(d->st_packets, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
@@ -260,9 +326,9 @@ int do_proc_net_dev(int update_every, usec_t dt) {
326 }
327 else rrdset_next(d->st_packets);
328
263 - rrddim_set_by_pointer(d->st_packets, d->rd_rpackets, d->rpackets);
264 - rrddim_set_by_pointer(d->st_packets, d->rd_tpackets, d->tpackets);
265 - rrddim_set_by_pointer(d->st_packets, d->rd_rmulticast, d->rmulticast);
329 + rrddim_set_by_pointer(d->st_packets, d->rd_rpackets, (collected_number)d->rpackets);
330 + rrddim_set_by_pointer(d->st_packets, d->rd_tpackets, (collected_number)d->tpackets);
331 + rrddim_set_by_pointer(d->st_packets, d->rd_rmulticast, (collected_number)d->rmulticast);
332 rrdset_done(d->st_packets);
333 }
334
@@ -273,12 +339,19 @@ int do_proc_net_dev(int update_every, usec_t dt) {
339
340 if(d->do_errors == CONFIG_BOOLEAN_YES) {
341 if(unlikely(!d->st_errors)) {
276 - d->st_errors = rrdset_find_bytype_localhost("net_errors", d->name);
342
278 - if(!d->st_errors)
279 - d->st_errors = rrdset_create_localhost("net_errors", d->name, NULL, d->name, "net.errors"
280 - , "Interface Errors", "errors/s", 7002, update_every
281 - , RRDSET_TYPE_LINE);
343 + d->st_errors = rrdset_create_localhost(
344 + "net_errors"
345 + , d->name
346 + , NULL
347 + , d->name
348 + , "net.errors"
349 + , "Interface Errors"
350 + , "errors/s"
351 + , 7002
352 + , update_every
353 + , RRDSET_TYPE_LINE
354 + );
355
356 rrdset_flag_set(d->st_errors, RRDSET_FLAG_DETAIL);
357
@@ -287,8 +360,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
360 }
361 else rrdset_next(d->st_errors);
362
290 - rrddim_set_by_pointer(d->st_errors, d->rd_rerrors, d->rerrors);
291 - rrddim_set_by_pointer(d->st_errors, d->rd_terrors, d->terrors);
363 + rrddim_set_by_pointer(d->st_errors, d->rd_rerrors, (collected_number)d->rerrors);
364 + rrddim_set_by_pointer(d->st_errors, d->rd_terrors, (collected_number)d->terrors);
365 rrdset_done(d->st_errors);
366 }
367
@@ -299,12 +372,19 @@ int do_proc_net_dev(int update_every, usec_t dt) {
372
373 if(d->do_drops == CONFIG_BOOLEAN_YES) {
374 if(unlikely(!d->st_drops)) {
302 - d->st_drops = rrdset_find_bytype_localhost("net_drops", d->name);
375
304 - if(!d->st_drops)
305 - d->st_drops = rrdset_create_localhost("net_drops", d->name, NULL, d->name, "net.drops"
306 - , "Interface Drops", "drops/s", 7003, update_every
307 - , RRDSET_TYPE_LINE);
376 + d->st_drops = rrdset_create_localhost(
377 + "net_drops"
378 + , d->name
379 + , NULL
380 + , d->name
381 + , "net.drops"
382 + , "Interface Drops"
383 + , "drops/s"
384 + , 7003
385 + , update_every
386 + , RRDSET_TYPE_LINE
387 + );
388
389 rrdset_flag_set(d->st_drops, RRDSET_FLAG_DETAIL);
390
@@ -313,8 +393,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
393 }
394 else rrdset_next(d->st_drops);
395
316 - rrddim_set_by_pointer(d->st_drops, d->rd_rdrops, d->rdrops);
317 - rrddim_set_by_pointer(d->st_drops, d->rd_tdrops, d->tdrops);
396 + rrddim_set_by_pointer(d->st_drops, d->rd_rdrops, (collected_number)d->rdrops);
397 + rrddim_set_by_pointer(d->st_drops, d->rd_tdrops, (collected_number)d->tdrops);
398 rrdset_done(d->st_drops);
399 }
400
@@ -325,12 +405,19 @@ int do_proc_net_dev(int update_every, usec_t dt) {
405
406 if(d->do_fifo == CONFIG_BOOLEAN_YES) {
407 if(unlikely(!d->st_fifo)) {
328 - d->st_fifo = rrdset_find_bytype_localhost("net_fifo", d->name);
408
330 - if(!d->st_fifo)
331 - d->st_fifo = rrdset_create_localhost("net_fifo", d->name, NULL, d->name, "net.fifo"
332 - , "Interface FIFO Buffer Errors", "errors", 7004, update_every
333 - , RRDSET_TYPE_LINE);
409 + d->st_fifo = rrdset_create_localhost(
410 + "net_fifo"
411 + , d->name
412 + , NULL
413 + , d->name
414 + , "net.fifo"
415 + , "Interface FIFO Buffer Errors"
416 + , "errors"
417 + , 7004
418 + , update_every
419 + , RRDSET_TYPE_LINE
420 + );
421
422 rrdset_flag_set(d->st_fifo, RRDSET_FLAG_DETAIL);
423
@@ -339,8 +426,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
426 }
427 else rrdset_next(d->st_fifo);
428
342 - rrddim_set_by_pointer(d->st_fifo, d->rd_rfifo, d->rfifo);
343 - rrddim_set_by_pointer(d->st_fifo, d->rd_tfifo, d->tfifo);
429 + rrddim_set_by_pointer(d->st_fifo, d->rd_rfifo, (collected_number)d->rfifo);
430 + rrddim_set_by_pointer(d->st_fifo, d->rd_tfifo, (collected_number)d->tfifo);
431 rrdset_done(d->st_fifo);
432 }
433
@@ -351,11 +438,19 @@ int do_proc_net_dev(int update_every, usec_t dt) {
438
439 if(d->do_compressed == CONFIG_BOOLEAN_YES) {
440 if(unlikely(!d->st_compressed)) {
354 - d->st_compressed = rrdset_find_bytype_localhost("net_compressed", d->name);
355 - if(!d->st_compressed)
356 - d->st_compressed = rrdset_create_localhost("net_compressed", d->name, NULL, d->name
357 - , "net.compressed", "Compressed Packets", "packets/s"
358 - , 7005, update_every, RRDSET_TYPE_LINE);
441 +
442 + d->st_compressed = rrdset_create_localhost(
443 + "net_compressed"
444 + , d->name
445 + , NULL
446 + , d->name
447 + , "net.compressed"
448 + , "Compressed Packets"
449 + , "packets/s"
450 + , 7005
451 + , update_every
452 + , RRDSET_TYPE_LINE
453 + );
454
455 rrdset_flag_set(d->st_compressed, RRDSET_FLAG_DETAIL);
456
@@ -364,8 +459,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
459 }
460 else rrdset_next(d->st_compressed);
461
367 - rrddim_set_by_pointer(d->st_compressed, d->rd_rcompressed, d->rcompressed);
368 - rrddim_set_by_pointer(d->st_compressed, d->rd_tcompressed, d->tcompressed);
462 + rrddim_set_by_pointer(d->st_compressed, d->rd_rcompressed, (collected_number)d->rcompressed);
463 + rrddim_set_by_pointer(d->st_compressed, d->rd_tcompressed, (collected_number)d->tcompressed);
464 rrdset_done(d->st_compressed);
465 }
466
@@ -376,11 +471,19 @@ int do_proc_net_dev(int update_every, usec_t dt) {
471
472 if(d->do_events == CONFIG_BOOLEAN_YES) {
473 if(unlikely(!d->st_events)) {
379 - d->st_events = rrdset_find_bytype_localhost("net_events", d->name);
380 - if(!d->st_events)
381 - d->st_events = rrdset_create_localhost("net_events", d->name, NULL, d->name, "net.events"
382 - , "Network Interface Events", "events/s", 7006, update_every
383 - , RRDSET_TYPE_LINE);
474 +
475 + d->st_events = rrdset_create_localhost(
476 + "net_events"
477 + , d->name
478 + , NULL
479 + , d->name
480 + , "net.events"
481 + , "Network Interface Events"
482 + , "events/s"
483 + , 7006
484 + , update_every
485 + , RRDSET_TYPE_LINE
486 + );
487
488 rrdset_flag_set(d->st_events, RRDSET_FLAG_DETAIL);
489
@@ -390,12 +493,14 @@ int do_proc_net_dev(int update_every, usec_t dt) {
493 }
494 else rrdset_next(d->st_events);
495
393 - rrddim_set_by_pointer(d->st_events, d->rd_rframe, d->rframe);
394 - rrddim_set_by_pointer(d->st_events, d->rd_tcollisions, d->tcollisions);
395 - rrddim_set_by_pointer(d->st_events, d->rd_tcarrier, d->tcarrier);
496 + rrddim_set_by_pointer(d->st_events, d->rd_rframe, (collected_number)d->rframe);
497 + rrddim_set_by_pointer(d->st_events, d->rd_tcollisions, (collected_number)d->tcollisions);
498 + rrddim_set_by_pointer(d->st_events, d->rd_tcarrier, (collected_number)d->tcarrier);
499 rrdset_done(d->st_events);
500 }
501 }
502
503 + netdev_cleanup();
504 +
505 return 0;
506 }
src/rrd.h
+11 -2
@@ -213,7 +213,8 @@ typedef enum rrdset_flags {
213 RRDSET_FLAG_ENABLED = 1 << 0, // enables or disables a chart
214 RRDSET_FLAG_DETAIL = 1 << 1, // if set, the data set should be considered as a detail of another
215 // (the master data set should be the one that has the same family and is not detail)
216 - RRDSET_FLAG_DEBUG = 1 << 2 // enables or disables debugging for a chart
216 + RRDSET_FLAG_DEBUG = 1 << 2, // enables or disables debugging for a chart
217 + RRDSET_FLAG_OBSOLETE = 1 << 3 // this is marked by the collector/module as obsolete
218 } RRDSET_FLAGS;
219
220 #define rrdset_flag_check(st, flag) ((st)->flags & flag)
@@ -276,7 +277,9 @@ struct rrdset {
277
278 size_t counter; // the number of times we added values to this database
279 size_t counter_done; // the number of times rrdset_done() has been called
279 - size_t unused[10];
280 +
281 + time_t last_accessed_time; // the last time this RRDSET has been accessed
282 + size_t unused[9];
283
284 uint32_t hash; // a simple hash on the id, to speed up searching
285 // we first compare hashes, and only if the hashes are equal we do string comparisons
@@ -540,6 +543,9 @@ extern void rrdset_next_usec(RRDSET *st, usec_t microseconds);
543
544 extern void rrdset_done(RRDSET *st);
545
546 +// checks if the RRDSET should be offered to viewers
547 +#define rrdset_is_available_for_viewers(st) (rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && !rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE) && (st)->dimensions)
548 +
549 // get the total duration in seconds of the round robin database
550 #define rrdset_duration(st) ((time_t)( (((st)->counter >= ((unsigned long)(st)->entries))?(unsigned long)(st)->entries:(st)->counter) * (st)->update_every ))
551
@@ -617,6 +623,9 @@ extern void rrdfamily_free(RRDHOST *host, RRDFAMILY *rc);
623 #define rrdset_index_del(host, st) (RRDSET *)avl_remove_lock(&((host)->rrdset_root_index), (avl *)(st))
624 extern RRDSET *rrdset_index_del_name(RRDHOST *host, RRDSET *st);
625
626 +extern void rrdset_save(RRDSET *st);
627 +extern void rrdhost_cleanup(RRDHOST *host);
628 +
629 #endif /* NETDATA_RRD_INTERNALS */
630
631
src/rrd2json.c
+43 -489
@@ -83,6 +83,8 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb)
83 size_t c, dimensions = 0, memory = 0, alarms = 0;
84 RRDSET *st;
85
86 + time_t now = now_realtime_sec();
87 +
88 buffer_sprintf(wb, "{\n"
89 "\t\"hostname\": \"%s\""
90 ",\n\t\"version\": \"%s\""
@@ -100,13 +102,15 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb)
102 c = 0;
103 rrdhost_rdlock(host);
104 rrdset_foreach_read(st, host) {
103 - if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
105 + if(rrdset_is_available_for_viewers(st)) {
106 if(c) buffer_strcat(wb, ",");
107 buffer_strcat(wb, "\n\t\t\"");
108 buffer_strcat(wb, st->id);
109 buffer_strcat(wb, "\": ");
110 rrd_stats_api_v1_chart_with_data(st, wb, &dimensions, &memory);
111 +
112 c++;
113 + st->last_accessed_time = now;
114 }
115 }
116
@@ -134,14 +138,15 @@ void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb)
138 if(unlikely(rrd_hosts_available > 1)) {
139 rrd_rdlock();
140 RRDHOST *h;
137 - rrdhost_foreach_read(h)
141 + rrdhost_foreach_read(h) {
142 buffer_sprintf(wb,
139 - "%s\n\t\t{"
140 - "\n\t\t\t\"hostname\": \"%s\""
141 - "\n\t\t}"
142 - , (h != localhost)?",":""
143 - , h->hostname
143 + "%s\n\t\t{"
144 + "\n\t\t\t\"hostname\": \"%s\""
145 + "\n\t\t}"
146 + , (h != localhost) ? "," : ""
147 + , h->hostname
148 );
149 + }
150 rrd_unlock();
151 }
152 else {
@@ -189,7 +194,7 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb) {
194 prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX);
195
196 buffer_strcat(wb, "\n");
192 - if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
197 + if(rrdset_is_available_for_viewers(st)) {
198 rrdset_rdlock(st);
199
200 // for each dimension
@@ -261,7 +266,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
266 shell_name_copy(chart, st->id, SHELL_ELEMENT_MAX);
267
268 buffer_sprintf(wb, "\n# chart: %s (name: %s)\n", st->id, st->name);
264 - if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
269 + if(rrdset_is_available_for_viewers(st)) {
270 rrdset_rdlock(st);
271
272 // for each dimension
@@ -317,157 +322,6 @@ void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb) {
322 rrdhost_unlock(host);
323 }
324
320 -// ----------------------------------------------------------------------------
321 -
322 -unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb)
323 -{
324 - time_t now = now_realtime_sec();
325 -
326 - rrdset_rdlock(st);
327 -
328 - buffer_sprintf(wb,
329 - "\t\t{\n"
330 - "\t\t\t\"id\": \"%s\",\n"
331 - "\t\t\t\"name\": \"%s\",\n"
332 - "\t\t\t\"type\": \"%s\",\n"
333 - "\t\t\t\"family\": \"%s\",\n"
334 - "\t\t\t\"context\": \"%s\",\n"
335 - "\t\t\t\"title\": \"%s\",\n"
336 - "\t\t\t\"priority\": %ld,\n"
337 - "\t\t\t\"enabled\": %d,\n"
338 - "\t\t\t\"units\": \"%s\",\n"
339 - "\t\t\t\"url\": \"/data/%s/%s\",\n"
340 - "\t\t\t\"chart_type\": \"%s\",\n"
341 - "\t\t\t\"counter\": %lu,\n"
342 - "\t\t\t\"entries\": %ld,\n"
343 - "\t\t\t\"first_entry_t\": %ld,\n"
344 - "\t\t\t\"last_entry\": %lu,\n"
345 - "\t\t\t\"last_entry_t\": %ld,\n"
346 - "\t\t\t\"last_entry_secs_ago\": %ld,\n"
347 - "\t\t\t\"update_every\": %d,\n"
348 - "\t\t\t\"isdetail\": %d,\n"
349 - "\t\t\t\"usec_since_last_update\": %llu,\n"
350 - "\t\t\t\"collected_total\": " TOTAL_NUMBER_FORMAT ",\n"
351 - "\t\t\t\"last_collected_total\": " TOTAL_NUMBER_FORMAT ",\n"
352 - "\t\t\t\"dimensions\": [\n"
353 - , st->id
354 - , st->name
355 - , st->type
356 - , st->family
357 - , st->context
358 - , st->title
359 - , st->priority
360 - , rrdset_flag_check(st, RRDSET_FLAG_ENABLED)?1:0
361 - , st->units
362 - , st->name, options?options:""
363 - , rrdset_type_name(st->chart_type)
364 - , st->counter
365 - , st->entries
366 - , rrdset_first_entry_t(st)
367 - , rrdset_last_slot(st)
368 - , rrdset_last_entry_t(st)
369 - , (now < rrdset_last_entry_t(st)) ? (time_t)0 : now - rrdset_last_entry_t(st)
370 - , st->update_every
371 - , rrdset_flag_check(st, RRDSET_FLAG_DETAIL)?1:0
372 - , st->usec_since_last_update
373 - , st->collected_total
374 - , st->last_collected_total
375 - );
376 -
377 - unsigned long memory = st->memsize;
378 -
379 - RRDDIM *rd;
380 - rrddim_foreach_read(rd, st) {
381 -
382 - memory += rd->memsize;
383 -
384 - buffer_sprintf(wb,
385 - "\t\t\t\t{\n"
386 - "\t\t\t\t\t\"id\": \"%s\",\n"
387 - "\t\t\t\t\t\"name\": \"%s\",\n"
388 - "\t\t\t\t\t\"entries\": %ld,\n"
389 - "\t\t\t\t\t\"isHidden\": %d,\n"
390 - "\t\t\t\t\t\"algorithm\": \"%s\",\n"
391 - "\t\t\t\t\t\"multiplier\": " COLLECTED_NUMBER_FORMAT ",\n"
392 - "\t\t\t\t\t\"divisor\": " COLLECTED_NUMBER_FORMAT ",\n"
393 - "\t\t\t\t\t\"last_entry_t\": %ld,\n"
394 - "\t\t\t\t\t\"collected_value\": " COLLECTED_NUMBER_FORMAT ",\n"
395 - "\t\t\t\t\t\"calculated_value\": " CALCULATED_NUMBER_FORMAT ",\n"
396 - "\t\t\t\t\t\"last_collected_value\": " COLLECTED_NUMBER_FORMAT ",\n"
397 - "\t\t\t\t\t\"last_calculated_value\": " CALCULATED_NUMBER_FORMAT ",\n"
398 - "\t\t\t\t\t\"memory\": %lu\n"
399 - "\t\t\t\t}%s\n"
400 - , rd->id
401 - , rd->name
402 - , rd->entries
403 - , rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?1:0
404 - , rrd_algorithm_name(rd->algorithm)
405 - , rd->multiplier
406 - , rd->divisor
407 - , rd->last_collected_time.tv_sec
408 - , rd->collected_value
409 - , rd->calculated_value
410 - , rd->last_collected_value
411 - , rd->last_calculated_value
412 - , rd->memsize
413 - , rd->next?",":""
414 - );
415 - }
416 -
417 - buffer_sprintf(wb,
418 - "\t\t\t],\n"
419 - "\t\t\t\"memory\" : %lu\n"
420 - "\t\t}"
421 - , memory
422 - );
423 -
424 - rrdset_unlock(st);
425 - return memory;
426 -}
427 -
428 -#define RRD_GRAPH_JSON_HEADER "{\n\t\"charts\": [\n"
429 -#define RRD_GRAPH_JSON_FOOTER "\n\t]\n}\n"
430 -
431 -void rrd_stats_graph_json(RRDSET *st, char *options, BUFFER *wb)
432 -{
433 - buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
434 - rrd_stats_one_json(st, options, wb);
435 - buffer_strcat(wb, RRD_GRAPH_JSON_FOOTER);
436 -}
437 -
438 -void rrd_stats_all_json(RRDHOST *host, BUFFER *wb)
439 -{
440 - unsigned long memory = 0;
441 - long c = 0;
442 - RRDSET *st;
443 -
444 - buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
445 -
446 - rrdhost_rdlock(host);
447 - rrdset_foreach_read(st, host) {
448 - if(rrdset_flag_check(st, RRDSET_FLAG_ENABLED) && st->dimensions) {
449 - if(c) buffer_strcat(wb, ",\n");
450 - memory += rrd_stats_one_json(st, NULL, wb);
451 - c++;
452 - }
453 - }
454 - rrdhost_unlock(host);
455 -
456 - buffer_sprintf(wb, "\n\t],\n"
457 - "\t\"hostname\": \"%s\",\n"
458 - "\t\"update_every\": %d,\n"
459 - "\t\"history\": %d,\n"
460 - "\t\"memory\": %lu\n"
461 - "}\n"
462 - , host->hostname
463 - , host->rrd_update_every
464 - , host->rrd_history_entries
465 - , memory
466 - );
467 -}
468 -
469 -
470 -
325 // ----------------------------------------------------------------------------
326
327 // RRDR dimension options
@@ -1665,7 +1519,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1519 );
1520
1521 r->group = group;
1668 - r->update_every = group * st->update_every;
1522 + r->update_every = (int)group * st->update_every;
1523 r->before = now;
1524 r->after = now;
1525
@@ -1817,8 +1671,20 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1671 return r;
1672 }
1673
1820 -int rrd2value(RRDSET *st, BUFFER *wb, calculated_number *n, const char *dimensions, long points, long long after, long long before, int group_method, uint32_t options, time_t *db_after, time_t *db_before, int *value_is_null)
1821 -{
1674 +int rrdset2value_api_v1(
1675 + RRDSET *st
1676 + , BUFFER *wb
1677 + , calculated_number *n
1678 + , const char *dimensions
1679 + , long points
1680 + , long long after
1681 + , long long before
1682 + , int group_method
1683 + , uint32_t options
1684 + , time_t *db_after
1685 + , time_t *db_before
1686 + , int *value_is_null
1687 +) {
1688 RRDR *r = rrd2rrdr(st, points, after, before, group_method, !(options & RRDR_OPTION_NOT_ALIGNED));
1689 if(!r) {
1690 if(value_is_null) *value_is_null = 1;
@@ -1855,8 +1721,20 @@ int rrd2value(RRDSET *st, BUFFER *wb, calculated_number *n, const char *dimensio
1721 return 200;
1722 }
1723
1858 -int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp)
1859 -{
1724 +int rrdset2anything_api_v1(
1725 + RRDSET *st
1726 + , BUFFER *wb
1727 + , BUFFER *dimensions
1728 + , uint32_t format
1729 + , long points
1730 + , long long after
1731 + , long long before
1732 + , int group_method
1733 + , uint32_t options
1734 + , time_t *latest_timestamp
1735 +) {
1736 + st->last_accessed_time = now_realtime_sec();
1737 +
1738 RRDR *r = rrd2rrdr(st, points, after, before, group_method, !(options & RRDR_OPTION_NOT_ALIGNED));
1739 if(!r) {
1740 buffer_strcat(wb, "Cannot generate output with these parameters on this chart.");
@@ -2028,327 +1906,3 @@ int rrd2format(RRDSET *st, BUFFER *wb, BUFFER *dimensions, uint32_t format, long
1906 rrdr_free(r);
1907 return 200;
1908 }
2031 -
2032 -time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long points, long group, int group_method, time_t after, time_t before, int only_non_zero)
2033 -{
2034 - int c;
2035 - rrdset_rdlock(st);
2036 -
2037 -
2038 - // -------------------------------------------------------------------------
2039 - // switch from JSON to google JSON
2040 -
2041 - char kq[2] = "\"";
2042 - char sq[2] = "\"";
2043 - switch(type) {
2044 - case DATASOURCE_DATATABLE_JSON:
2045 - case DATASOURCE_DATATABLE_JSONP:
2046 - kq[0] = '\0';
2047 - sq[0] = '\'';
2048 - break;
2049 -
2050 - case DATASOURCE_JSON:
2051 - default:
2052 - break;
2053 - }
2054 -
2055 -
2056 - // -------------------------------------------------------------------------
2057 - // validate the parameters
2058 -
2059 - if(points < 1) points = 1;
2060 - if(group < 1) group = 1;
2061 -
2062 - if(before == 0 || before > rrdset_last_entry_t(st)) before = rrdset_last_entry_t(st);
2063 - if(after == 0 || after < rrdset_first_entry_t(st)) after = rrdset_first_entry_t(st);
2064 -
2065 - // ---
2066 -
2067 - // our return value (the last timestamp printed)
2068 - // this is required to detect re-transmit in google JSONP
2069 - time_t last_timestamp = 0;
2070 -
2071 -
2072 - // -------------------------------------------------------------------------
2073 - // find how many dimensions we have
2074 -
2075 - int dimensions = 0;
2076 - RRDDIM *rd;
2077 - rrddim_foreach_read(rd, st) dimensions++;
2078 - if(!dimensions) {
2079 - rrdset_unlock(st);
2080 - buffer_strcat(wb, "No dimensions yet.");
2081 - return 0;
2082 - }
2083 -
2084 -
2085 - // -------------------------------------------------------------------------
2086 - // prepare various strings, to speed up the loop
2087 -
2088 - char overflow_annotation[201]; snprintfz(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq);
2089 - char normal_annotation[201]; snprintfz(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq);
2090 - char pre_date[51]; snprintfz(pre_date, 50, " {%sc%s:[{%sv%s:%s", kq, kq, kq, kq, sq);
2091 - char post_date[21]; snprintfz(post_date, 20, "%s}", sq);
2092 - char pre_value[21]; snprintfz(pre_value, 20, ",{%sv%s:", kq, kq);
2093 - char post_value[21]; strcpy(post_value, "}");
2094 -
2095 -
2096 - // -------------------------------------------------------------------------
2097 - // checks for debugging
2098 -
2099 - if(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)) {
2100 - debug(D_RRD_STATS, "%s first_entry_t = %ld, last_entry_t = %ld, duration = %ld, after = %ld, before = %ld, duration = %ld, entries_to_show = %ld, group = %ld"
2101 - , st->id
2102 - , rrdset_first_entry_t(st)
2103 - , rrdset_last_entry_t(st)
2104 - , rrdset_last_entry_t(st) - rrdset_first_entry_t(st)
2105 - , after
2106 - , before
2107 - , before - after
2108 - , points
2109 - , group
2110 - );
2111 -
2112 - if(before < after)
2113 - debug(D_RRD_STATS, "WARNING: %s The newest value in the database (%ld) is earlier than the oldest (%ld)", st->name, before, after);
2114 -
2115 - if((before - after) > st->entries * st->update_every)
2116 - debug(D_RRD_STATS, "WARNING: %s The time difference between the oldest and the newest entries (%ld) is higher than the capacity of the database (%ld)", st->name, before - after, st->entries * st->update_every);
2117 - }
2118 -
2119 -
2120 - // -------------------------------------------------------------------------
2121 - // temp arrays for keeping values per dimension
2122 -
2123 - calculated_number group_values[dimensions]; // keep sums when grouping
2124 - int print_hidden[dimensions]; // keep hidden flags
2125 - int found_non_zero[dimensions];
2126 - int found_non_existing[dimensions];
2127 -
2128 - // initialize them
2129 - for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
2130 - group_values[c] = 0;
2131 - print_hidden[c] = rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?1:0;
2132 - found_non_zero[c] = 0;
2133 - found_non_existing[c] = 0;
2134 - }
2135 -
2136 -
2137 - // error("OLD: points=%d after=%d before=%d group=%d, duration=%d", entries_to_show, before - (st->update_every * group * entries_to_show), before, group, before - after + 1);
2138 - // rrd2array(st, entries_to_show, before - (st->update_every * group * entries_to_show), before, group_method, only_non_zero);
2139 - // rrd2rrdr(st, entries_to_show, before - (st->update_every * group * entries_to_show), before, group_method);
2140 -
2141 - // -------------------------------------------------------------------------
2142 - // remove dimensions that contain only zeros
2143 -
2144 - int max_loop = 1;
2145 - if(only_non_zero) max_loop = 2;
2146 -
2147 - for(; max_loop ; max_loop--) {
2148 -
2149 - // -------------------------------------------------------------------------
2150 - // print the JSON header
2151 -
2152 - buffer_sprintf(wb, "{\n %scols%s:\n [\n", kq, kq);
2153 - buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%stime%s,%spattern%s:%s%s,%stype%s:%sdatetime%s},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq);
2154 - buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotation%s}},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
2155 - buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotationText%s}}", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
2156 -
2157 - // print the header for each dimension
2158 - // and update the print_hidden array for the dimensions that should be hidden
2159 - int pc = 0;
2160 - for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
2161 - if(!print_hidden[c]) {
2162 - pc++;
2163 - buffer_sprintf(wb, ",\n {%sid%s:%s%s,%slabel%s:%s%s%s,%spattern%s:%s%s,%stype%s:%snumber%s}", kq, kq, sq, sq, kq, kq, sq, rd->name, sq, kq, kq, sq, sq, kq, kq, sq, sq);
2164 - }
2165 - }
2166 - if(!pc) {
2167 - buffer_sprintf(wb, ",\n {%sid%s:%s%s,%slabel%s:%s%s%s,%spattern%s:%s%s,%stype%s:%snumber%s}", kq, kq, sq, sq, kq, kq, sq, "no data", sq, kq, kq, sq, sq, kq, kq, sq, sq);
2168 - }
2169 -
2170 - // print the begin of row data
2171 - buffer_sprintf(wb, "\n ],\n %srows%s:\n [\n", kq, kq);
2172 -
2173 -
2174 - // -------------------------------------------------------------------------
2175 - // the main loop
2176 -
2177 - int annotate_reset = 0;
2178 - int annotation_count = 0;
2179 -
2180 - long t = rrdset_time2slot(st, before),
2181 - stop_at_t = rrdset_time2slot(st, after),
2182 - stop_now = 0;
2183 -
2184 - t -= t % group;
2185 -
2186 - time_t now = rrdset_slot2time(st, t),
2187 - dt = st->update_every;
2188 -
2189 - long count = 0, printed = 0, group_count = 0;
2190 - last_timestamp = 0;
2191 -
2192 - if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)))
2193 - debug(D_RRD_STATS, "%s: REQUEST after:%u before:%u, points:%ld, group:%ld, CHART cur:%ld first: %u last:%u, CALC start_t:%ld, stop_t:%ld"
2194 - , st->id
2195 - , (uint32_t)after
2196 - , (uint32_t)before
2197 - , points
2198 - , group
2199 - , st->current_entry
2200 - , (uint32_t)rrdset_first_entry_t(st)
2201 - , (uint32_t)rrdset_last_entry_t(st)
2202 - , t
2203 - , stop_at_t
2204 - );
2205 -
2206 - long counter = 0;
2207 - for(; !stop_now ; now -= dt, t--, counter++) {
2208 - if(t < 0) t = st->entries - 1;
2209 - if(t == stop_at_t) stop_now = counter;
2210 -
2211 - int print_this = 0;
2212 -
2213 - if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)))
2214 - debug(D_RRD_STATS, "%s t = %ld, count = %ld, group_count = %ld, printed = %ld, now = %ld, %s %s"
2215 - , st->id
2216 - , t
2217 - , count + 1
2218 - , group_count + 1
2219 - , printed
2220 - , now
2221 - , (group_count + 1 == group)?"PRINT":" - "
2222 - , (now >= after && now <= before)?"RANGE":" - "
2223 - );
2224 -
2225 -
2226 - // make sure we return data in the proper time range
2227 - if(now > before) continue;
2228 - if(now < after) break;
2229 -
2230 - //if(rrdset_slot2time(st, t) != now)
2231 - // error("%s: slot=%ld, now=%ld, slot2time=%ld, diff=%ld, last_entry_t=%ld, rrdset_last_slot=%ld", st->id, t, now, rrdset_slot2time(st,t), now - rrdset_slot2time(st,t), rrdset_last_entry_t(st), rrdset_last_slot(st));
2232 -
2233 - count++;
2234 - group_count++;
2235 -
2236 - // check if we have to print this now
2237 - if(group_count == group) {
2238 - if(printed >= points) {
2239 - // debug(D_RRD_STATS, "Already printed all rows. Stopping.");
2240 - break;
2241 - }
2242 -
2243 - // generate the local date time
2244 - struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
2245 - if(!tm) { error("localtime() failed."); continue; }
2246 - if(now > last_timestamp) last_timestamp = now;
2247 -
2248 - if(printed) buffer_strcat(wb, "]},\n");
2249 - buffer_strcat(wb, pre_date);
2250 - buffer_jsdate(wb, tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
2251 - buffer_strcat(wb, post_date);
2252 -
2253 - print_this = 1;
2254 - }
2255 -
2256 - // do the calculations
2257 - for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
2258 - storage_number n = rd->values[t];
2259 - calculated_number value = unpack_storage_number(n);
2260 -
2261 - if(!does_storage_number_exist(n)) {
2262 - value = 0.0;
2263 - found_non_existing[c]++;
2264 - }
2265 - if(did_storage_number_reset(n)) annotate_reset = 1;
2266 -
2267 - switch(group_method) {
2268 - case GROUP_MAX:
2269 - if(abs(value) > abs(group_values[c])) group_values[c] = value;
2270 - break;
2271 -
2272 - case GROUP_SUM:
2273 - group_values[c] += value;
2274 - break;
2275 -
2276 - default:
2277 - case GROUP_AVERAGE:
2278 - group_values[c] += value;
2279 - if(print_this) group_values[c] /= ( group_count - found_non_existing[c] );
2280 - break;
2281 - }
2282 - }
2283 -
2284 - if(print_this) {
2285 - if(annotate_reset) {
2286 - annotation_count++;
2287 - buffer_strcat(wb, overflow_annotation);
2288 - annotate_reset = 0;
2289 - }
2290 - else
2291 - buffer_strcat(wb, normal_annotation);
2292 -
2293 - pc = 0;
2294 - for(c = 0 ; c < dimensions ; c++) {
2295 - if(found_non_existing[c] == group_count) {
2296 - // all entries are non-existing
2297 - pc++;
2298 - buffer_strcat(wb, pre_value);
2299 - buffer_strcat(wb, "null");
2300 - buffer_strcat(wb, post_value);
2301 - }
2302 - else if(!print_hidden[c]) {
2303 - pc++;
2304 - buffer_strcat(wb, pre_value);
2305 - buffer_rrd_value(wb, group_values[c]);
2306 - buffer_strcat(wb, post_value);
2307 -
2308 - if(group_values[c]) found_non_zero[c]++;
2309 - }
2310 -
2311 - // reset them for the next loop
2312 - group_values[c] = 0;
2313 - found_non_existing[c] = 0;
2314 - }
2315 -
2316 - // if all dimensions are hidden, print a null
2317 - if(!pc) {
2318 - buffer_strcat(wb, pre_value);
2319 - buffer_strcat(wb, "null");
2320 - buffer_strcat(wb, post_value);
2321 - }
2322 -
2323 - printed++;
2324 - group_count = 0;
2325 - }
2326 - }
2327 -
2328 - if(printed) buffer_strcat(wb, "]}");
2329 - buffer_strcat(wb, "\n ]\n}\n");
2330 -
2331 - if(only_non_zero && max_loop > 1) {
2332 - int changed = 0;
2333 - for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
2334 - group_values[c] = 0;
2335 - found_non_existing[c] = 0;
2336 -
2337 - if(!print_hidden[c] && !found_non_zero[c]) {
2338 - changed = 1;
2339 - print_hidden[c] = 1;
2340 - }
2341 - }
2342 -
2343 - if(changed) buffer_flush(wb);
2344 - else break;
2345 - }
2346 - else break;
2347 -
2348 - } // max_loop
2349 -
2350 - debug(D_RRD_STATS, "RRD_STATS_JSON: %s total %zu bytes", st->name, wb->len);
2351 -
2352 - rrdset_unlock(st);
2353 - return last_timestamp;
2354 -}
src/rrd2json.h
+6 -10
@@ -64,15 +64,11 @@ extern void rrd_stats_api_v1_charts(RRDHOST *host, BUFFER *wb);
64 extern void rrd_stats_api_v1_charts_allmetrics_shell(RRDHOST *host, BUFFER *wb);
65 extern void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER *wb);
66
67 -extern unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb);
68 -
69 -extern void rrd_stats_graph_json(RRDSET *st, char *options, BUFFER *wb);
70 -
71 -extern void rrd_stats_all_json(RRDHOST *host, BUFFER *wb);
72 -
73 -extern time_t rrd_stats_json(int type, RRDSET *st, BUFFER *wb, long entries_to_show, long group, int group_method, time_t after, time_t before, int only_non_zero);
74 -
75 -extern int rrd2format(RRDSET *st, BUFFER *out, BUFFER *dimensions, uint32_t format, long points, long long after, long long before, int group_method, uint32_t options, time_t *latest_timestamp);
76 -extern int rrd2value(RRDSET *st, BUFFER *wb, calculated_number *n, const char *dimensions, long points, long long after, long long before, int group_method, uint32_t options, time_t *db_before, time_t *db_after, int *value_is_null);
67 +extern int rrdset2anything_api_v1(RRDSET *st, BUFFER *out, BUFFER *dimensions, uint32_t format, long points
68 + , long long after, long long before, int group_method, uint32_t options
69 + , time_t *latest_timestamp);
70 +extern int rrdset2value_api_v1(RRDSET *st, BUFFER *wb, calculated_number *n, const char *dimensions, long points
71 + , long long after, long long before, int group_method, uint32_t options
72 + , time_t *db_before, time_t *db_after, int *value_is_null);
73
74 #endif /* NETDATA_RRD2JSON_H */
src/rrd2json_api_old.c new
+487
@@ -0,0 +1,487 @@
1 +#include "common.h"
2 +
3 +unsigned long rrdset_info2json_api_old(RRDSET *st, char *options, BUFFER *wb) {
4 + time_t now = now_realtime_sec();
5 +
6 + rrdset_rdlock(st);
7 +
8 + st->last_accessed_time = now;
9 +
10 + buffer_sprintf(wb,
11 + "\t\t{\n"
12 + "\t\t\t\"id\": \"%s\",\n"
13 + "\t\t\t\"name\": \"%s\",\n"
14 + "\t\t\t\"type\": \"%s\",\n"
15 + "\t\t\t\"family\": \"%s\",\n"
16 + "\t\t\t\"context\": \"%s\",\n"
17 + "\t\t\t\"title\": \"%s\",\n"
18 + "\t\t\t\"priority\": %ld,\n"
19 + "\t\t\t\"enabled\": %d,\n"
20 + "\t\t\t\"units\": \"%s\",\n"
21 + "\t\t\t\"url\": \"/data/%s/%s\",\n"
22 + "\t\t\t\"chart_type\": \"%s\",\n"
23 + "\t\t\t\"counter\": %lu,\n"
24 + "\t\t\t\"entries\": %ld,\n"
25 + "\t\t\t\"first_entry_t\": %ld,\n"
26 + "\t\t\t\"last_entry\": %lu,\n"
27 + "\t\t\t\"last_entry_t\": %ld,\n"
28 + "\t\t\t\"last_entry_secs_ago\": %ld,\n"
29 + "\t\t\t\"update_every\": %d,\n"
30 + "\t\t\t\"isdetail\": %d,\n"
31 + "\t\t\t\"usec_since_last_update\": %llu,\n"
32 + "\t\t\t\"collected_total\": " TOTAL_NUMBER_FORMAT ",\n"
33 + "\t\t\t\"last_collected_total\": " TOTAL_NUMBER_FORMAT ",\n"
34 + "\t\t\t\"dimensions\": [\n"
35 + , st->id
36 + , st->name
37 + , st->type
38 + , st->family
39 + , st->context
40 + , st->title
41 + , st->priority
42 + , rrdset_flag_check(st, RRDSET_FLAG_ENABLED)?1:0
43 + , st->units
44 + , st->name, options?options:""
45 + , rrdset_type_name(st->chart_type)
46 + , st->counter
47 + , st->entries
48 + , rrdset_first_entry_t(st)
49 + , rrdset_last_slot(st)
50 + , rrdset_last_entry_t(st)
51 + , (now < rrdset_last_entry_t(st)) ? (time_t)0 : now - rrdset_last_entry_t(st)
52 + , st->update_every
53 + , rrdset_flag_check(st, RRDSET_FLAG_DETAIL)?1:0
54 + , st->usec_since_last_update
55 + , st->collected_total
56 + , st->last_collected_total
57 + );
58 +
59 + unsigned long memory = st->memsize;
60 +
61 + RRDDIM *rd;
62 + rrddim_foreach_read(rd, st) {
63 +
64 + memory += rd->memsize;
65 +
66 + buffer_sprintf(wb,
67 + "\t\t\t\t{\n"
68 + "\t\t\t\t\t\"id\": \"%s\",\n"
69 + "\t\t\t\t\t\"name\": \"%s\",\n"
70 + "\t\t\t\t\t\"entries\": %ld,\n"
71 + "\t\t\t\t\t\"isHidden\": %d,\n"
72 + "\t\t\t\t\t\"algorithm\": \"%s\",\n"
73 + "\t\t\t\t\t\"multiplier\": " COLLECTED_NUMBER_FORMAT ",\n"
74 + "\t\t\t\t\t\"divisor\": " COLLECTED_NUMBER_FORMAT ",\n"
75 + "\t\t\t\t\t\"last_entry_t\": %ld,\n"
76 + "\t\t\t\t\t\"collected_value\": " COLLECTED_NUMBER_FORMAT ",\n"
77 + "\t\t\t\t\t\"calculated_value\": " CALCULATED_NUMBER_FORMAT ",\n"
78 + "\t\t\t\t\t\"last_collected_value\": " COLLECTED_NUMBER_FORMAT ",\n"
79 + "\t\t\t\t\t\"last_calculated_value\": " CALCULATED_NUMBER_FORMAT ",\n"
80 + "\t\t\t\t\t\"memory\": %lu\n"
81 + "\t\t\t\t}%s\n"
82 + , rd->id
83 + , rd->name
84 + , rd->entries
85 + , rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?1:0
86 + , rrd_algorithm_name(rd->algorithm)
87 + , rd->multiplier
88 + , rd->divisor
89 + , rd->last_collected_time.tv_sec
90 + , rd->collected_value
91 + , rd->calculated_value
92 + , rd->last_collected_value
93 + , rd->last_calculated_value
94 + , rd->memsize
95 + , rd->next?",":""
96 + );
97 + }
98 +
99 + buffer_sprintf(wb,
100 + "\t\t\t],\n"
101 + "\t\t\t\"memory\" : %lu\n"
102 + "\t\t}"
103 + , memory
104 + );
105 +
106 + rrdset_unlock(st);
107 + return memory;
108 +}
109 +
110 +#define RRD_GRAPH_JSON_HEADER "{\n\t\"charts\": [\n"
111 +#define RRD_GRAPH_JSON_FOOTER "\n\t]\n}\n"
112 +
113 +void rrd_graph2json_api_old(RRDSET *st, char *options, BUFFER *wb)
114 +{
115 + buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
116 + rrdset_info2json_api_old(st, options, wb);
117 + buffer_strcat(wb, RRD_GRAPH_JSON_FOOTER);
118 +}
119 +
120 +void rrd_all2json_api_old(RRDHOST *host, BUFFER *wb)
121 +{
122 + unsigned long memory = 0;
123 + long c = 0;
124 + RRDSET *st;
125 +
126 + time_t now = now_realtime_sec();
127 +
128 + buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
129 +
130 + rrdhost_rdlock(host);
131 + rrdset_foreach_read(st, host) {
132 + if(rrdset_is_available_for_viewers(st)) {
133 + if(c) buffer_strcat(wb, ",\n");
134 + memory += rrdset_info2json_api_old(st, NULL, wb);
135 +
136 + c++;
137 + st->last_accessed_time = now;
138 + }
139 + }
140 + rrdhost_unlock(host);
141 +
142 + buffer_sprintf(wb, "\n\t],\n"
143 + "\t\"hostname\": \"%s\",\n"
144 + "\t\"update_every\": %d,\n"
145 + "\t\"history\": %d,\n"
146 + "\t\"memory\": %lu\n"
147 + "}\n"
148 + , host->hostname
149 + , host->rrd_update_every
150 + , host->rrd_history_entries
151 + , memory
152 + );
153 +}
154 +
155 +time_t rrdset2json_api_old(
156 + int type
157 + , RRDSET *st
158 + , BUFFER *wb
159 + , long points
160 + , long group
161 + , int group_method
162 + , time_t after
163 + , time_t before
164 + , int only_non_zero
165 +) {
166 + int c;
167 + rrdset_rdlock(st);
168 +
169 + st->last_accessed_time = now_realtime_sec();
170 +
171 + // -------------------------------------------------------------------------
172 + // switch from JSON to google JSON
173 +
174 + char kq[2] = "\"";
175 + char sq[2] = "\"";
176 + switch(type) {
177 + case DATASOURCE_DATATABLE_JSON:
178 + case DATASOURCE_DATATABLE_JSONP:
179 + kq[0] = '\0';
180 + sq[0] = '\'';
181 + break;
182 +
183 + case DATASOURCE_JSON:
184 + default:
185 + break;
186 + }
187 +
188 +
189 + // -------------------------------------------------------------------------
190 + // validate the parameters
191 +
192 + if(points < 1) points = 1;
193 + if(group < 1) group = 1;
194 +
195 + if(before == 0 || before > rrdset_last_entry_t(st)) before = rrdset_last_entry_t(st);
196 + if(after == 0 || after < rrdset_first_entry_t(st)) after = rrdset_first_entry_t(st);
197 +
198 + // ---
199 +
200 + // our return value (the last timestamp printed)
201 + // this is required to detect re-transmit in google JSONP
202 + time_t last_timestamp = 0;
203 +
204 +
205 + // -------------------------------------------------------------------------
206 + // find how many dimensions we have
207 +
208 + int dimensions = 0;
209 + RRDDIM *rd;
210 + rrddim_foreach_read(rd, st) dimensions++;
211 + if(!dimensions) {
212 + rrdset_unlock(st);
213 + buffer_strcat(wb, "No dimensions yet.");
214 + return 0;
215 + }
216 +
217 +
218 + // -------------------------------------------------------------------------
219 + // prepare various strings, to speed up the loop
220 +
221 + char overflow_annotation[201]; snprintfz(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq);
222 + char normal_annotation[201]; snprintfz(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq);
223 + char pre_date[51]; snprintfz(pre_date, 50, " {%sc%s:[{%sv%s:%s", kq, kq, kq, kq, sq);
224 + char post_date[21]; snprintfz(post_date, 20, "%s}", sq);
225 + char pre_value[21]; snprintfz(pre_value, 20, ",{%sv%s:", kq, kq);
226 + char post_value[21]; strcpy(post_value, "}");
227 +
228 +
229 + // -------------------------------------------------------------------------
230 + // checks for debugging
231 +
232 + if(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)) {
233 + debug(D_RRD_STATS, "%s first_entry_t = %ld, last_entry_t = %ld, duration = %ld, after = %ld, before = %ld, duration = %ld, entries_to_show = %ld, group = %ld"
234 + , st->id
235 + , rrdset_first_entry_t(st)
236 + , rrdset_last_entry_t(st)
237 + , rrdset_last_entry_t(st) - rrdset_first_entry_t(st)
238 + , after
239 + , before
240 + , before - after
241 + , points
242 + , group
243 + );
244 +
245 + if(before < after)
246 + debug(D_RRD_STATS, "WARNING: %s The newest value in the database (%ld) is earlier than the oldest (%ld)", st->name, before, after);
247 +
248 + if((before - after) > st->entries * st->update_every)
249 + debug(D_RRD_STATS, "WARNING: %s The time difference between the oldest and the newest entries (%ld) is higher than the capacity of the database (%ld)", st->name, before - after, st->entries * st->update_every);
250 + }
251 +
252 +
253 + // -------------------------------------------------------------------------
254 + // temp arrays for keeping values per dimension
255 +
256 + calculated_number group_values[dimensions]; // keep sums when grouping
257 + int print_hidden[dimensions]; // keep hidden flags
258 + int found_non_zero[dimensions];
259 + int found_non_existing[dimensions];
260 +
261 + // initialize them
262 + for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
263 + group_values[c] = 0;
264 + print_hidden[c] = rrddim_flag_check(rd, RRDDIM_FLAG_HIDDEN)?1:0;
265 + found_non_zero[c] = 0;
266 + found_non_existing[c] = 0;
267 + }
268 +
269 +
270 + // error("OLD: points=%d after=%d before=%d group=%d, duration=%d", entries_to_show, before - (st->update_every * group * entries_to_show), before, group, before - after + 1);
271 + // rrd2array(st, entries_to_show, before - (st->update_every * group * entries_to_show), before, group_method, only_non_zero);
272 + // rrd2rrdr(st, entries_to_show, before - (st->update_every * group * entries_to_show), before, group_method);
273 +
274 + // -------------------------------------------------------------------------
275 + // remove dimensions that contain only zeros
276 +
277 + int max_loop = 1;
278 + if(only_non_zero) max_loop = 2;
279 +
280 + for(; max_loop ; max_loop--) {
281 +
282 + // -------------------------------------------------------------------------
283 + // print the JSON header
284 +
285 + buffer_sprintf(wb, "{\n %scols%s:\n [\n", kq, kq);
286 + buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%stime%s,%spattern%s:%s%s,%stype%s:%sdatetime%s},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq);
287 + buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotation%s}},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
288 + buffer_sprintf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotationText%s}}", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
289 +
290 + // print the header for each dimension
291 + // and update the print_hidden array for the dimensions that should be hidden
292 + int pc = 0;
293 + for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
294 + if(!print_hidden[c]) {
295 + pc++;
296 + buffer_sprintf(wb, ",\n {%sid%s:%s%s,%slabel%s:%s%s%s,%spattern%s:%s%s,%stype%s:%snumber%s}", kq, kq, sq, sq, kq, kq, sq, rd->name, sq, kq, kq, sq, sq, kq, kq, sq, sq);
297 + }
298 + }
299 + if(!pc) {
300 + buffer_sprintf(wb, ",\n {%sid%s:%s%s,%slabel%s:%s%s%s,%spattern%s:%s%s,%stype%s:%snumber%s}", kq, kq, sq, sq, kq, kq, sq, "no data", sq, kq, kq, sq, sq, kq, kq, sq, sq);
301 + }
302 +
303 + // print the begin of row data
304 + buffer_sprintf(wb, "\n ],\n %srows%s:\n [\n", kq, kq);
305 +
306 +
307 + // -------------------------------------------------------------------------
308 + // the main loop
309 +
310 + int annotate_reset = 0;
311 + int annotation_count = 0;
312 +
313 + long t = rrdset_time2slot(st, before),
314 + stop_at_t = rrdset_time2slot(st, after),
315 + stop_now = 0;
316 +
317 + t -= t % group;
318 +
319 + time_t now = rrdset_slot2time(st, t),
320 + dt = st->update_every;
321 +
322 + long count = 0, printed = 0, group_count = 0;
323 + last_timestamp = 0;
324 +
325 + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)))
326 + debug(D_RRD_STATS, "%s: REQUEST after:%u before:%u, points:%ld, group:%ld, CHART cur:%ld first: %u last:%u, CALC start_t:%ld, stop_t:%ld"
327 + , st->id
328 + , (uint32_t)after
329 + , (uint32_t)before
330 + , points
331 + , group
332 + , st->current_entry
333 + , (uint32_t)rrdset_first_entry_t(st)
334 + , (uint32_t)rrdset_last_entry_t(st)
335 + , t
336 + , stop_at_t
337 + );
338 +
339 + long counter = 0;
340 + for(; !stop_now ; now -= dt, t--, counter++) {
341 + if(t < 0) t = st->entries - 1;
342 + if(t == stop_at_t) stop_now = counter;
343 +
344 + int print_this = 0;
345 +
346 + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_DEBUG)))
347 + debug(D_RRD_STATS, "%s t = %ld, count = %ld, group_count = %ld, printed = %ld, now = %ld, %s %s"
348 + , st->id
349 + , t
350 + , count + 1
351 + , group_count + 1
352 + , printed
353 + , now
354 + , (group_count + 1 == group)?"PRINT":" - "
355 + , (now >= after && now <= before)?"RANGE":" - "
356 + );
357 +
358 +
359 + // make sure we return data in the proper time range
360 + if(now > before) continue;
361 + if(now < after) break;
362 +
363 + //if(rrdset_slot2time(st, t) != now)
364 + // error("%s: slot=%ld, now=%ld, slot2time=%ld, diff=%ld, last_entry_t=%ld, rrdset_last_slot=%ld", st->id, t, now, rrdset_slot2time(st,t), now - rrdset_slot2time(st,t), rrdset_last_entry_t(st), rrdset_last_slot(st));
365 +
366 + count++;
367 + group_count++;
368 +
369 + // check if we have to print this now
370 + if(group_count == group) {
371 + if(printed >= points) {
372 + // debug(D_RRD_STATS, "Already printed all rows. Stopping.");
373 + break;
374 + }
375 +
376 + // generate the local date time
377 + struct tm tmbuf, *tm = localtime_r(&now, &tmbuf);
378 + if(!tm) { error("localtime() failed."); continue; }
379 + if(now > last_timestamp) last_timestamp = now;
380 +
381 + if(printed) buffer_strcat(wb, "]},\n");
382 + buffer_strcat(wb, pre_date);
383 + buffer_jsdate(wb, tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
384 + buffer_strcat(wb, post_date);
385 +
386 + print_this = 1;
387 + }
388 +
389 + // do the calculations
390 + for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
391 + storage_number n = rd->values[t];
392 + calculated_number value = unpack_storage_number(n);
393 +
394 + if(!does_storage_number_exist(n)) {
395 + value = 0.0;
396 + found_non_existing[c]++;
397 + }
398 + if(did_storage_number_reset(n)) annotate_reset = 1;
399 +
400 + switch(group_method) {
401 + case GROUP_MAX:
402 + if(abs(value) > abs(group_values[c])) group_values[c] = value;
403 + break;
404 +
405 + case GROUP_SUM:
406 + group_values[c] += value;
407 + break;
408 +
409 + default:
410 + case GROUP_AVERAGE:
411 + group_values[c] += value;
412 + if(print_this) group_values[c] /= ( group_count - found_non_existing[c] );
413 + break;
414 + }
415 + }
416 +
417 + if(print_this) {
418 + if(annotate_reset) {
419 + annotation_count++;
420 + buffer_strcat(wb, overflow_annotation);
421 + annotate_reset = 0;
422 + }
423 + else
424 + buffer_strcat(wb, normal_annotation);
425 +
426 + pc = 0;
427 + for(c = 0 ; c < dimensions ; c++) {
428 + if(found_non_existing[c] == group_count) {
429 + // all entries are non-existing
430 + pc++;
431 + buffer_strcat(wb, pre_value);
432 + buffer_strcat(wb, "null");
433 + buffer_strcat(wb, post_value);
434 + }
435 + else if(!print_hidden[c]) {
436 + pc++;
437 + buffer_strcat(wb, pre_value);
438 + buffer_rrd_value(wb, group_values[c]);
439 + buffer_strcat(wb, post_value);
440 +
441 + if(group_values[c]) found_non_zero[c]++;
442 + }
443 +
444 + // reset them for the next loop
445 + group_values[c] = 0;
446 + found_non_existing[c] = 0;
447 + }
448 +
449 + // if all dimensions are hidden, print a null
450 + if(!pc) {
451 + buffer_strcat(wb, pre_value);
452 + buffer_strcat(wb, "null");
453 + buffer_strcat(wb, post_value);
454 + }
455 +
456 + printed++;
457 + group_count = 0;
458 + }
459 + }
460 +
461 + if(printed) buffer_strcat(wb, "]}");
462 + buffer_strcat(wb, "\n ]\n}\n");
463 +
464 + if(only_non_zero && max_loop > 1) {
465 + int changed = 0;
466 + for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
467 + group_values[c] = 0;
468 + found_non_existing[c] = 0;
469 +
470 + if(!print_hidden[c] && !found_non_zero[c]) {
471 + changed = 1;
472 + print_hidden[c] = 1;
473 + }
474 + }
475 +
476 + if(changed) buffer_flush(wb);
477 + else break;
478 + }
479 + else break;
480 +
481 + } // max_loop
482 +
483 + debug(D_RRD_STATS, "RRD_STATS_JSON: %s total %zu bytes", st->name, wb->len);
484 +
485 + rrdset_unlock(st);
486 + return last_timestamp;
487 +}
src/rrd2json_api_old.h new
+14
@@ -0,0 +1,14 @@
1 +#ifndef NETDATA_RRD2JSON_API_OLD_H
2 +#define NETDATA_RRD2JSON_API_OLD_H
3 +
4 +extern unsigned long rrdset_info2json_api_old(RRDSET *st, char *options, BUFFER *wb);
5 +
6 +extern void rrd_graph2json_api_old(RRDSET *st, char *options, BUFFER *wb);
7 +
8 +extern void rrd_all2json_api_old(RRDHOST *host, BUFFER *wb);
9 +
10 +extern time_t rrdset2json_api_old(int type, RRDSET *st, BUFFER *wb, long entries_to_show, long group, int group_method
11 + , time_t after, time_t before, int only_non_zero);
12 +
13 +
14 +#endif //NETDATA_RRD2JSON_API_OLD_H
src/rrdhost.c
+33 -16
@@ -5,6 +5,7 @@ RRDHOST *localhost = NULL;
5 size_t rrd_hosts_available = 0;
6 pthread_rwlock_t rrd_rwlock = PTHREAD_RWLOCK_INITIALIZER;
7
8 +time_t rrdset_free_obsolete_time = 3600;
9 time_t rrdhost_free_orphan_time = 3600;
10
11 // ----------------------------------------------------------------------------
@@ -315,18 +316,22 @@ RRDHOST *rrdhost_find_or_create(
316 }
317
318 void rrdhost_cleanup_remote_stale(RRDHOST *protected) {
319 + time_t now = now_realtime_sec();
320 +
321 rrd_wrlock();
322
323 RRDHOST *h;
324 +
325 +restart_after_removal:
326 rrdhost_foreach_write(h) {
327 if(h != protected
328 && h != localhost
329 && !h->connected_senders
325 - && h->senders_disconnected_time + rrdhost_free_orphan_time > now_realtime_sec()) {
330 + && h->senders_disconnected_time + rrdhost_free_orphan_time < now) {
331 info("Host '%s' with machine guid '%s' is obsolete - cleaning up.", h->hostname, h->machine_guid);
332 rrdhost_save(h);
333 rrdhost_free(h);
329 - break;
334 + goto restart_after_removal;
335 }
336 }
337
@@ -337,6 +342,8 @@ void rrdhost_cleanup_remote_stale(RRDHOST *protected) {
342 // RRDHOST global / startup initialization
343
344 void rrd_init(char *hostname) {
345 + rrdset_free_obsolete_time = config_get_number(CONFIG_SECTION_GLOBAL, "cleanup obsolete charts after seconds", rrdset_free_obsolete_time);
346 +
347 health_init();
348 registry_init();
349 rrdpush_init();
@@ -472,7 +479,6 @@ void rrdhost_save(RRDHOST *host) {
479 info("Saving database of host '%s'...", host->hostname);
480
481 RRDSET *st;
475 - RRDDIM *rd;
482
483 // we get a write lock
484 // to ensure only one thread is saving the database
@@ -480,19 +486,7 @@ void rrdhost_save(RRDHOST *host) {
486
487 rrdset_foreach_write(st, host) {
488 rrdset_rdlock(st);
483 -
484 - if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
485 - debug(D_RRD_STATS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename);
486 - savememory(st->cache_filename, st, st->memsize);
487 - }
488 -
489 - rrddim_foreach_read(rd, st) {
490 - if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE)) {
491 - debug(D_RRD_STATS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename);
492 - savememory(rd->cache_filename, rd, rd->memsize);
493 - }
494 - }
495 -
489 + rrdset_save(st);
490 rrdset_unlock(st);
491 }
492
@@ -510,3 +504,26 @@ void rrdhost_save_all(void) {
504
505 rrd_unlock();
506 }
507 +
508 +void rrdhost_cleanup(RRDHOST *host) {
509 + time_t now = now_realtime_sec();
510 +
511 + RRDSET *st;
512 +
513 +restart_after_removal:
514 + rrdset_foreach_write(st, host) {
515 + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE)
516 + && st->last_accessed_time + rrdset_free_obsolete_time < now
517 + && st->last_updated.tv_sec + rrdset_free_obsolete_time < now
518 + && st->last_collected_time.tv_sec + rrdset_free_obsolete_time < now
519 + )) {
520 +
521 + rrdset_rdlock(st);
522 + rrdset_save(st);
523 + rrdset_unlock(st);
524 +
525 + rrdset_free(st);
526 + goto restart_after_removal;
527 + }
528 + }
529 +}
src/rrdset.c
+52 -12
@@ -234,14 +234,7 @@ void rrdset_free(RRDSET *st) {
234 rrdhost_check_wrlock(st->rrdhost); // make sure we have a write lock on the host
235 rrdset_wrlock(st); // lock this RRDSET
236
237 - // ------------------------------------------------------------------------
238 - // free its children structures
239 -
240 - while(st->variables) rrdsetvar_free(st->variables);
241 - while(st->alarms) rrdsetcalc_unlink(st->alarms);
242 - while(st->dimensions) rrddim_free(st, st->dimensions);
243 -
244 - rrdfamily_free(st->rrdhost, st->rrdfamily);
237 + // info("Removing chart '%s' ('%s')", st->id, st->name);
238
239 // ------------------------------------------------------------------------
240 // remove it from the indexes
@@ -251,6 +244,15 @@ void rrdset_free(RRDSET *st) {
244
245 rrdset_index_del_name(st->rrdhost, st);
246
247 + // ------------------------------------------------------------------------
248 + // free its children structures
249 +
250 + while(st->variables) rrdsetvar_free(st->variables);
251 + while(st->alarms) rrdsetcalc_unlink(st->alarms);
252 + while(st->dimensions) rrddim_free(st, st->dimensions);
253 +
254 + rrdfamily_free(st->rrdhost, st->rrdfamily);
255 +
256 // ------------------------------------------------------------------------
257 // unlink it from the host
258
@@ -283,13 +285,42 @@ void rrdset_free(RRDSET *st) {
285 freez(st);
286 }
287
288 +void rrdset_save(RRDSET *st) {
289 + RRDDIM *rd;
290 +
291 + rrdset_check_rdlock(st);
292 +
293 + // info("Saving chart '%s' ('%s')", st->id, st->name);
294 +
295 + if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
296 + debug(D_RRD_STATS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename);
297 + savememory(st->cache_filename, st, st->memsize);
298 + }
299 +
300 + rrddim_foreach_read(rd, st) {
301 + if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE)) {
302 + debug(D_RRD_STATS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename);
303 + savememory(rd->cache_filename, rd, rd->memsize);
304 + }
305 + }
306 +}
307 +
308 // ----------------------------------------------------------------------------
309 // RRDSET - create a chart
310
289 -RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const char *name, const char *family
290 - , const char *context, const char *title, const char *units, long priority
291 - , int update_every, RRDSET_TYPE chart_type) {
292 -
311 +RRDSET *rrdset_create(
312 + RRDHOST *host
313 + , const char *type
314 + , const char *id
315 + , const char *name
316 + , const char *family
317 + , const char *context
318 + , const char *title
319 + , const char *units
320 + , long priority
321 + , int update_every
322 + , RRDSET_TYPE chart_type
323 +) {
324 if(!type || !type[0]) {
325 fatal("Cannot create rrd stats without a type.");
326 return NULL;
@@ -308,6 +339,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
339
340 RRDSET *st = rrdset_find(host, fullid);
341 if(st) {
342 + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
343 debug(D_RRD_CALLS, "RRDSET '%s', already exists.", fullid);
344 return st;
345 }
@@ -449,6 +481,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
481
482 rrdset_flag_clear(st, RRDSET_FLAG_DETAIL);
483 rrdset_flag_clear(st, RRDSET_FLAG_DEBUG);
484 + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
485
486 // if(!strcmp(st->id, "disk_util.dm-0")) {
487 // st->debug = 1;
@@ -502,6 +535,8 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
535 rrdsetcalc_link_matching(st);
536 rrdcalctemplate_link_matching(st);
537
538 + rrdhost_cleanup(host);
539 +
540 rrdhost_unlock(host);
541
542 return(st);
@@ -677,6 +712,11 @@ void rrdset_done(RRDSET *st) {
712 st->enabled = 1;
713 */
714
715 + if(unlikely(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE))) {
716 + error("Chart '%s' has the OBSOLETE flag set, but it is collected.", st->id);
717 + rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
718 + }
719 +
720 // check if the chart has a long time to be updated
721 if(unlikely(st->usec_since_last_update > st->entries * update_every_ut)) {
722 info("%s: took too long to be updated (%0.3Lf secs). Resetting it.", st->name, (long double)(st->usec_since_last_update / 1000000.0));
src/sys_fs_cgroup.c
+603 -290
@@ -881,6 +881,21 @@ static inline struct cgroup *cgroup_add(const char *id) {
881 static inline void cgroup_free(struct cgroup *cg) {
882 debug(D_CGROUP, "Removing cgroup '%s' with chart id '%s' (was %s and %s)", cg->id, cg->chart_id, (cg->enabled)?"enabled":"disabled", (cg->available)?"available":"not available");
883
884 + if(cg->st_cpu) rrdset_flag_set(cg->st_cpu, RRDSET_FLAG_OBSOLETE);
885 + if(cg->st_cpu_per_core) rrdset_flag_set(cg->st_cpu_per_core, RRDSET_FLAG_OBSOLETE);
886 + if(cg->st_mem) rrdset_flag_set(cg->st_mem, RRDSET_FLAG_OBSOLETE);
887 + if(cg->st_writeback) rrdset_flag_set(cg->st_writeback, RRDSET_FLAG_OBSOLETE);
888 + if(cg->st_mem_activity) rrdset_flag_set(cg->st_mem_activity, RRDSET_FLAG_OBSOLETE);
889 + if(cg->st_pgfaults) rrdset_flag_set(cg->st_pgfaults, RRDSET_FLAG_OBSOLETE);
890 + if(cg->st_mem_usage) rrdset_flag_set(cg->st_mem_usage, RRDSET_FLAG_OBSOLETE);
891 + if(cg->st_mem_failcnt) rrdset_flag_set(cg->st_mem_failcnt, RRDSET_FLAG_OBSOLETE);
892 + if(cg->st_io) rrdset_flag_set(cg->st_io, RRDSET_FLAG_OBSOLETE);
893 + if(cg->st_serviced_ops) rrdset_flag_set(cg->st_serviced_ops, RRDSET_FLAG_OBSOLETE);
894 + if(cg->st_throttle_io) rrdset_flag_set(cg->st_throttle_io, RRDSET_FLAG_OBSOLETE);
895 + if(cg->st_throttle_serviced_ops) rrdset_flag_set(cg->st_throttle_serviced_ops, RRDSET_FLAG_OBSOLETE);
896 + if(cg->st_queued_ops) rrdset_flag_set(cg->st_queued_ops, RRDSET_FLAG_OBSOLETE);
897 + if(cg->st_merged_ops) rrdset_flag_set(cg->st_merged_ops, RRDSET_FLAG_OBSOLETE);
898 +
899 freez(cg->cpuacct_usage.cpu_percpu);
900
901 freez(cg->cpuacct_stat.filename);
@@ -1266,18 +1281,19 @@ static inline void find_all_cgroups() {
1281
1282 #define CHART_TITLE_MAX 300
1283
1269 -void update_services_charts(int update_every,
1270 - int do_cpu,
1271 - int do_mem_usage,
1272 - int do_mem_detailed,
1273 - int do_mem_failcnt,
1274 - int do_swap_usage,
1275 - int do_io,
1276 - int do_io_ops,
1277 - int do_throttle_io,
1278 - int do_throttle_ops,
1279 - int do_queued_ops,
1280 - int do_merged_ops
1284 +void update_systemd_services_charts(
1285 + int update_every
1286 + , int do_cpu
1287 + , int do_mem_usage
1288 + , int do_mem_detailed
1289 + , int do_mem_failcnt
1290 + , int do_swap_usage
1291 + , int do_io
1292 + , int do_io_ops
1293 + , int do_throttle_io
1294 + , int do_throttle_ops
1295 + , int do_queued_ops
1296 + , int do_merged_ops
1297 ) {
1298 static RRDSET
1299 *st_cpu = NULL,
@@ -1313,13 +1329,21 @@ void update_services_charts(int update_every,
1329 if(likely(do_cpu)) {
1330 if(unlikely(!st_cpu)) {
1331 char title[CHART_TITLE_MAX + 1];
1332 + snprintfz(title, CHART_TITLE_MAX, "Systemd Services CPU utilization (%d%% = %d core%s)", (processors * 100), processors, (processors > 1) ? "s" : "");
1333 +
1334 + st_cpu = rrdset_create_localhost(
1335 + "services"
1336 + , "cpu"
1337 + , NULL
1338 + , "cpu"
1339 + , "services.cpu"
1340 + , title
1341 + , "%"
1342 + , CHART_PRIORITY_SYSTEMD_SERVICES
1343 + , update_every
1344 + , RRDSET_TYPE_STACKED
1345 + );
1346
1317 - st_cpu = rrdset_find_bytype_localhost("services", "cpu");
1318 - if(likely(!st_cpu)) {
1319 - snprintfz(title, CHART_TITLE_MAX, "Systemd Services CPU utilization (%d%% = %d core%s)", (processors * 100), processors, (processors > 1) ? "s" : "");
1320 - st_cpu = rrdset_create_localhost("services", "cpu", NULL, "cpu", "services.cpu", title, "%"
1321 - , CHART_PRIORITY_SYSTEMD_SERVICES, update_every, RRDSET_TYPE_STACKED);
1322 - }
1347 }
1348 else
1349 rrdset_next(st_cpu);
@@ -1327,13 +1351,21 @@ void update_services_charts(int update_every,
1351
1352 if(likely(do_mem_usage)) {
1353 if(unlikely(!st_mem_usage)) {
1330 - st_mem_usage = rrdset_find_bytype_localhost("services", "mem_usage");
1331 - if(likely(!st_mem_usage))
1332 - st_mem_usage = rrdset_create_localhost("services", "mem_usage", NULL, "mem", "services.mem_usage"
1333 - , (cgroup_used_memory_without_cache)
1334 - ? "Systemd Services Used Memory without Cache"
1335 - : "Systemd Services Used Memory", "MB",
1336 - CHART_PRIORITY_SYSTEMD_SERVICES + 10, update_every, RRDSET_TYPE_STACKED);
1354 +
1355 + st_mem_usage = rrdset_create_localhost(
1356 + "services"
1357 + , "mem_usage"
1358 + , NULL
1359 + , "mem"
1360 + , "services.mem_usage"
1361 + , (cgroup_used_memory_without_cache) ? "Systemd Services Used Memory without Cache"
1362 + : "Systemd Services Used Memory"
1363 + , "MB"
1364 + , CHART_PRIORITY_SYSTEMD_SERVICES + 10
1365 + , update_every
1366 + , RRDSET_TYPE_STACKED
1367 + );
1368 +
1369 }
1370 else
1371 rrdset_next(st_mem_usage);
@@ -1341,90 +1373,152 @@ void update_services_charts(int update_every,
1373
1374 if(likely(do_mem_detailed)) {
1375 if(unlikely(!st_mem_detailed_rss)) {
1344 - st_mem_detailed_rss = rrdset_find_bytype_localhost("services", "mem_rss");
1345 - if(likely(!st_mem_detailed_rss))
1346 - st_mem_detailed_rss = rrdset_create_localhost("services", "mem_rss", NULL, "mem", "services.mem_rss"
1347 - , "Systemd Services RSS Memory", "MB",
1348 - CHART_PRIORITY_SYSTEMD_SERVICES + 20, update_every, RRDSET_TYPE_STACKED);
1376 +
1377 + st_mem_detailed_rss = rrdset_create_localhost(
1378 + "services"
1379 + , "mem_rss"
1380 + , NULL
1381 + , "mem"
1382 + , "services.mem_rss"
1383 + , "Systemd Services RSS Memory"
1384 + , "MB"
1385 + , CHART_PRIORITY_SYSTEMD_SERVICES + 20
1386 + , update_every
1387 + , RRDSET_TYPE_STACKED
1388 + );
1389 +
1390 }
1391 else
1392 rrdset_next(st_mem_detailed_rss);
1393
1394 if(unlikely(!st_mem_detailed_mapped)) {
1354 - st_mem_detailed_mapped = rrdset_find_bytype_localhost("services", "mem_mapped");
1355 - if(likely(!st_mem_detailed_mapped))
1356 - st_mem_detailed_mapped = rrdset_create_localhost("services", "mem_mapped", NULL, "mem"
1357 - , "services.mem_mapped"
1358 - , "Systemd Services Mapped Memory", "MB",
1359 - CHART_PRIORITY_SYSTEMD_SERVICES + 30, update_every, RRDSET_TYPE_STACKED);
1395 +
1396 + st_mem_detailed_mapped = rrdset_create_localhost(
1397 + "services"
1398 + , "mem_mapped"
1399 + , NULL
1400 + , "mem"
1401 + , "services.mem_mapped"
1402 + , "Systemd Services Mapped Memory"
1403 + , "MB"
1404 + , CHART_PRIORITY_SYSTEMD_SERVICES + 30
1405 + , update_every
1406 + , RRDSET_TYPE_STACKED
1407 + );
1408 +
1409 }
1410 else
1411 rrdset_next(st_mem_detailed_mapped);
1412
1413 if(unlikely(!st_mem_detailed_cache)) {
1365 - st_mem_detailed_cache = rrdset_find_bytype_localhost("services", "mem_cache");
1366 - if(likely(!st_mem_detailed_cache))
1367 - st_mem_detailed_cache = rrdset_create_localhost("services", "mem_cache", NULL, "mem"
1368 - , "services.mem_cache", "Systemd Services Cache Memory"
1369 - , "MB", CHART_PRIORITY_SYSTEMD_SERVICES + 40
1370 - , update_every, RRDSET_TYPE_STACKED);
1414 +
1415 + st_mem_detailed_cache = rrdset_create_localhost(
1416 + "services"
1417 + , "mem_cache"
1418 + , NULL
1419 + , "mem"
1420 + , "services.mem_cache"
1421 + , "Systemd Services Cache Memory"
1422 + , "MB"
1423 + , CHART_PRIORITY_SYSTEMD_SERVICES + 40
1424 + , update_every
1425 + , RRDSET_TYPE_STACKED
1426 + );
1427 +
1428 }
1429 else
1430 rrdset_next(st_mem_detailed_cache);
1431
1432 if(unlikely(!st_mem_detailed_writeback)) {
1376 - st_mem_detailed_writeback = rrdset_find_bytype_localhost("services", "mem_writeback");
1377 - if(likely(!st_mem_detailed_writeback))
1378 - st_mem_detailed_writeback = rrdset_create_localhost("services", "mem_writeback", NULL, "mem"
1379 - , "services.mem_writeback"
1380 - , "Systemd Services Writeback Memory", "MB",
1381 - CHART_PRIORITY_SYSTEMD_SERVICES + 50, update_every, RRDSET_TYPE_STACKED);
1433 +
1434 + st_mem_detailed_writeback = rrdset_create_localhost(
1435 + "services"
1436 + , "mem_writeback"
1437 + , NULL
1438 + , "mem"
1439 + , "services.mem_writeback"
1440 + , "Systemd Services Writeback Memory"
1441 + , "MB"
1442 + , CHART_PRIORITY_SYSTEMD_SERVICES + 50
1443 + , update_every
1444 + , RRDSET_TYPE_STACKED
1445 + );
1446 +
1447 }
1448 else
1449 rrdset_next(st_mem_detailed_writeback);
1450
1451 if(unlikely(!st_mem_detailed_pgfault)) {
1387 - st_mem_detailed_pgfault = rrdset_find_bytype_localhost("services", "mem_pgfault");
1388 - if(likely(!st_mem_detailed_pgfault))
1389 - st_mem_detailed_pgfault = rrdset_create_localhost("services", "mem_pgfault", NULL, "mem"
1390 - , "services.mem_pgfault"
1391 - , "Systemd Services Memory Minor Page Faults", "MB/s",
1392 - CHART_PRIORITY_SYSTEMD_SERVICES + 60, update_every, RRDSET_TYPE_STACKED);
1452 +
1453 + st_mem_detailed_pgfault = rrdset_create_localhost(
1454 + "services"
1455 + , "mem_pgfault"
1456 + , NULL
1457 + , "mem"
1458 + , "services.mem_pgfault"
1459 + , "Systemd Services Memory Minor Page Faults"
1460 + , "MB/s"
1461 + , CHART_PRIORITY_SYSTEMD_SERVICES + 60
1462 + , update_every
1463 + , RRDSET_TYPE_STACKED
1464 + );
1465 }
1466 else
1467 rrdset_next(st_mem_detailed_pgfault);
1468
1469 if(unlikely(!st_mem_detailed_pgmajfault)) {
1398 - st_mem_detailed_pgmajfault = rrdset_find_bytype_localhost("services", "mem_pgmajfault");
1399 - if(likely(!st_mem_detailed_pgmajfault))
1400 - st_mem_detailed_pgmajfault = rrdset_create_localhost("services", "mem_pgmajfault", NULL, "mem"
1401 - , "services.mem_pgmajfault"
1402 - , "Systemd Services Memory Major Page Faults"
1403 - , "MB/s", CHART_PRIORITY_SYSTEMD_SERVICES + 70
1404 - , update_every, RRDSET_TYPE_STACKED);
1470 +
1471 + st_mem_detailed_pgmajfault = rrdset_create_localhost(
1472 + "services"
1473 + , "mem_pgmajfault"
1474 + , NULL
1475 + , "mem"
1476 + , "services.mem_pgmajfault"
1477 + , "Systemd Services Memory Major Page Faults"
1478 + , "MB/s"
1479 + , CHART_PRIORITY_SYSTEMD_SERVICES + 70
1480 + , update_every
1481 + , RRDSET_TYPE_STACKED
1482 + );
1483 +
1484 }
1485 else
1486 rrdset_next(st_mem_detailed_pgmajfault);
1487
1488 if(unlikely(!st_mem_detailed_pgpgin)) {
1410 - st_mem_detailed_pgpgin = rrdset_find_bytype_localhost("services", "mem_pgpgin");
1411 - if(likely(!st_mem_detailed_pgpgin))
1412 - st_mem_detailed_pgpgin = rrdset_create_localhost("services", "mem_pgpgin", NULL, "mem"
1413 - , "services.mem_pgpgin"
1414 - , "Systemd Services Memory Charging Activity", "MB/s",
1415 - CHART_PRIORITY_SYSTEMD_SERVICES + 80, update_every, RRDSET_TYPE_STACKED);
1489 +
1490 + st_mem_detailed_pgpgin = rrdset_create_localhost(
1491 + "services"
1492 + , "mem_pgpgin"
1493 + , NULL
1494 + , "mem"
1495 + , "services.mem_pgpgin"
1496 + , "Systemd Services Memory Charging Activity"
1497 + , "MB/s"
1498 + , CHART_PRIORITY_SYSTEMD_SERVICES + 80
1499 + , update_every
1500 + , RRDSET_TYPE_STACKED
1501 + );
1502 +
1503 }
1504 else
1505 rrdset_next(st_mem_detailed_pgpgin);
1506
1507 if(unlikely(!st_mem_detailed_pgpgout)) {
1421 - st_mem_detailed_pgpgout = rrdset_find_bytype_localhost("services", "mem_pgpgout");
1422 - if(likely(!st_mem_detailed_pgpgout))
1423 - st_mem_detailed_pgpgout = rrdset_create_localhost("services", "mem_pgpgout", NULL, "mem"
1424 - , "services.mem_pgpgout"
1425 - , "Systemd Services Memory Uncharging Activity"
1426 - , "MB/s", CHART_PRIORITY_SYSTEMD_SERVICES + 90
1427 - , update_every, RRDSET_TYPE_STACKED);
1508 +
1509 + st_mem_detailed_pgpgout = rrdset_create_localhost(
1510 + "services"
1511 + , "mem_pgpgout"
1512 + , NULL
1513 + , "mem"
1514 + , "services.mem_pgpgout"
1515 + , "Systemd Services Memory Uncharging Activity"
1516 + , "MB/s"
1517 + , CHART_PRIORITY_SYSTEMD_SERVICES + 90
1518 + , update_every
1519 + , RRDSET_TYPE_STACKED
1520 + );
1521 +
1522 }
1523 else
1524 rrdset_next(st_mem_detailed_pgpgout);
@@ -1432,11 +1526,20 @@ void update_services_charts(int update_every,
1526
1527 if(likely(do_mem_failcnt)) {
1528 if(unlikely(!st_mem_failcnt)) {
1435 - st_mem_failcnt = rrdset_find_bytype_localhost("services", "mem_failcnt");
1436 - if(likely(!st_mem_failcnt))
1437 - st_mem_failcnt = rrdset_create_localhost("services", "mem_failcnt", NULL, "mem", "services.mem_failcnt"
1438 - , "Systemd Services Memory Limit Failures", "MB",
1439 - CHART_PRIORITY_SYSTEMD_SERVICES + 110, update_every, RRDSET_TYPE_STACKED);
1529 +
1530 + st_mem_failcnt = rrdset_create_localhost(
1531 + "services"
1532 + , "mem_failcnt"
1533 + , NULL
1534 + , "mem"
1535 + , "services.mem_failcnt"
1536 + , "Systemd Services Memory Limit Failures"
1537 + , "MB"
1538 + , CHART_PRIORITY_SYSTEMD_SERVICES + 110
1539 + , update_every
1540 + , RRDSET_TYPE_STACKED
1541 + );
1542 +
1543 }
1544 else
1545 rrdset_next(st_mem_failcnt);
@@ -1444,11 +1547,20 @@ void update_services_charts(int update_every,
1547
1548 if(likely(do_swap_usage)) {
1549 if(unlikely(!st_swap_usage)) {
1447 - st_swap_usage = rrdset_find_bytype_localhost("services", "swap_usage");
1448 - if(likely(!st_swap_usage))
1449 - st_swap_usage = rrdset_create_localhost("services", "swap_usage", NULL, "swap", "services.swap_usage"
1450 - , "Systemd Services Swap Memory Used", "MB",
1451 - CHART_PRIORITY_SYSTEMD_SERVICES + 100, update_every, RRDSET_TYPE_STACKED);
1550 +
1551 + st_swap_usage = rrdset_create_localhost(
1552 + "services"
1553 + , "swap_usage"
1554 + , NULL
1555 + , "swap"
1556 + , "services.swap_usage"
1557 + , "Systemd Services Swap Memory Used"
1558 + , "MB"
1559 + , CHART_PRIORITY_SYSTEMD_SERVICES + 100
1560 + , update_every
1561 + , RRDSET_TYPE_STACKED
1562 + );
1563 +
1564 }
1565 else
1566 rrdset_next(st_swap_usage);
@@ -1456,21 +1568,39 @@ void update_services_charts(int update_every,
1568
1569 if(likely(do_io)) {
1570 if(unlikely(!st_io_read)) {
1459 - st_io_read = rrdset_find_bytype_localhost("services", "io_read");
1460 - if(likely(!st_io_read))
1461 - st_io_read = rrdset_create_localhost("services", "io_read", NULL, "disk", "services.io_read"
1462 - , "Systemd Services Disk Read Bandwidth", "KB/s",
1463 - CHART_PRIORITY_SYSTEMD_SERVICES + 120, update_every, RRDSET_TYPE_STACKED);
1571 +
1572 + st_io_read = rrdset_create_localhost(
1573 + "services"
1574 + , "io_read"
1575 + , NULL
1576 + , "disk"
1577 + , "services.io_read"
1578 + , "Systemd Services Disk Read Bandwidth"
1579 + , "KB/s"
1580 + , CHART_PRIORITY_SYSTEMD_SERVICES + 120
1581 + , update_every
1582 + , RRDSET_TYPE_STACKED
1583 + );
1584 +
1585 }
1586 else
1587 rrdset_next(st_io_read);
1588
1589 if(unlikely(!st_io_write)) {
1469 - st_io_write = rrdset_find_bytype_localhost("services", "io_write");
1470 - if(likely(!st_io_write))
1471 - st_io_write = rrdset_create_localhost("services", "io_write", NULL, "disk", "services.io_write"
1472 - , "Systemd Services Disk Write Bandwidth", "KB/s",
1473 - CHART_PRIORITY_SYSTEMD_SERVICES + 130, update_every, RRDSET_TYPE_STACKED);
1590 +
1591 + st_io_write = rrdset_create_localhost(
1592 + "services"
1593 + , "io_write"
1594 + , NULL
1595 + , "disk"
1596 + , "services.io_write"
1597 + , "Systemd Services Disk Write Bandwidth"
1598 + , "KB/s"
1599 + , CHART_PRIORITY_SYSTEMD_SERVICES + 130
1600 + , update_every
1601 + , RRDSET_TYPE_STACKED
1602 + );
1603 +
1604 }
1605 else
1606 rrdset_next(st_io_write);
@@ -1478,24 +1608,39 @@ void update_services_charts(int update_every,
1608
1609 if(likely(do_io_ops)) {
1610 if(unlikely(!st_io_serviced_read)) {
1481 - st_io_serviced_read = rrdset_find_bytype_localhost("services", "io_ops_read");
1482 - if(likely(!st_io_serviced_read))
1483 - st_io_serviced_read = rrdset_create_localhost("services", "io_ops_read", NULL, "disk"
1484 - , "services.io_ops_read"
1485 - , "Systemd Services Disk Read Operations", "operations/s",
1486 - CHART_PRIORITY_SYSTEMD_SERVICES + 140, update_every, RRDSET_TYPE_STACKED);
1611 +
1612 + st_io_serviced_read = rrdset_create_localhost(
1613 + "services"
1614 + , "io_ops_read"
1615 + , NULL
1616 + , "disk"
1617 + , "services.io_ops_read"
1618 + , "Systemd Services Disk Read Operations"
1619 + , "operations/s"
1620 + , CHART_PRIORITY_SYSTEMD_SERVICES + 140
1621 + , update_every
1622 + , RRDSET_TYPE_STACKED
1623 + );
1624 +
1625 }
1626 else
1627 rrdset_next(st_io_serviced_read);
1628
1629 if(unlikely(!st_io_serviced_write)) {
1492 - st_io_serviced_write = rrdset_find_bytype_localhost("services", "io_ops_write");
1493 - if(likely(!st_io_serviced_write))
1494 - st_io_serviced_write = rrdset_create_localhost("services", "io_ops_write", NULL, "disk"
1495 - , "services.io_ops_write"
1496 - , "Systemd Services Disk Write Operations"
1497 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 150
1498 - , update_every, RRDSET_TYPE_STACKED);
1630 +
1631 + st_io_serviced_write = rrdset_create_localhost(
1632 + "services"
1633 + , "io_ops_write"
1634 + , NULL
1635 + , "disk"
1636 + , "services.io_ops_write"
1637 + , "Systemd Services Disk Write Operations"
1638 + , "operations/s"
1639 + , CHART_PRIORITY_SYSTEMD_SERVICES + 150
1640 + , update_every
1641 + , RRDSET_TYPE_STACKED
1642 + );
1643 +
1644 }
1645 else
1646 rrdset_next(st_io_serviced_write);
@@ -1503,24 +1648,39 @@ void update_services_charts(int update_every,
1648
1649 if(likely(do_throttle_io)) {
1650 if(unlikely(!st_throttle_io_read)) {
1506 - st_throttle_io_read = rrdset_find_bytype_localhost("services", "throttle_io_read");
1507 - if(likely(!st_throttle_io_read))
1508 - st_throttle_io_read = rrdset_create_localhost("services", "throttle_io_read", NULL, "disk"
1509 - , "services.throttle_io_read"
1510 - , "Systemd Services Throttle Disk Read Bandwidth", "KB/s",
1511 - CHART_PRIORITY_SYSTEMD_SERVICES + 160, update_every, RRDSET_TYPE_STACKED);
1651 +
1652 + st_throttle_io_read = rrdset_create_localhost(
1653 + "services"
1654 + , "throttle_io_read"
1655 + , NULL
1656 + , "disk"
1657 + , "services.throttle_io_read"
1658 + , "Systemd Services Throttle Disk Read Bandwidth"
1659 + , "KB/s"
1660 + , CHART_PRIORITY_SYSTEMD_SERVICES + 160
1661 + , update_every
1662 + , RRDSET_TYPE_STACKED
1663 + );
1664 +
1665 }
1666 else
1667 rrdset_next(st_throttle_io_read);
1668
1669 if(unlikely(!st_throttle_io_write)) {
1517 - st_throttle_io_write = rrdset_find_bytype_localhost("services", "throttle_io_write");
1518 - if(likely(!st_throttle_io_write))
1519 - st_throttle_io_write = rrdset_create_localhost("services", "throttle_io_write", NULL, "disk"
1520 - , "services.throttle_io_write"
1521 - , "Systemd Services Throttle Disk Write Bandwidth"
1522 - , "KB/s", CHART_PRIORITY_SYSTEMD_SERVICES + 170
1523 - , update_every, RRDSET_TYPE_STACKED);
1670 +
1671 + st_throttle_io_write = rrdset_create_localhost(
1672 + "services"
1673 + , "throttle_io_write"
1674 + , NULL
1675 + , "disk"
1676 + , "services.throttle_io_write"
1677 + , "Systemd Services Throttle Disk Write Bandwidth"
1678 + , "KB/s"
1679 + , CHART_PRIORITY_SYSTEMD_SERVICES + 170
1680 + , update_every
1681 + , RRDSET_TYPE_STACKED
1682 + );
1683 +
1684 }
1685 else
1686 rrdset_next(st_throttle_io_write);
@@ -1528,25 +1688,39 @@ void update_services_charts(int update_every,
1688
1689 if(likely(do_throttle_ops)) {
1690 if(unlikely(!st_throttle_ops_read)) {
1531 - st_throttle_ops_read = rrdset_find_bytype_localhost("services", "throttle_io_ops_read");
1532 - if(likely(!st_throttle_ops_read))
1533 - st_throttle_ops_read = rrdset_create_localhost("services", "throttle_io_ops_read", NULL, "disk"
1534 - , "services.throttle_io_ops_read"
1535 - , "Systemd Services Throttle Disk Read Operations"
1536 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 180
1537 - , update_every, RRDSET_TYPE_STACKED);
1691 +
1692 + st_throttle_ops_read = rrdset_create_localhost(
1693 + "services"
1694 + , "throttle_io_ops_read"
1695 + , NULL
1696 + , "disk"
1697 + , "services.throttle_io_ops_read"
1698 + , "Systemd Services Throttle Disk Read Operations"
1699 + , "operations/s"
1700 + , CHART_PRIORITY_SYSTEMD_SERVICES + 180
1701 + , update_every
1702 + , RRDSET_TYPE_STACKED
1703 + );
1704 +
1705 }
1706 else
1707 rrdset_next(st_throttle_ops_read);
1708
1709 if(unlikely(!st_throttle_ops_write)) {
1543 - st_throttle_ops_write = rrdset_find_bytype_localhost("services", "throttle_io_ops_write");
1544 - if(likely(!st_throttle_ops_write))
1545 - st_throttle_ops_write = rrdset_create_localhost("services", "throttle_io_ops_write", NULL, "disk"
1546 - , "services.throttle_io_ops_write"
1547 - , "Systemd Services Throttle Disk Write Operations"
1548 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 190
1549 - , update_every, RRDSET_TYPE_STACKED);
1710 +
1711 + st_throttle_ops_write = rrdset_create_localhost(
1712 + "services"
1713 + , "throttle_io_ops_write"
1714 + , NULL
1715 + , "disk"
1716 + , "services.throttle_io_ops_write"
1717 + , "Systemd Services Throttle Disk Write Operations"
1718 + , "operations/s"
1719 + , CHART_PRIORITY_SYSTEMD_SERVICES + 190
1720 + , update_every
1721 + , RRDSET_TYPE_STACKED
1722 + );
1723 +
1724 }
1725 else
1726 rrdset_next(st_throttle_ops_write);
@@ -1554,25 +1728,39 @@ void update_services_charts(int update_every,
1728
1729 if(likely(do_queued_ops)) {
1730 if(unlikely(!st_queued_ops_read)) {
1557 - st_queued_ops_read = rrdset_find_bytype_localhost("services", "queued_io_ops_read");
1558 - if(likely(!st_queued_ops_read))
1559 - st_queued_ops_read = rrdset_create_localhost("services", "queued_io_ops_read", NULL, "disk"
1560 - , "services.queued_io_ops_read"
1561 - , "Systemd Services Queued Disk Read Operations"
1562 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 200
1563 - , update_every, RRDSET_TYPE_STACKED);
1731 +
1732 + st_queued_ops_read = rrdset_create_localhost(
1733 + "services"
1734 + , "queued_io_ops_read"
1735 + , NULL
1736 + , "disk"
1737 + , "services.queued_io_ops_read"
1738 + , "Systemd Services Queued Disk Read Operations"
1739 + , "operations/s"
1740 + , CHART_PRIORITY_SYSTEMD_SERVICES + 200
1741 + , update_every
1742 + , RRDSET_TYPE_STACKED
1743 + );
1744 +
1745 }
1746 else
1747 rrdset_next(st_queued_ops_read);
1748
1749 if(unlikely(!st_queued_ops_write)) {
1569 - st_queued_ops_write = rrdset_find_bytype_localhost("services", "queued_io_ops_write");
1570 - if(likely(!st_queued_ops_write))
1571 - st_queued_ops_write = rrdset_create_localhost("services", "queued_io_ops_write", NULL, "disk"
1572 - , "services.queued_io_ops_write"
1573 - , "Systemd Services Queued Disk Write Operations"
1574 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 210
1575 - , update_every, RRDSET_TYPE_STACKED);
1750 +
1751 + st_queued_ops_write = rrdset_create_localhost(
1752 + "services"
1753 + , "queued_io_ops_write"
1754 + , NULL
1755 + , "disk"
1756 + , "services.queued_io_ops_write"
1757 + , "Systemd Services Queued Disk Write Operations"
1758 + , "operations/s"
1759 + , CHART_PRIORITY_SYSTEMD_SERVICES + 210
1760 + , update_every
1761 + , RRDSET_TYPE_STACKED
1762 + );
1763 +
1764 }
1765 else
1766 rrdset_next(st_queued_ops_write);
@@ -1580,25 +1768,39 @@ void update_services_charts(int update_every,
1768
1769 if(likely(do_merged_ops)) {
1770 if(unlikely(!st_merged_ops_read)) {
1583 - st_merged_ops_read = rrdset_find_bytype_localhost("services", "merged_io_ops_read");
1584 - if(likely(!st_merged_ops_read))
1585 - st_merged_ops_read = rrdset_create_localhost("services", "merged_io_ops_read", NULL, "disk"
1586 - , "services.merged_io_ops_read"
1587 - , "Systemd Services Merged Disk Read Operations"
1588 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 220
1589 - , update_every, RRDSET_TYPE_STACKED);
1771 +
1772 + st_merged_ops_read = rrdset_create_localhost(
1773 + "services"
1774 + , "merged_io_ops_read"
1775 + , NULL
1776 + , "disk"
1777 + , "services.merged_io_ops_read"
1778 + , "Systemd Services Merged Disk Read Operations"
1779 + , "operations/s"
1780 + , CHART_PRIORITY_SYSTEMD_SERVICES + 220
1781 + , update_every
1782 + , RRDSET_TYPE_STACKED
1783 + );
1784 +
1785 }
1786 else
1787 rrdset_next(st_merged_ops_read);
1788
1789 if(unlikely(!st_merged_ops_write)) {
1595 - st_merged_ops_write = rrdset_find_bytype_localhost("services", "merged_io_ops_write");
1596 - if(likely(!st_merged_ops_write))
1597 - st_merged_ops_write = rrdset_create_localhost("services", "merged_io_ops_write", NULL, "disk"
1598 - , "services.merged_io_ops_write"
1599 - , "Systemd Services Merged Disk Write Operations"
1600 - , "operations/s", CHART_PRIORITY_SYSTEMD_SERVICES + 230
1601 - , update_every, RRDSET_TYPE_STACKED);
1790 +
1791 + st_merged_ops_write = rrdset_create_localhost(
1792 + "services"
1793 + , "merged_io_ops_write"
1794 + , NULL
1795 + , "disk"
1796 + , "services.merged_io_ops_write"
1797 + , "Systemd Services Merged Disk Write Operations"
1798 + , "operations/s"
1799 + , CHART_PRIORITY_SYSTEMD_SERVICES + 230
1800 + , update_every
1801 + , RRDSET_TYPE_STACKED
1802 + );
1803 +
1804 }
1805 else
1806 rrdset_next(st_merged_ops_write);
@@ -1627,34 +1829,42 @@ void update_services_charts(int update_every,
1829 if(likely(do_mem_detailed && cg->memory.updated_detailed)) {
1830 if(unlikely(!cg->rd_mem_detailed_rss))
1831 cg->rd_mem_detailed_rss = rrddim_add(st_mem_detailed_rss, cg->chart_id, cg->chart_title, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
1832 +
1833 rrddim_set_by_pointer(st_mem_detailed_rss, cg->rd_mem_detailed_rss, cg->memory.rss + cg->memory.rss_huge);
1834
1835 if(unlikely(!cg->rd_mem_detailed_mapped))
1836 cg->rd_mem_detailed_mapped = rrddim_add(st_mem_detailed_mapped, cg->chart_id, cg->chart_title, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
1837 +
1838 rrddim_set_by_pointer(st_mem_detailed_mapped, cg->rd_mem_detailed_mapped, cg->memory.mapped_file);
1839
1840 if(unlikely(!cg->rd_mem_detailed_cache))
1841 cg->rd_mem_detailed_cache = rrddim_add(st_mem_detailed_cache, cg->chart_id, cg->chart_title, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
1842 +
1843 rrddim_set_by_pointer(st_mem_detailed_cache, cg->rd_mem_detailed_cache, cg->memory.cache);
1844
1845 if(unlikely(!cg->rd_mem_detailed_writeback))
1846 cg->rd_mem_detailed_writeback = rrddim_add(st_mem_detailed_writeback, cg->chart_id, cg->chart_title, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
1847 +
1848 rrddim_set_by_pointer(st_mem_detailed_writeback, cg->rd_mem_detailed_writeback, cg->memory.writeback);
1849
1850 if(unlikely(!cg->rd_mem_detailed_pgfault))
1851 cg->rd_mem_detailed_pgfault = rrddim_add(st_mem_detailed_pgfault, cg->chart_id, cg->chart_title, system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
1852 +
1853 rrddim_set_by_pointer(st_mem_detailed_pgfault, cg->rd_mem_detailed_pgfault, cg->memory.pgfault);
1854
1855 if(unlikely(!cg->rd_mem_detailed_pgmajfault))
1856 cg->rd_mem_detailed_pgmajfault = rrddim_add(st_mem_detailed_pgmajfault, cg->chart_id, cg->chart_title, system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
1857 +
1858 rrddim_set_by_pointer(st_mem_detailed_pgmajfault, cg->rd_mem_detailed_pgmajfault, cg->memory.pgmajfault);
1859
1860 if(unlikely(!cg->rd_mem_detailed_pgpgin))
1861 cg->rd_mem_detailed_pgpgin = rrddim_add(st_mem_detailed_pgpgin, cg->chart_id, cg->chart_title, system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
1862 +
1863 rrddim_set_by_pointer(st_mem_detailed_pgpgin, cg->rd_mem_detailed_pgpgin, cg->memory.pgpgin);
1864
1865 if(unlikely(!cg->rd_mem_detailed_pgpgout))
1866 cg->rd_mem_detailed_pgpgout = rrddim_add(st_mem_detailed_pgpgout, cg->chart_id, cg->chart_title, system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
1867 +
1868 rrddim_set_by_pointer(st_mem_detailed_pgpgout, cg->rd_mem_detailed_pgpgout, cg->memory.pgpgout);
1869 }
1870
@@ -1856,13 +2066,21 @@ void update_cgroup_charts(int update_every) {
2066
2067 if(likely(cg->cpuacct_stat.updated && cg->cpuacct_stat.enabled == CONFIG_BOOLEAN_YES)) {
2068 if(unlikely(!cg->st_cpu)) {
1859 - cg->st_cpu = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
1860 - , "cpu");
1861 - if(likely(!cg->st_cpu)) {
1862 - snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) for cgroup %s", (processors * 100), processors, (processors > 1) ? "s" : "", cg->chart_title);
1863 - cg->st_cpu = rrdset_create_localhost(type, "cpu", NULL, "cpu", "cgroup.cpu", title, "%"
1864 - , CHART_PRIORITY_CONTAINERS, update_every, RRDSET_TYPE_STACKED);
1865 - }
2069 + snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) for cgroup %s", (processors * 100), processors, (processors > 1) ? "s" : "", cg->chart_title);
2070 +
2071 + cg->st_cpu = rrdset_create_localhost(
2072 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2073 + , "cpu"
2074 + , NULL
2075 + , "cpu"
2076 + , "cgroup.cpu"
2077 + , title
2078 + , "%"
2079 + , CHART_PRIORITY_CONTAINERS
2080 + , update_every
2081 + , RRDSET_TYPE_STACKED
2082 + );
2083 +
2084 rrddim_add(cg->st_cpu, "user", NULL, 100, hz, RRD_ALGORITHM_INCREMENTAL);
2085 rrddim_add(cg->st_cpu, "system", NULL, 100, hz, RRD_ALGORITHM_INCREMENTAL);
2086 }
@@ -1879,14 +2097,21 @@ void update_cgroup_charts(int update_every) {
2097 unsigned int i;
2098
2099 if(unlikely(!cg->st_cpu_per_core)) {
1882 - cg->st_cpu_per_core = rrdset_find_bytype_localhost(
1883 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "cpu_per_core");
1884 - if(likely(!cg->st_cpu_per_core)) {
1885 - snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) Per Core for cgroup %s", (processors * 100), processors, (processors > 1) ? "s" : "", cg->chart_title);
1886 - cg->st_cpu_per_core = rrdset_create_localhost(type, "cpu_per_core", NULL, "cpu"
1887 - , "cgroup.cpu_per_core", title, "%",
1888 - CHART_PRIORITY_CONTAINERS + 100, update_every, RRDSET_TYPE_STACKED);
1889 - }
2100 + snprintfz(title, CHART_TITLE_MAX, "CPU Usage (%d%% = %d core%s) Per Core for cgroup %s", (processors * 100), processors, (processors > 1) ? "s" : "", cg->chart_title);
2101 +
2102 + cg->st_cpu_per_core = rrdset_create_localhost(
2103 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2104 + , "cpu_per_core"
2105 + , NULL
2106 + , "cpu"
2107 + , "cgroup.cpu_per_core"
2108 + , title
2109 + , "%"
2110 + , CHART_PRIORITY_CONTAINERS + 100
2111 + , update_every
2112 + , RRDSET_TYPE_STACKED
2113 + );
2114 +
2115 for(i = 0; i < cg->cpuacct_usage.cpus; i++) {
2116 snprintfz(id, CHART_TITLE_MAX, "cpu%u", i);
2117 rrddim_add(cg->st_cpu_per_core, id, NULL, 100, 1000000000, RRD_ALGORITHM_INCREMENTAL);
@@ -1904,18 +2129,27 @@ void update_cgroup_charts(int update_every) {
2129
2130 if(likely(cg->memory.updated_detailed && cg->memory.enabled_detailed == CONFIG_BOOLEAN_YES)) {
2131 if(unlikely(!cg->st_mem)) {
1907 - cg->st_mem = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
1908 - , "mem");
1909 - if(likely(!cg->st_mem)) {
1910 - snprintfz(title, CHART_TITLE_MAX, "Memory Usage for cgroup %s", cg->chart_title);
1911 - cg->st_mem = rrdset_create_localhost(type, "mem", NULL, "mem", "cgroup.mem", title, "MB",
1912 - CHART_PRIORITY_CONTAINERS + 210, update_every, RRDSET_TYPE_STACKED);
1913 - }
2132 + snprintfz(title, CHART_TITLE_MAX, "Memory Usage for cgroup %s", cg->chart_title);
2133 +
2134 + cg->st_mem = rrdset_create_localhost(
2135 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2136 + , "mem"
2137 + , NULL
2138 + , "mem"
2139 + , "cgroup.mem"
2140 + , title
2141 + , "MB"
2142 + , CHART_PRIORITY_CONTAINERS + 210
2143 + , update_every
2144 + , RRDSET_TYPE_STACKED
2145 + );
2146
2147 rrddim_add(cg->st_mem, "cache", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2148 rrddim_add(cg->st_mem, "rss", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2149 +
2150 if(cg->memory.detailed_has_swap)
2151 rrddim_add(cg->st_mem, "swap", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2152 +
2153 rrddim_add(cg->st_mem, "rss_huge", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2154 rrddim_add(cg->st_mem, "mapped_file", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2155 }
@@ -1924,24 +2158,33 @@ void update_cgroup_charts(int update_every) {
2158
2159 rrddim_set(cg->st_mem, "cache", cg->memory.cache);
2160 rrddim_set(cg->st_mem, "rss", cg->memory.rss);
2161 +
2162 if(cg->memory.detailed_has_swap)
2163 rrddim_set(cg->st_mem, "swap", cg->memory.swap);
2164 +
2165 rrddim_set(cg->st_mem, "rss_huge", cg->memory.rss_huge);
2166 rrddim_set(cg->st_mem, "mapped_file", cg->memory.mapped_file);
2167 rrdset_done(cg->st_mem);
2168
2169 if(unlikely(!cg->st_writeback)) {
1934 - cg->st_writeback = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
1935 - , "writeback");
1936 - if(likely(!cg->st_writeback)) {
1937 - snprintfz(title, CHART_TITLE_MAX, "Writeback Memory for cgroup %s", cg->chart_title);
1938 - cg->st_writeback = rrdset_create_localhost(type, "writeback", NULL, "mem", "cgroup.writeback", title
1939 - , "MB", CHART_PRIORITY_CONTAINERS + 300, update_every
1940 - , RRDSET_TYPE_AREA);
1941 - }
2170 + snprintfz(title, CHART_TITLE_MAX, "Writeback Memory for cgroup %s", cg->chart_title);
2171 +
2172 + cg->st_writeback = rrdset_create_localhost(
2173 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2174 + , "writeback"
2175 + , NULL
2176 + , "mem"
2177 + , "cgroup.writeback"
2178 + , title
2179 + , "MB"
2180 + , CHART_PRIORITY_CONTAINERS + 300
2181 + , update_every
2182 + , RRDSET_TYPE_AREA
2183 + );
2184
2185 if(cg->memory.detailed_has_dirty)
2186 rrddim_add(cg->st_writeback, "dirty", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2187 +
2188 rrddim_add(cg->st_writeback, "writeback", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2189 }
2190 else
@@ -1949,18 +2192,26 @@ void update_cgroup_charts(int update_every) {
2192
2193 if(cg->memory.detailed_has_dirty)
2194 rrddim_set(cg->st_writeback, "dirty", cg->memory.dirty);
2195 +
2196 rrddim_set(cg->st_writeback, "writeback", cg->memory.writeback);
2197 rrdset_done(cg->st_writeback);
2198
2199 if(unlikely(!cg->st_mem_activity)) {
1956 - cg->st_mem_activity = rrdset_find_bytype_localhost(
1957 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "mem_activity");
1958 - if(likely(!cg->st_mem_activity)) {
1959 - snprintfz(title, CHART_TITLE_MAX, "Memory Activity for cgroup %s", cg->chart_title);
1960 - cg->st_mem_activity = rrdset_create_localhost(type, "mem_activity", NULL, "mem"
1961 - , "cgroup.mem_activity", title, "MB/s",
1962 - CHART_PRIORITY_CONTAINERS + 400, update_every, RRDSET_TYPE_LINE);
1963 - }
2200 + snprintfz(title, CHART_TITLE_MAX, "Memory Activity for cgroup %s", cg->chart_title);
2201 +
2202 + cg->st_mem_activity = rrdset_create_localhost(
2203 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2204 + , "mem_activity"
2205 + , NULL
2206 + , "mem"
2207 + , "cgroup.mem_activity"
2208 + , title
2209 + , "MB/s"
2210 + , CHART_PRIORITY_CONTAINERS + 400
2211 + , update_every
2212 + , RRDSET_TYPE_LINE
2213 + );
2214 +
2215 rrddim_add(cg->st_mem_activity, "pgpgin", "in", system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2216 rrddim_add(cg->st_mem_activity, "pgpgout", "out", -system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2217 }
@@ -1972,14 +2223,21 @@ void update_cgroup_charts(int update_every) {
2223 rrdset_done(cg->st_mem_activity);
2224
2225 if(unlikely(!cg->st_pgfaults)) {
1975 - cg->st_pgfaults = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
1976 - , "pgfaults");
1977 - if(likely(!cg->st_pgfaults)) {
1978 - snprintfz(title, CHART_TITLE_MAX, "Memory Page Faults for cgroup %s", cg->chart_title);
1979 - cg->st_pgfaults = rrdset_create_localhost(type, "pgfaults", NULL, "mem", "cgroup.pgfaults", title
1980 - , "MB/s", CHART_PRIORITY_CONTAINERS + 500, update_every
1981 - , RRDSET_TYPE_LINE);
1982 - }
2226 + snprintfz(title, CHART_TITLE_MAX, "Memory Page Faults for cgroup %s", cg->chart_title);
2227 +
2228 + cg->st_pgfaults = rrdset_create_localhost(
2229 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2230 + , "pgfaults"
2231 + , NULL
2232 + , "mem"
2233 + , "cgroup.pgfaults"
2234 + , title
2235 + , "MB/s"
2236 + , CHART_PRIORITY_CONTAINERS + 500
2237 + , update_every
2238 + , RRDSET_TYPE_LINE
2239 + );
2240 +
2241 rrddim_add(cg->st_pgfaults, "pgfault", NULL, system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2242 rrddim_add(cg->st_pgfaults, "pgmajfault", "swap", -system_page_size, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
2243 }
@@ -1993,14 +2251,21 @@ void update_cgroup_charts(int update_every) {
2251
2252 if(likely(cg->memory.updated_usage_in_bytes && cg->memory.enabled_usage_in_bytes == CONFIG_BOOLEAN_YES)) {
2253 if(unlikely(!cg->st_mem_usage)) {
1996 - cg->st_mem_usage = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
1997 - , "mem_usage");
1998 - if(likely(!cg->st_mem_usage)) {
1999 - snprintfz(title, CHART_TITLE_MAX, "Used Memory %sfor cgroup %s", (cgroup_used_memory_without_cache && cg->memory.updated_detailed)?"without Cache ":"", cg->chart_title);
2000 - cg->st_mem_usage = rrdset_create_localhost(type, "mem_usage", NULL, "mem", "cgroup.mem_usage", title
2001 - , "MB", CHART_PRIORITY_CONTAINERS + 200, update_every
2002 - , RRDSET_TYPE_STACKED);
2003 - }
2254 + snprintfz(title, CHART_TITLE_MAX, "Used Memory %sfor cgroup %s", (cgroup_used_memory_without_cache && cg->memory.updated_detailed)?"without Cache ":"", cg->chart_title);
2255 +
2256 + cg->st_mem_usage = rrdset_create_localhost(
2257 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2258 + , "mem_usage"
2259 + , NULL
2260 + , "mem"
2261 + , "cgroup.mem_usage"
2262 + , title
2263 + , "MB"
2264 + , CHART_PRIORITY_CONTAINERS + 200
2265 + , update_every
2266 + , RRDSET_TYPE_STACKED
2267 + );
2268 +
2269 rrddim_add(cg->st_mem_usage, "ram", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2270 rrddim_add(cg->st_mem_usage, "swap", NULL, 1, 1024 * 1024, RRD_ALGORITHM_ABSOLUTE);
2271 }
@@ -2014,14 +2279,21 @@ void update_cgroup_charts(int update_every) {
2279
2280 if(likely(cg->memory.updated_failcnt && cg->memory.enabled_failcnt == CONFIG_BOOLEAN_YES)) {
2281 if(unlikely(!cg->st_mem_failcnt)) {
2017 - cg->st_mem_failcnt = rrdset_find_bytype_localhost(
2018 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "mem_failcnt");
2019 - if(likely(!cg->st_mem_failcnt)) {
2020 - snprintfz(title, CHART_TITLE_MAX, "Memory Limit Failures for cgroup %s", cg->chart_title);
2021 - cg->st_mem_failcnt = rrdset_create_localhost(type, "mem_failcnt", NULL, "mem", "cgroup.mem_failcnt"
2022 - , title, "count", CHART_PRIORITY_CONTAINERS + 250
2023 - , update_every, RRDSET_TYPE_LINE);
2024 - }
2282 + snprintfz(title, CHART_TITLE_MAX, "Memory Limit Failures for cgroup %s", cg->chart_title);
2283 +
2284 + cg->st_mem_failcnt = rrdset_create_localhost(
2285 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2286 + , "mem_failcnt"
2287 + , NULL
2288 + , "mem"
2289 + , "cgroup.mem_failcnt"
2290 + , title
2291 + , "count"
2292 + , CHART_PRIORITY_CONTAINERS + 250
2293 + , update_every
2294 + , RRDSET_TYPE_LINE
2295 + );
2296 +
2297 rrddim_add(cg->st_mem_failcnt, "failures", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2298 }
2299 else
@@ -2033,12 +2305,21 @@ void update_cgroup_charts(int update_every) {
2305
2306 if(likely(cg->io_service_bytes.updated && cg->io_service_bytes.enabled == CONFIG_BOOLEAN_YES)) {
2307 if(unlikely(!cg->st_io)) {
2036 - cg->st_io = rrdset_find_bytype_localhost(cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "io");
2037 - if(likely(!cg->st_io)) {
2038 - snprintfz(title, CHART_TITLE_MAX, "I/O Bandwidth (all disks) for cgroup %s", cg->chart_title);
2039 - cg->st_io = rrdset_create_localhost(type, "io", NULL, "disk", "cgroup.io", title, "KB/s",
2040 - CHART_PRIORITY_CONTAINERS + 1200, update_every, RRDSET_TYPE_AREA);
2041 - }
2308 + snprintfz(title, CHART_TITLE_MAX, "I/O Bandwidth (all disks) for cgroup %s", cg->chart_title);
2309 +
2310 + cg->st_io = rrdset_create_localhost(
2311 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2312 + , "io"
2313 + , NULL
2314 + , "disk"
2315 + , "cgroup.io"
2316 + , title
2317 + , "KB/s"
2318 + , CHART_PRIORITY_CONTAINERS + 1200
2319 + , update_every
2320 + , RRDSET_TYPE_AREA
2321 + );
2322 +
2323 rrddim_add(cg->st_io, "read", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
2324 rrddim_add(cg->st_io, "write", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
2325 }
@@ -2052,14 +2333,21 @@ void update_cgroup_charts(int update_every) {
2333
2334 if(likely(cg->io_serviced.updated && cg->io_serviced.enabled == CONFIG_BOOLEAN_YES)) {
2335 if(unlikely(!cg->st_serviced_ops)) {
2055 - cg->st_serviced_ops = rrdset_find_bytype_localhost(
2056 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "serviced_ops");
2057 - if(likely(!cg->st_serviced_ops)) {
2058 - snprintfz(title, CHART_TITLE_MAX, "Serviced I/O Operations (all disks) for cgroup %s", cg->chart_title);
2059 - cg->st_serviced_ops = rrdset_create_localhost(type, "serviced_ops", NULL, "disk"
2060 - , "cgroup.serviced_ops", title, "operations/s",
2061 - CHART_PRIORITY_CONTAINERS + 1200, update_every, RRDSET_TYPE_LINE);
2062 - }
2336 + snprintfz(title, CHART_TITLE_MAX, "Serviced I/O Operations (all disks) for cgroup %s", cg->chart_title);
2337 +
2338 + cg->st_serviced_ops = rrdset_create_localhost(
2339 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2340 + , "serviced_ops"
2341 + , NULL
2342 + , "disk"
2343 + , "cgroup.serviced_ops"
2344 + , title
2345 + , "operations/s"
2346 + , CHART_PRIORITY_CONTAINERS + 1200
2347 + , update_every
2348 + , RRDSET_TYPE_LINE
2349 + );
2350 +
2351 rrddim_add(cg->st_serviced_ops, "read", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2352 rrddim_add(cg->st_serviced_ops, "write", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2353 }
@@ -2073,14 +2361,21 @@ void update_cgroup_charts(int update_every) {
2361
2362 if(likely(cg->throttle_io_service_bytes.updated && cg->throttle_io_service_bytes.enabled == CONFIG_BOOLEAN_YES)) {
2363 if(unlikely(!cg->st_throttle_io)) {
2076 - cg->st_throttle_io = rrdset_find_bytype_localhost(
2077 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "throttle_io");
2078 - if(likely(!cg->st_throttle_io)) {
2079 - snprintfz(title, CHART_TITLE_MAX, "Throttle I/O Bandwidth (all disks) for cgroup %s", cg->chart_title);
2080 - cg->st_throttle_io = rrdset_create_localhost(type, "throttle_io", NULL, "disk", "cgroup.throttle_io"
2081 - , title, "KB/s", CHART_PRIORITY_CONTAINERS + 1200
2082 - , update_every, RRDSET_TYPE_AREA);
2083 - }
2364 + snprintfz(title, CHART_TITLE_MAX, "Throttle I/O Bandwidth (all disks) for cgroup %s", cg->chart_title);
2365 +
2366 + cg->st_throttle_io = rrdset_create_localhost(
2367 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2368 + , "throttle_io"
2369 + , NULL
2370 + , "disk"
2371 + , "cgroup.throttle_io"
2372 + , title
2373 + , "KB/s"
2374 + , CHART_PRIORITY_CONTAINERS + 1200
2375 + , update_every
2376 + , RRDSET_TYPE_AREA
2377 + );
2378 +
2379 rrddim_add(cg->st_throttle_io, "read", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
2380 rrddim_add(cg->st_throttle_io, "write", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
2381 }
@@ -2094,16 +2389,21 @@ void update_cgroup_charts(int update_every) {
2389
2390 if(likely(cg->throttle_io_serviced.updated && cg->throttle_io_serviced.enabled == CONFIG_BOOLEAN_YES)) {
2391 if(unlikely(!cg->st_throttle_serviced_ops)) {
2097 - cg->st_throttle_serviced_ops = rrdset_find_bytype_localhost(
2098 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "throttle_serviced_ops");
2099 - if(likely(!cg->st_throttle_serviced_ops)) {
2100 - snprintfz(title, CHART_TITLE_MAX, "Throttle Serviced I/O Operations (all disks) for cgroup %s", cg->chart_title);
2101 - cg->st_throttle_serviced_ops = rrdset_create_localhost(type, "throttle_serviced_ops", NULL, "disk"
2102 - , "cgroup.throttle_serviced_ops", title
2103 - , "operations/s", CHART_PRIORITY_CONTAINERS +
2104 - 1200, update_every
2105 - , RRDSET_TYPE_LINE);
2106 - }
2392 + snprintfz(title, CHART_TITLE_MAX, "Throttle Serviced I/O Operations (all disks) for cgroup %s", cg->chart_title);
2393 +
2394 + cg->st_throttle_serviced_ops = rrdset_create_localhost(
2395 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2396 + , "throttle_serviced_ops"
2397 + , NULL
2398 + , "disk"
2399 + , "cgroup.throttle_serviced_ops"
2400 + , title
2401 + , "operations/s"
2402 + , CHART_PRIORITY_CONTAINERS + 1200
2403 + , update_every
2404 + , RRDSET_TYPE_LINE
2405 + );
2406 +
2407 rrddim_add(cg->st_throttle_serviced_ops, "read", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2408 rrddim_add(cg->st_throttle_serviced_ops, "write", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2409 }
@@ -2117,14 +2417,21 @@ void update_cgroup_charts(int update_every) {
2417
2418 if(likely(cg->io_queued.updated && cg->io_queued.enabled == CONFIG_BOOLEAN_YES)) {
2419 if(unlikely(!cg->st_queued_ops)) {
2120 - cg->st_queued_ops = rrdset_find_bytype_localhost(
2121 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "queued_ops");
2122 - if(likely(!cg->st_queued_ops)) {
2123 - snprintfz(title, CHART_TITLE_MAX, "Queued I/O Operations (all disks) for cgroup %s", cg->chart_title);
2124 - cg->st_queued_ops = rrdset_create_localhost(type, "queued_ops", NULL, "disk", "cgroup.queued_ops"
2125 - , title, "operations", CHART_PRIORITY_CONTAINERS + 2000
2126 - , update_every, RRDSET_TYPE_LINE);
2127 - }
2420 + snprintfz(title, CHART_TITLE_MAX, "Queued I/O Operations (all disks) for cgroup %s", cg->chart_title);
2421 +
2422 + cg->st_queued_ops = rrdset_create_localhost(
2423 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2424 + , "queued_ops"
2425 + , NULL
2426 + , "disk"
2427 + , "cgroup.queued_ops"
2428 + , title
2429 + , "operations"
2430 + , CHART_PRIORITY_CONTAINERS + 2000
2431 + , update_every
2432 + , RRDSET_TYPE_LINE
2433 + );
2434 +
2435 rrddim_add(cg->st_queued_ops, "read", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
2436 rrddim_add(cg->st_queued_ops, "write", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
2437 }
@@ -2138,15 +2445,21 @@ void update_cgroup_charts(int update_every) {
2445
2446 if(likely(cg->io_merged.updated && cg->io_merged.enabled == CONFIG_BOOLEAN_YES)) {
2447 if(unlikely(!cg->st_merged_ops)) {
2141 - cg->st_merged_ops = rrdset_find_bytype_localhost(
2142 - cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX), "merged_ops");
2143 - if(likely(!cg->st_merged_ops)) {
2144 - snprintfz(title, CHART_TITLE_MAX, "Merged I/O Operations (all disks) for cgroup %s", cg->chart_title);
2145 - cg->st_merged_ops = rrdset_create_localhost(type, "merged_ops", NULL, "disk", "cgroup.merged_ops"
2146 - , title, "operations/s", CHART_PRIORITY_CONTAINERS +
2147 - 2100, update_every
2148 - , RRDSET_TYPE_LINE);
2149 - }
2448 + snprintfz(title, CHART_TITLE_MAX, "Merged I/O Operations (all disks) for cgroup %s", cg->chart_title);
2449 +
2450 + cg->st_merged_ops = rrdset_create_localhost(
2451 + cgroup_chart_type(type, cg->chart_id, RRD_ID_LENGTH_MAX)
2452 + , "merged_ops"
2453 + , NULL
2454 + , "disk"
2455 + , "cgroup.merged_ops"
2456 + , title
2457 + , "operations/s"
2458 + , CHART_PRIORITY_CONTAINERS + 2100
2459 + , update_every
2460 + , RRDSET_TYPE_LINE
2461 + );
2462 +
2463 rrddim_add(cg->st_merged_ops, "read", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
2464 rrddim_add(cg->st_merged_ops, "write", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
2465 }
@@ -2160,18 +2473,10 @@ void update_cgroup_charts(int update_every) {
2473 }
2474
2475 if(likely(cgroup_enable_systemd_services))
2163 - update_services_charts(update_every,
2164 - services_do_cpu,
2165 - services_do_mem_usage,
2166 - services_do_mem_detailed,
2167 - services_do_mem_failcnt,
2168 - services_do_swap_usage,
2169 - services_do_io,
2170 - services_do_io_ops,
2171 - services_do_throttle_io,
2172 - services_do_throttle_ops,
2173 - services_do_queued_ops,
2174 - services_do_merged_ops
2476 + update_systemd_services_charts(update_every, services_do_cpu, services_do_mem_usage, services_do_mem_detailed
2477 + , services_do_mem_failcnt, services_do_swap_usage, services_do_io
2478 + , services_do_io_ops, services_do_throttle_io, services_do_throttle_ops
2479 + , services_do_queued_ops, services_do_merged_ops
2480 );
2481
2482 debug(D_CGROUP, "done updating cgroups charts");
@@ -2227,11 +2532,19 @@ void *cgroups_main(void *ptr) {
2532 getrusage(RUSAGE_THREAD, &thread);
2533
2534 if(unlikely(!stcpu_thread)) {
2230 - stcpu_thread = rrdset_find_localhost("netdata.plugin_cgroups_cpu");
2231 - if(unlikely(!stcpu_thread))
2232 - stcpu_thread = rrdset_create_localhost("netdata", "plugin_cgroups_cpu", NULL, "cgroups", NULL
2233 - , "NetData CGroups Plugin CPU usage", "milliseconds/s"
2234 - , 132000, cgroup_update_every, RRDSET_TYPE_STACKED);
2535 +
2536 + stcpu_thread = rrdset_create_localhost(
2537 + "netdata"
2538 + , "plugin_cgroups_cpu"
2539 + , NULL
2540 + , "cgroups"
2541 + , NULL
2542 + , "NetData CGroups Plugin CPU usage"
2543 + , "milliseconds/s"
2544 + , 132000
2545 + , cgroup_update_every
2546 + , RRDSET_TYPE_STACKED
2547 + );
2548
2549 rrddim_add(stcpu_thread, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
2550 rrddim_add(stcpu_thread, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
src/web_api_old.c
+10 -4
@@ -154,7 +154,9 @@ int web_client_api_old_data_request(RRDHOST *host, struct web_client *w, char *u
154 debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %ld after, %ld before).",
155 w->id, st->name, st->id, lines, group_count, group_method, after, before);
156
157 - time_t timestamp_in_data = rrd_stats_json(datasource_type, st, w->response.data, lines, group_count, group_method, (unsigned long)after, (unsigned long)before, nonzero);
157 + time_t timestamp_in_data = rrdset2json_api_old(datasource_type, st, w->response.data, lines, group_count
158 + , group_method, (unsigned long) after, (unsigned long) before
159 + , nonzero);
160
161 if(datasource_type == DATASOURCE_DATATABLE_JSONP) {
162 if(timestamp_in_data > last_timestamp_in_data)
@@ -195,11 +197,12 @@ inline int web_client_api_old_graph_request(RRDHOST *host, struct web_client *w,
197 buffer_flush(w->response.data);
198 return mysendfile(w, tok);
199 }
200 + st->last_accessed_time = now_realtime_sec();
201
202 debug(D_WEB_CLIENT_ACCESS, "%llu: Sending %s.json of RRD_STATS...", w->id, st->name);
203 w->response.data->contenttype = CT_APPLICATION_JSON;
204 buffer_flush(w->response.data);
202 - rrd_stats_graph_json(st, url, w->response.data);
205 + rrd_graph2json_api_old(st, url, w->response.data);
206 return 200;
207 }
208
@@ -215,7 +218,10 @@ inline int web_client_api_old_list_request(RRDHOST *host, struct web_client *w,
218 RRDSET *st;
219
220 rrdhost_rdlock(host);
218 - rrdset_foreach_read(st, host) buffer_sprintf(w->response.data, "%s\n", st->name);
221 + rrdset_foreach_read(st, host) {
222 + if(rrdset_is_available_for_viewers(st))
223 + buffer_sprintf(w->response.data, "%s\n", st->name);
224 + }
225 rrdhost_unlock(host);
226
227 return 200;
@@ -226,6 +232,6 @@ inline int web_client_api_old_all_json(RRDHOST *host, struct web_client *w, char
232
233 w->response.data->contenttype = CT_APPLICATION_JSON;
234 buffer_flush(w->response.data);
229 - rrd_stats_all_json(host, w->response.data);
235 + rrd_all2json_api_old(host, w->response.data);
236 return 200;
237 }
src/web_api_v1.c
+7 -13
@@ -185,6 +185,7 @@ inline int web_client_api_request_single_chart(RRDHOST *host, struct web_client
185 }
186
187 w->response.data->contenttype = CT_APPLICATION_JSON;
188 + st->last_accessed_time = now_realtime_sec();
189 callback(st, w->response.data);
190 return 200;
191
@@ -329,6 +330,7 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
330 ret = 200;
331 goto cleanup;
332 }
333 + st->last_accessed_time = now_realtime_sec();
334
335 RRDCALC *rc = NULL;
336 if(alarm) {
@@ -462,18 +464,8 @@ int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *u
464
465 // if the collected value is too old, don't calculate its value
466 if (rrdset_last_entry_t(st) >= (now_realtime_sec() - (st->update_every * st->gap_when_lost_iterations_above)))
465 - ret = rrd2value(st,
466 - w->response.data,
467 - &n,
468 - (dimensions) ? buffer_tostring(dimensions) : NULL,
469 - points,
470 - after,
471 - before,
472 - group,
473 - options,
474 - NULL,
475 - &latest_timestamp,
476 - &value_is_null);
467 + ret = rrdset2value_api_v1(st, w->response.data, &n, (dimensions) ? buffer_tostring(dimensions) : NULL
468 + , points, after, before, group, options, NULL, &latest_timestamp, &value_is_null);
469
470 // if the value cannot be calculated, show empty badge
471 if (ret != 200) {
@@ -613,6 +605,7 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
605 ret = 404;
606 goto cleanup;
607 }
608 + st->last_accessed_time = now_realtime_sec();
609
610 long long before = (before_str && *before_str)?str2l(before_str):0;
611 long long after = (after_str && *after_str) ?str2l(after_str):0;
@@ -655,7 +648,8 @@ inline int web_client_api_request_v1_data(RRDHOST *host, struct web_client *w, c
648 buffer_strcat(w->response.data, "(");
649 }
650
658 - ret = rrd2format(st, w->response.data, dimensions, format, points, after, before, group, options, &last_timestamp_in_data);
651 + ret = rrdset2anything_api_v1(st, w->response.data, dimensions, format, points, after, before, group, options
652 + , &last_timestamp_in_data);
653
654 if(format == DATASOURCE_DATATABLE_JSONP) {
655 if(google_timestamp < last_timestamp_in_data)