summaryrefslogtreecommitdiffstats
path: root/collectors/timex.plugin/plugin_timex.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/timex.plugin/plugin_timex.c')
-rw-r--r--collectors/timex.plugin/plugin_timex.c74
1 files changed, 69 insertions, 5 deletions
diff --git a/collectors/timex.plugin/plugin_timex.c b/collectors/timex.plugin/plugin_timex.c
index b69f34292..34a3415a0 100644
--- a/collectors/timex.plugin/plugin_timex.c
+++ b/collectors/timex.plugin/plugin_timex.c
@@ -1,12 +1,35 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "daemon/common.h"
-#include "sys/timex.h"
+#include "libnetdata/os.h"
#define PLUGIN_TIMEX_NAME "timex.plugin"
#define CONFIG_SECTION_TIMEX "plugin:timex"
+struct status_codes {
+ char *name;
+ int code;
+ RRDDIM *rd;
+} sta_codes[] = {
+ // {"pll", STA_PLL, NULL},
+ // {"ppsfreq", STA_PPSFREQ, NULL},
+ // {"ppstime", STA_PPSTIME, NULL},
+ // {"fll", STA_FLL, NULL},
+ // {"ins", STA_INS, NULL},
+ // {"del", STA_DEL, NULL},
+ {"unsync", STA_UNSYNC, NULL},
+ // {"freqhold", STA_FREQHOLD, NULL},
+ // {"ppssignal", STA_PPSSIGNAL, NULL},
+ // {"ppsjitter", STA_PPSJITTER, NULL},
+ // {"ppswander", STA_PPSWANDER, NULL},
+ // {"ppserror", STA_PPSERROR, NULL},
+ {"clockerr", STA_CLOCKERR, NULL},
+ // {"nano", STA_NANO, NULL},
+ // {"clk", STA_CLK, NULL},
+ {NULL, 0, NULL},
+};
+
static void timex_main_cleanup(void *ptr)
{
struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
@@ -44,7 +67,17 @@ void *timex_main(void *ptr)
struct timex timex_buf = {};
int sync_state = 0;
- sync_state = adjtimex(&timex_buf);
+ static int prev_sync_state = 0;
+
+ sync_state = ADJUST_TIMEX(&timex_buf);
+
+ int non_seq_failure = (sync_state == -1 && prev_sync_state != -1);
+ prev_sync_state = sync_state;
+
+ if (non_seq_failure) {
+ error("Cannot get clock synchronization state");
+ continue;
+ }
collected_number divisor = USEC_PER_MS;
if (timex_buf.status & STA_NANO)
@@ -78,9 +111,39 @@ void *timex_main(void *ptr)
rrddim_set_by_pointer(st_sync_state, rd_sync_state, sync_state != TIME_ERROR ? 1 : 0);
rrdset_done(st_sync_state);
+
+ static RRDSET *st_clock_status = NULL;
+
+ if (unlikely(!st_clock_status)) {
+ st_clock_status = rrdset_create_localhost(
+ "system",
+ "clock_status",
+ NULL,
+ "clock synchronization",
+ NULL,
+ "System Clock Status",
+ "status",
+ PLUGIN_TIMEX_NAME,
+ NULL,
+ NETDATA_CHART_PRIO_CLOCK_STATUS,
+ update_every,
+ RRDSET_TYPE_LINE);
+
+ for (int i = 0; sta_codes[i].name != NULL; i++) {
+ sta_codes[i].rd =
+ rrddim_add(st_clock_status, sta_codes[i].name, NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ } else {
+ rrdset_next(st_clock_status);
+ }
+
+ for (int i = 0; sta_codes[i].name != NULL; i++) {
+ rrddim_set_by_pointer(st_clock_status, sta_codes[i].rd, timex_buf.status & sta_codes[i].code ? 1 : 0);
+ }
+ rrdset_done(st_clock_status);
}
- if (do_sync) {
+ if (do_offset) {
static RRDSET *st_offset = NULL;
static RRDDIM *rd_offset;
@@ -132,13 +195,14 @@ void *timex_main(void *ptr)
update_every,
RRDSET_TYPE_STACKED);
- rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
+ rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
rd_system = rrddim_add(stcpu_thread, "system", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
} else {
rrdset_next(stcpu_thread);
}
- rrddim_set_by_pointer(stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec);
+ rrddim_set_by_pointer(
+ stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec);
rrddim_set_by_pointer(
stcpu_thread, rd_system, thread.ru_stime.tv_sec * USEC_PER_SEC + thread.ru_stime.tv_usec);
rrdset_done(stcpu_thread);