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)