]> arthur.barton.de Git - netdata.git/commitdiff
uptime plugin; fixes #1546; fixes #1507
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 11 Jan 2017 19:44:38 +0000 (21:44 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 11 Jan 2017 19:44:38 +0000 (21:44 +0200)
CMakeLists.txt
src/Makefile.am
src/clocks.h
src/plugin_proc.c
src/plugin_proc.h
src/proc_loadavg.c
src/proc_uptime.c [new file with mode: 0644]
src/web_buffer_svg.c

index 47faf76b869e5e1c14139a82a911d9d7f02878ee..f4eb2872ff3bd047def6205bf1103143781714c7 100755 (executable)
@@ -101,7 +101,7 @@ set(NETDATA_SOURCE_FILES
         src/registry_person.c
         src/registry_person.h
         src/registry_machine.c
-        src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c)
+        src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c)
 
 set(APPS_PLUGIN_SOURCE_FILES
         src/appconfig.c
index 6ceeecde71c1d671cdc9307d335311401db6d564..12f296c1f8503d9a47f19c31d4df95636e973bf5 100644 (file)
@@ -83,6 +83,7 @@ netdata_SOURCES += \
        $(NULL)
 else
 netdata_SOURCES += \
+       ipc.c ipc.h \
        plugin_proc.c plugin_proc.h \
        proc_diskstats.c \
        proc_interrupts.c \
@@ -102,7 +103,7 @@ netdata_SOURCES += \
        proc_stat.c \
        proc_sys_kernel_random_entropy_avail.c \
        proc_vmstat.c \
-       ipc.c ipc.h \
+       proc_uptime.c \
        sys_kernel_mm_ksm.c \
        $(NULL)
 endif
index 9634ac67e5007e16efe3ddc8dead592089373054..c1b8e70179ec93acda3025e0afa0e3163e03d290 100644 (file)
@@ -29,6 +29,10 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts);
 #ifndef CLOCK_BOOTTIME
 /* fallback to CLOCK_MONOTONIC if not available */
 #define CLOCK_BOOTTIME  CLOCK_MONOTONIC
+#else
+#ifdef HAVE_CLOCK_GETTIME
+#define CLOCK_BOOTTIME_IS_AVAILABLE 1 // required for /proc/uptime
+#endif
 #endif
 
 typedef unsigned long long usec_t;
index 4188c9a2b617334d2b3eec2b630ebc4e7a09bc89..ed483d6754da25e5f009b16afd65957d26794316 100644 (file)
@@ -35,6 +35,7 @@ void *proc_main(void *ptr)
     int vdo_proc_softirqs           = !config_get_boolean("plugin:proc", "/proc/softirqs", 1);
     int vdo_proc_net_softnet_stat   = !config_get_boolean("plugin:proc", "/proc/net/softnet_stat", 1);
     int vdo_proc_loadavg            = !config_get_boolean("plugin:proc", "/proc/loadavg", 1);
+    int vdo_proc_uptime             = !config_get_boolean("plugin:proc", "/proc/uptime", 1);
     int vdo_ipc                     = !config_get_boolean("plugin:proc", "ipc", 1);
     int vdo_sys_kernel_mm_ksm       = !config_get_boolean("plugin:proc", "/sys/kernel/mm/ksm", 1);
     int vdo_cpu_netdata             = !config_get_boolean("plugin:proc", "netdata server resources", 1);
@@ -58,6 +59,7 @@ void *proc_main(void *ptr)
     usec_t sutime_proc_softirqs = 0ULL;
     usec_t sutime_proc_net_softnet_stat = 0ULL;
     usec_t sutime_proc_loadavg = 0ULL;
+    usec_t sutime_proc_uptime = 0ULL;
     usec_t sutime_ipc = 0ULL;
     usec_t sutime_sys_kernel_mm_ksm = 0ULL;
 
@@ -92,6 +94,14 @@ void *proc_main(void *ptr)
         }
         if(unlikely(netdata_exit)) break;
 
+        if(!vdo_proc_uptime) {
+            debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_uptime().");
+            now = now_realtime_usec();
+            vdo_proc_uptime = do_proc_uptime(rrd_update_every, (sutime_proc_uptime > 0)?now - sutime_proc_uptime:0ULL);
+            sutime_proc_uptime = now;
+        }
+        if(unlikely(netdata_exit)) break;
+
         if(!vdo_ipc) {
             debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_ipc().");
             now = now_realtime_usec();
index 4e0cbc3ceed0c1c73c9598d0d0073f1ef1aae483..0f52e4e451ddd5e2ed8b4a302ce4ad7f986695ac 100644 (file)
@@ -22,5 +22,6 @@ extern int do_sys_kernel_mm_ksm(int update_every, usec_t dt);
 extern int do_proc_loadavg(int update_every, usec_t dt);
 extern int do_proc_net_stat_synproxy(int update_every, usec_t dt);
 extern int do_proc_net_softnet_stat(int update_every, usec_t dt);
+extern int do_proc_uptime(int update_every, usec_t dt);
 
 #endif /* NETDATA_PLUGIN_PROC_H */
index c0f3902c8555cdefbda7755afc3906cc8eee7a1f..3256cad40303ec6308794bed82fdf73906eddd79 100644 (file)
@@ -4,8 +4,6 @@
 #define MIN_LOADAVG_UPDATE_EVERY 5
 
 int do_proc_loadavg(int update_every, usec_t dt) {
-    (void)dt;
-
     static procfile *ff = NULL;
     static int do_loadavg = -1, do_all_processes = -1;
     static usec_t last_loadavg_usec = 0;
@@ -14,10 +12,11 @@ int do_proc_loadavg(int update_every, usec_t dt) {
     if(unlikely(!ff)) {
         char filename[FILENAME_MAX + 1];
         snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/loadavg");
+
         ff = procfile_open(config_get("plugin:proc:/proc/loadavg", "filename to monitor", filename), " \t,:|/", PROCFILE_FLAG_DEFAULT);
+        if(unlikely(!ff))
+            return 1;
     }
-    if(unlikely(!ff))
-        return 1;
 
     ff = procfile_readall(ff);
     if(unlikely(!ff))
diff --git a/src/proc_uptime.c b/src/proc_uptime.c
new file mode 100644 (file)
index 0000000..9f341a3
--- /dev/null
@@ -0,0 +1,54 @@
+#include "common.h"
+
+int do_proc_uptime(int update_every, usec_t dt) {
+    (void)dt;
+
+    static RRDSET *st = NULL;
+    collected_number uptime = 0;
+
+#ifdef CLOCK_BOOTTIME_IS_AVAILABLE
+    uptime = now_boottime_usec() / 1000;
+#else
+    static procfile *ff = NULL;
+
+    if(unlikely(!ff)) {
+        char filename[FILENAME_MAX + 1];
+        snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/uptime");
+
+        ff = procfile_open(config_get("plugin:proc:/proc/uptime", "filename to monitor", filename), " \t", PROCFILE_FLAG_DEFAULT);
+        if(unlikely(!ff))
+            return 1;
+    }
+
+    ff = procfile_readall(ff);
+    if(unlikely(!ff))
+        return 0; // we return 0, so that we will retry to open it next time
+
+    if(unlikely(procfile_lines(ff) < 1)) {
+        error("/proc/uptime has no lines.");
+        return 1;
+    }
+    if(unlikely(procfile_linewords(ff, 0) < 1)) {
+        error("/proc/uptime has less than 1 word in it.");
+        return 1;
+    }
+
+    uptime = (collected_number)(strtold(procfile_lineword(ff, 0, 0), NULL) * 1000.0);
+#endif
+
+    // --------------------------------------------------------------------
+
+    if(unlikely(!st))
+        st = rrdset_find("system.uptime");
+
+    if(unlikely(!st)) {
+        st = rrdset_create("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000, update_every, RRDSET_TYPE_LINE);
+        rrddim_add(st, "uptime", NULL, 1, 1000, RRDDIM_ABSOLUTE);
+    }
+    else rrdset_next(st);
+
+    rrddim_set(st, "uptime", uptime);
+    rrdset_done(st);
+
+    return 0;
+}
index 3e847b5d9b0fe43ebe28d079b4b8019e9b47a6f2..dd11c0abc423ab795087dae55e8493c7d128c366 100644 (file)
@@ -525,7 +525,49 @@ void buffer_svg(BUFFER *wb, const char *label, calculated_number value, const ch
     if(unlikely(isalnum(*units)))
         separator = " ";
 
-    if(unlikely(value_is_null))
+    if(unlikely(!strcmp(units, "seconds"))) {
+        size_t s = (size_t)value;
+        size_t d = s / 86400;
+        s = s % 86400;
+
+        size_t h = s / 3600;
+        s = s % 3600;
+
+        size_t m = s / 60;
+        s = s % 60;
+
+        if(d)
+            snprintfz(value_string, VALUE_STRING_SIZE, "%zu %s %02zu:%02zu:%02zu", d, (d == 1)?"day":"days", h, m, s);
+        else
+            snprintfz(value_string, VALUE_STRING_SIZE, "%02zu:%02zu:%02zu", h, m, s);
+    }
+
+    else if(unlikely(!strcmp(units, "minutes"))) {
+        size_t m = (size_t)value;
+        size_t d = m / (60 * 24);
+        m = m % (60 * 24);
+
+        size_t h = m / 60;
+        m = m % 60;
+
+        if(d)
+            snprintfz(value_string, VALUE_STRING_SIZE, "%zud %02zuh %02zum", d, h, m);
+        else
+            snprintfz(value_string, VALUE_STRING_SIZE, "%zuh %zum", h, m);
+    }
+
+    else if(unlikely(!strcmp(units, "hours"))) {
+        size_t h = (size_t)value;
+        size_t d = h / 24;
+        h = h % 24;
+
+        if(d)
+            snprintfz(value_string, VALUE_STRING_SIZE, "%zud %zuh", d, h);
+        else
+            snprintfz(value_string, VALUE_STRING_SIZE, "%zuh", h);
+    }
+
+    else if(unlikely(value_is_null))
         strcpy(value_string, "-");
 
     else if(precision < 0) {