uptime plugin; fixes #1546; fixes #1507
Costa Tsaousis (ktsaou) committed
Jan 11, 2017 at 21:44 UTC
1887a9aba01139d60fa1f5d313618e79ab268154
8 files changed
+118
-7
CMakeLists.txt
+1
-1
@@ -101,7 +101,7 @@ set(NETDATA_SOURCE_FILES
101
src/registry_person.c
102
src/registry_person.h
103
src/registry_machine.c
104
- src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c)
104
+ src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c)
105
106
set(APPS_PLUGIN_SOURCE_FILES
107
src/appconfig.c
src/Makefile.am
+2
-1
@@ -83,6 +83,7 @@ netdata_SOURCES += \
83
$(NULL)
84
else
85
netdata_SOURCES += \
86
+ ipc.c ipc.h \
87
plugin_proc.c plugin_proc.h \
88
proc_diskstats.c \
89
proc_interrupts.c \
@@ -102,7 +103,7 @@ netdata_SOURCES += \
103
proc_stat.c \
104
proc_sys_kernel_random_entropy_avail.c \
105
proc_vmstat.c \
105
- ipc.c ipc.h \
106
+ proc_uptime.c \
107
sys_kernel_mm_ksm.c \
108
$(NULL)
109
endif
src/clocks.h
+4
@@ -29,6 +29,10 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts);
29
#ifndef CLOCK_BOOTTIME
30
/* fallback to CLOCK_MONOTONIC if not available */
31
#define CLOCK_BOOTTIME CLOCK_MONOTONIC
32
+#else
33
+#ifdef HAVE_CLOCK_GETTIME
34
+#define CLOCK_BOOTTIME_IS_AVAILABLE 1 // required for /proc/uptime
35
+#endif
36
#endif
37
38
typedef unsigned long long usec_t;
src/plugin_proc.c
+10
@@ -35,6 +35,7 @@ void *proc_main(void *ptr)
35
int vdo_proc_softirqs = !config_get_boolean("plugin:proc", "/proc/softirqs", 1);
36
int vdo_proc_net_softnet_stat = !config_get_boolean("plugin:proc", "/proc/net/softnet_stat", 1);
37
int vdo_proc_loadavg = !config_get_boolean("plugin:proc", "/proc/loadavg", 1);
38
+ int vdo_proc_uptime = !config_get_boolean("plugin:proc", "/proc/uptime", 1);
39
int vdo_ipc = !config_get_boolean("plugin:proc", "ipc", 1);
40
int vdo_sys_kernel_mm_ksm = !config_get_boolean("plugin:proc", "/sys/kernel/mm/ksm", 1);
41
int vdo_cpu_netdata = !config_get_boolean("plugin:proc", "netdata server resources", 1);
@@ -58,6 +59,7 @@ void *proc_main(void *ptr)
59
usec_t sutime_proc_softirqs = 0ULL;
60
usec_t sutime_proc_net_softnet_stat = 0ULL;
61
usec_t sutime_proc_loadavg = 0ULL;
62
+ usec_t sutime_proc_uptime = 0ULL;
63
usec_t sutime_ipc = 0ULL;
64
usec_t sutime_sys_kernel_mm_ksm = 0ULL;
65
@@ -92,6 +94,14 @@ void *proc_main(void *ptr)
94
}
95
if(unlikely(netdata_exit)) break;
96
97
+ if(!vdo_proc_uptime) {
98
+ debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_uptime().");
99
+ now = now_realtime_usec();
100
+ vdo_proc_uptime = do_proc_uptime(rrd_update_every, (sutime_proc_uptime > 0)?now - sutime_proc_uptime:0ULL);
101
+ sutime_proc_uptime = now;
102
+ }
103
+ if(unlikely(netdata_exit)) break;
104
+
105
if(!vdo_ipc) {
106
debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_ipc().");
107
now = now_realtime_usec();
src/plugin_proc.h
+1
@@ -22,5 +22,6 @@ extern int do_sys_kernel_mm_ksm(int update_every, usec_t dt);
22
extern int do_proc_loadavg(int update_every, usec_t dt);
23
extern int do_proc_net_stat_synproxy(int update_every, usec_t dt);
24
extern int do_proc_net_softnet_stat(int update_every, usec_t dt);
25
+extern int do_proc_uptime(int update_every, usec_t dt);
26
27
#endif /* NETDATA_PLUGIN_PROC_H */
src/proc_loadavg.c
+3
-4
@@ -4,8 +4,6 @@
4
#define MIN_LOADAVG_UPDATE_EVERY 5
5
6
int do_proc_loadavg(int update_every, usec_t dt) {
7
- (void)dt;
8
-
7
static procfile *ff = NULL;
8
static int do_loadavg = -1, do_all_processes = -1;
9
static usec_t last_loadavg_usec = 0;
@@ -14,10 +12,11 @@ int do_proc_loadavg(int update_every, usec_t dt) {
12
if(unlikely(!ff)) {
13
char filename[FILENAME_MAX + 1];
14
snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/loadavg");
15
+
16
ff = procfile_open(config_get("plugin:proc:/proc/loadavg", "filename to monitor", filename), " \t,:|/", PROCFILE_FLAG_DEFAULT);
17
+ if(unlikely(!ff))
18
+ return 1;
19
}
19
- if(unlikely(!ff))
20
- return 1;
20
21
ff = procfile_readall(ff);
22
if(unlikely(!ff))
src/proc_uptime.c
new
+54
@@ -0,0 +1,54 @@
1
+#include "common.h"
2
+
3
+int do_proc_uptime(int update_every, usec_t dt) {
4
+ (void)dt;
5
+
6
+ static RRDSET *st = NULL;
7
+ collected_number uptime = 0;
8
+
9
+#ifdef CLOCK_BOOTTIME_IS_AVAILABLE
10
+ uptime = now_boottime_usec() / 1000;
11
+#else
12
+ static procfile *ff = NULL;
13
+
14
+ if(unlikely(!ff)) {
15
+ char filename[FILENAME_MAX + 1];
16
+ snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/uptime");
17
+
18
+ ff = procfile_open(config_get("plugin:proc:/proc/uptime", "filename to monitor", filename), " \t", PROCFILE_FLAG_DEFAULT);
19
+ if(unlikely(!ff))
20
+ return 1;
21
+ }
22
+
23
+ ff = procfile_readall(ff);
24
+ if(unlikely(!ff))
25
+ return 0; // we return 0, so that we will retry to open it next time
26
+
27
+ if(unlikely(procfile_lines(ff) < 1)) {
28
+ error("/proc/uptime has no lines.");
29
+ return 1;
30
+ }
31
+ if(unlikely(procfile_linewords(ff, 0) < 1)) {
32
+ error("/proc/uptime has less than 1 word in it.");
33
+ return 1;
34
+ }
35
+
36
+ uptime = (collected_number)(strtold(procfile_lineword(ff, 0, 0), NULL) * 1000.0);
37
+#endif
38
+
39
+ // --------------------------------------------------------------------
40
+
41
+ if(unlikely(!st))
42
+ st = rrdset_find("system.uptime");
43
+
44
+ if(unlikely(!st)) {
45
+ st = rrdset_create("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000, update_every, RRDSET_TYPE_LINE);
46
+ rrddim_add(st, "uptime", NULL, 1, 1000, RRDDIM_ABSOLUTE);
47
+ }
48
+ else rrdset_next(st);
49
+
50
+ rrddim_set(st, "uptime", uptime);
51
+ rrdset_done(st);
52
+
53
+ return 0;
54
+}
src/web_buffer_svg.c
+43
-1
@@ -525,7 +525,49 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
525
if(unlikely(isalnum(*units)))
526
separator = " ";
527
528
- if(unlikely(value_is_null))
528
+ if(unlikely(!strcmp(units, "seconds"))) {
529
+ size_t s = (size_t)value;
530
+ size_t d = s / 86400;
531
+ s = s % 86400;
532
+
533
+ size_t h = s / 3600;
534
+ s = s % 3600;
535
+
536
+ size_t m = s / 60;
537
+ s = s % 60;
538
+
539
+ if(d)
540
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zu %s %02zu:%02zu:%02zu", d, (d == 1)?"day":"days", h, m, s);
541
+ else
542
+ snprintfz(value_string, VALUE_STRING_SIZE, "%02zu:%02zu:%02zu", h, m, s);
543
+ }
544
+
545
+ else if(unlikely(!strcmp(units, "minutes"))) {
546
+ size_t m = (size_t)value;
547
+ size_t d = m / (60 * 24);
548
+ m = m % (60 * 24);
549
+
550
+ size_t h = m / 60;
551
+ m = m % 60;
552
+
553
+ if(d)
554
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zud %02zuh %02zum", d, h, m);
555
+ else
556
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zuh %zum", h, m);
557
+ }
558
+
559
+ else if(unlikely(!strcmp(units, "hours"))) {
560
+ size_t h = (size_t)value;
561
+ size_t d = h / 24;
562
+ h = h % 24;
563
+
564
+ if(d)
565
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zud %zuh", d, h);
566
+ else
567
+ snprintfz(value_string, VALUE_STRING_SIZE, "%zuh", h);
568
+ }
569
+
570
+ else if(unlikely(value_is_null))
571
strcpy(value_string, "-");
572
573
else if(precision < 0) {