diff options
-rw-r--r-- | collectors/all.h | 1 | ||||
-rw-r--r-- | collectors/timex.plugin/README.md | 11 | ||||
-rw-r--r-- | collectors/timex.plugin/plugin_timex.c | 58 | ||||
-rw-r--r-- | web/gui/dashboard_info.js | 11 |
4 files changed, 73 insertions, 8 deletions
diff --git a/collectors/all.h b/collectors/all.h index 9f3178f15e..61f3c01bff 100644 --- a/collectors/all.h +++ b/collectors/all.h @@ -44,6 +44,7 @@ #define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000 #define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000 #define NETDATA_CHART_PRIO_CLOCK_SYNC_STATE 1100 +#define NETDATA_CHART_PRIO_CLOCK_STATUS 1105 #define NETDATA_CHART_PRIO_CLOCK_SYNC_OFFSET 1110 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 1200 // freebsd only #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1201 diff --git a/collectors/timex.plugin/README.md b/collectors/timex.plugin/README.md index 2956512f1d..18665f8070 100644 --- a/collectors/timex.plugin/README.md +++ b/collectors/timex.plugin/README.md @@ -8,10 +8,11 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/timex This plugin monitors the system kernel clock synchronization state. -This plugin creates two charts: +This plugin creates the following charts: -- System clock synchronization state according to the system kernel -- Computed time offset between local system and reference clock +- System clock synchronization state according to the system kernel +- System clock status which gives the value of the `time_status` variable in the kernel +- Computed time offset between local system and reference clock This is obtained from the information provided by the [ntp_adjtime()](https://man7.org/linux/man-pages/man2/adjtimex.2.html) system call. An unsynchronized clock may indicate a hardware clock error, or an issue with UTC synchronization. @@ -22,11 +23,9 @@ Edit the `netdata.conf` configuration file using [`edit-config`](/docs/configure Scroll down to the `[plugin:timex]` section to find the available options: -``` +```ini [plugin:timex] # update every = 1 # clock synchronization state = yes # time offset = yes ``` - - diff --git a/collectors/timex.plugin/plugin_timex.c b/collectors/timex.plugin/plugin_timex.c index 832b5e863b..b8d75e5733 100644 --- a/collectors/timex.plugin/plugin_timex.c +++ b/collectors/timex.plugin/plugin_timex.c @@ -7,6 +7,29 @@ #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; @@ -79,6 +102,36 @@ 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_offset) { @@ -133,13 +186,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); diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js index f2f68e99f2..67c207658a 100644 --- a/web/gui/dashboard_info.js +++ b/web/gui/dashboard_info.js @@ -1316,6 +1316,17 @@ netdataDashboard.context = { '<p><b>State map</b>: 0 - not synchronized, 1 - synchronized.</p>' }, + 'system.clock_status': { + info:'<p>The kernel code can operate in various modes and with various features enabled or disabled, as selected by the '+ + '<a href="https://man7.org/linux/man-pages/man2/adjtimex.2.html" target="_blank">ntp_adjtime()</a> system call. '+ + 'The system clock status shows the value of the <b>time_status</b> variable in the kernel. '+ + 'The bits of the variable are used to control these functions and record error conditions as they exist.</p>'+ + '<p><b>UNSYNC</b> - set/cleared by the caller to indicate clock unsynchronized (e.g., when no peers are reachable). '+ + 'This flag is usually controlled by an application program, but the operating system may also set it. '+ + '<b>CLOCKERR</b> - set/cleared by the external hardware clock driver to indicate hardware fault.</p>'+ + '<p><b>Status map</b>: 0 - bit unset, 1 - bit set.</p>' + }, + 'system.clock_sync_offset': { info: 'A typical NTP client regularly polls one or more NTP servers. '+ 'The client must compute its '+ |