From: Costa Tsaousis (ktsaou) Date: Wed, 11 Jan 2017 19:44:38 +0000 (+0200) Subject: uptime plugin; fixes #1546; fixes #1507 X-Git-Tag: v1.5.0~32^2 X-Git-Url: https://arthur.barton.de/gitweb/?p=netdata.git;a=commitdiff_plain;h=1887a9aba01139d60fa1f5d313618e79ab268154 uptime plugin; fixes #1546; fixes #1507 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 47faf76b..f4eb2872 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 6ceeecde..12f296c1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/clocks.h b/src/clocks.h index 9634ac67..c1b8e701 100644 --- a/src/clocks.h +++ b/src/clocks.h @@ -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; diff --git a/src/plugin_proc.c b/src/plugin_proc.c index 4188c9a2..ed483d67 100644 --- a/src/plugin_proc.c +++ b/src/plugin_proc.c @@ -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(); diff --git a/src/plugin_proc.h b/src/plugin_proc.h index 4e0cbc3c..0f52e4e4 100644 --- a/src/plugin_proc.h +++ b/src/plugin_proc.h @@ -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 */ diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c index c0f3902c..3256cad4 100644 --- a/src/proc_loadavg.c +++ b/src/proc_loadavg.c @@ -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 index 00000000..9f341a33 --- /dev/null +++ b/src/proc_uptime.c @@ -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; +} diff --git a/src/web_buffer_svg.c b/src/web_buffer_svg.c index 3e847b5d..dd11c0ab 100644 --- a/src/web_buffer_svg.c +++ b/src/web_buffer_svg.c @@ -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) {