@cryptotaxi247 / netdata-1 / commits / 64efa1122

feat(collectors/timex.plugin): add clock status chart (#12501)

Co-authored-by: Suraj Neupane <neupanesuraj@gmail.com>

Ilya Mashchenko committed Mar 24, 2022 at 13:02 UTC 64efa1122d33d0975694b7ba3808489928a2c4a1
4 files changed +73 -8
collectors/all.h
+1
@@ -44,6 +44,7 @@
44 #define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000
45 #define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000
46 #define NETDATA_CHART_PRIO_CLOCK_SYNC_STATE 1100
47 +#define NETDATA_CHART_PRIO_CLOCK_STATUS 1105
48 #define NETDATA_CHART_PRIO_CLOCK_SYNC_OFFSET 1110
49 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 1200 // freebsd only
50 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1201
collectors/timex.plugin/README.md
+5 -6
@@ -8,10 +8,11 @@ custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/timex
8
9 This plugin monitors the system kernel clock synchronization state.
10
11 -This plugin creates two charts:
11 +This plugin creates the following charts:
12
13 -- System clock synchronization state according to the system kernel
14 -- Computed time offset between local system and reference clock
13 +- System clock synchronization state according to the system kernel
14 +- System clock status which gives the value of the `time_status` variable in the kernel
15 +- Computed time offset between local system and reference clock
16
17 This is obtained from the information provided by the [ntp_adjtime()](https://man7.org/linux/man-pages/man2/adjtimex.2.html) system call.
18 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
23
24 Scroll down to the `[plugin:timex]` section to find the available options:
25
25 -```
26 +```ini
27 [plugin:timex]
28 # update every = 1
29 # clock synchronization state = yes
30 # time offset = yes
31 ```
31 -
32 -
collectors/timex.plugin/plugin_timex.c
+56 -2
@@ -7,6 +7,29 @@
7
8 #define CONFIG_SECTION_TIMEX "plugin:timex"
9
10 +struct status_codes {
11 + char *name;
12 + int code;
13 + RRDDIM *rd;
14 +} sta_codes[] = {
15 + // {"pll", STA_PLL, NULL},
16 + // {"ppsfreq", STA_PPSFREQ, NULL},
17 + // {"ppstime", STA_PPSTIME, NULL},
18 + // {"fll", STA_FLL, NULL},
19 + // {"ins", STA_INS, NULL},
20 + // {"del", STA_DEL, NULL},
21 + {"unsync", STA_UNSYNC, NULL},
22 + // {"freqhold", STA_FREQHOLD, NULL},
23 + // {"ppssignal", STA_PPSSIGNAL, NULL},
24 + // {"ppsjitter", STA_PPSJITTER, NULL},
25 + // {"ppswander", STA_PPSWANDER, NULL},
26 + // {"ppserror", STA_PPSERROR, NULL},
27 + {"clockerr", STA_CLOCKERR, NULL},
28 + // {"nano", STA_NANO, NULL},
29 + // {"clk", STA_CLK, NULL},
30 + {NULL, 0, NULL},
31 +};
32 +
33 static void timex_main_cleanup(void *ptr)
34 {
35 struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
@@ -79,6 +102,36 @@ void *timex_main(void *ptr)
102
103 rrddim_set_by_pointer(st_sync_state, rd_sync_state, sync_state != TIME_ERROR ? 1 : 0);
104 rrdset_done(st_sync_state);
105 +
106 + static RRDSET *st_clock_status = NULL;
107 +
108 + if (unlikely(!st_clock_status)) {
109 + st_clock_status = rrdset_create_localhost(
110 + "system",
111 + "clock_status",
112 + NULL,
113 + "clock synchronization",
114 + NULL,
115 + "System Clock Status",
116 + "status",
117 + PLUGIN_TIMEX_NAME,
118 + NULL,
119 + NETDATA_CHART_PRIO_CLOCK_STATUS,
120 + update_every,
121 + RRDSET_TYPE_LINE);
122 +
123 + for (int i = 0; sta_codes[i].name != NULL; i++) {
124 + sta_codes[i].rd =
125 + rrddim_add(st_clock_status, sta_codes[i].name, NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
126 + }
127 + } else {
128 + rrdset_next(st_clock_status);
129 + }
130 +
131 + for (int i = 0; sta_codes[i].name != NULL; i++) {
132 + rrddim_set_by_pointer(st_clock_status, sta_codes[i].rd, timex_buf.status & sta_codes[i].code ? 1 : 0);
133 + }
134 + rrdset_done(st_clock_status);
135 }
136
137 if (do_offset) {
@@ -133,13 +186,14 @@ void *timex_main(void *ptr)
186 update_every,
187 RRDSET_TYPE_STACKED);
188
136 - rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
189 + rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
190 rd_system = rrddim_add(stcpu_thread, "system", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
191 } else {
192 rrdset_next(stcpu_thread);
193 }
194
142 - rrddim_set_by_pointer(stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec);
195 + rrddim_set_by_pointer(
196 + stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec);
197 rrddim_set_by_pointer(
198 stcpu_thread, rd_system, thread.ru_stime.tv_sec * USEC_PER_SEC + thread.ru_stime.tv_usec);
199 rrdset_done(stcpu_thread);
web/gui/dashboard_info.js
+11
@@ -1316,6 +1316,17 @@ netdataDashboard.context = {
1316 '<p><b>State map</b>: 0 - not synchronized, 1 - synchronized.</p>'
1317 },
1318
1319 + 'system.clock_status': {
1320 + info:'<p>The kernel code can operate in various modes and with various features enabled or disabled, as selected by the '+
1321 + '<a href="https://man7.org/linux/man-pages/man2/adjtimex.2.html" target="_blank">ntp_adjtime()</a> system call. '+
1322 + 'The system clock status shows the value of the <b>time_status</b> variable in the kernel. '+
1323 + 'The bits of the variable are used to control these functions and record error conditions as they exist.</p>'+
1324 + '<p><b>UNSYNC</b> - set/cleared by the caller to indicate clock unsynchronized (e.g., when no peers are reachable). '+
1325 + 'This flag is usually controlled by an application program, but the operating system may also set it. '+
1326 + '<b>CLOCKERR</b> - set/cleared by the external hardware clock driver to indicate hardware fault.</p>'+
1327 + '<p><b>Status map</b>: 0 - bit unset, 1 - bit set.</p>'
1328 + },
1329 +
1330 'system.clock_sync_offset': {
1331 info: 'A typical NTP client regularly polls one or more NTP servers. '+
1332 'The client must compute its '+