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
$(NULL)
else
netdata_SOURCES += \
+ ipc.c ipc.h \
plugin_proc.c plugin_proc.h \
proc_diskstats.c \
proc_interrupts.c \
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
#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;
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);
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;
}
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();
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 */
#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;
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))
--- /dev/null
+#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;
+}
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) {