@cryptotaxi247 / netdata-1 / commits / 7de64f49f

Add a plugin for the system clock synchronization state (#10895)

Co-authored-by: Joel Hans <joel.g.hans@gmail.com>

Vladimir Kobal committed Apr 14, 2021 at 12:20 UTC 7de64f49ff88375f76c253c8cc50ec4f07e5a806
15 files changed +304 -32
CMakeLists.txt
+6
@@ -458,6 +458,11 @@ set(DISKSPACE_PLUGIN_FILES
458 collectors/diskspace.plugin/plugin_diskspace.c
459 )
460
461 +set(TIMEX_PLUGIN_FILES
462 + collectors/timex.plugin/plugin_timex.h
463 + collectors/timex.plugin/plugin_timex.c
464 + )
465 +
466 set(FREEIPMI_PLUGIN_FILES
467 collectors/freeipmi.plugin/freeipmi_plugin.c
468 )
@@ -984,6 +989,7 @@ IF(LINUX)
989 add_executable(netdata config.h ${NETDATA_FILES}
990 ${CGROUPS_PLUGIN_FILES}
991 ${DISKSPACE_PLUGIN_FILES}
992 + ${TIMEX_PLUGIN_FILES}
993 ${PROC_PLUGIN_FILES}
994 ${TC_PLUGIN_FILES}
995 )
Makefile.am
+6
@@ -258,6 +258,11 @@ DISKSPACE_PLUGIN_FILES = \
258 collectors/diskspace.plugin/plugin_diskspace.c \
259 $(NULL)
260
261 +TIMEX_PLUGIN_FILES = \
262 + collectors/timex.plugin/plugin_timex.h \
263 + collectors/timex.plugin/plugin_timex.c \
264 + $(NULL)
265 +
266 FREEIPMI_PLUGIN_FILES = \
267 collectors/freeipmi.plugin/freeipmi_plugin.c \
268 $(LIBNETDATA_FILES) \
@@ -714,6 +719,7 @@ if LINUX
719 NETDATA_FILES += \
720 $(CGROUPS_PLUGIN_FILES) \
721 $(DISKSPACE_PLUGIN_FILES) \
722 + $(TIMEX_PLUGIN_FILES) \
723 $(PROC_PLUGIN_FILES) \
724 $(TC_PLUGIN_FILES) \
725 $(NULL)
collectors/COLLECTORS.md
+33 -29
@@ -26,35 +26,38 @@ issues](https://github.com/netdata/netdata/issues). Use the search bar to look f
26 collector—we may be looking for contributions from users such as yourself! If you don't see the collector there, make a
27 [feature request](https://community.netdata.cloud/c/feature-requests/7/none) on our community forums.
28
29 -- [Service and application collectors](#service-and-application-collectors)
30 - - [APM (application performance monitoring)](#apm-application-performance-monitoring)
31 - - [Containers and VMs](#containers-and-vms)
32 - - [Data stores](#data-stores)
33 - - [Distributed computing](#distributed-computing)
34 - - [Email](#email)
35 - - [Kubernetes](#kubernetes)
36 - - [Logs](#logs)
37 - - [Messaging](#messaging)
38 - - [Network](#network)
39 - - [Provisioning](#provisioning)
40 - - [Remote devices](#remote-devices)
41 - - [Search](#search)
42 - - [Storage](#storage)
43 - - [Web](#web)
44 -- [System collectors](#system-collectors)
45 - - [Applications](#applications)
46 - - [Disks and filesystems](#disks-and-filesystems)
47 - - [eBPF (extended Berkeley Packet Filter)](#ebpf)
48 - - [Hardware](#hardware)
49 - - [Memory](#memory)
50 - - [Networks](#networks)
51 - - [Processes](#processes)
52 - - [Resources](#resources)
53 - - [Users](#users)
54 -- [Netdata collectors](#netdata-collectors)
55 -- [Orchestrators](#orchestrators)
56 -- [Third-party collectors](#third-party-collectors)
57 -- [Etc](#etc)
29 +- [Supported collectors list](#supported-collectors-list)
30 + - [Service and application collectors](#service-and-application-collectors)
31 + - [Generic](#generic)
32 + - [APM (application performance monitoring)](#apm-application-performance-monitoring)
33 + - [Containers and VMs](#containers-and-vms)
34 + - [Data stores](#data-stores)
35 + - [Distributed computing](#distributed-computing)
36 + - [Email](#email)
37 + - [Kubernetes](#kubernetes)
38 + - [Logs](#logs)
39 + - [Messaging](#messaging)
40 + - [Network](#network)
41 + - [Provisioning](#provisioning)
42 + - [Remote devices](#remote-devices)
43 + - [Search](#search)
44 + - [Storage](#storage)
45 + - [Web](#web)
46 + - [System collectors](#system-collectors)
47 + - [Applications](#applications)
48 + - [Disks and filesystems](#disks-and-filesystems)
49 + - [eBPF](#ebpf)
50 + - [Hardware](#hardware)
51 + - [Memory](#memory)
52 + - [Networks](#networks)
53 + - [Operating systems](#operating-systems)
54 + - [Processes](#processes)
55 + - [Resources](#resources)
56 + - [Users](#users)
57 + - [Netdata collectors](#netdata-collectors)
58 + - [Orchestrators](#orchestrators)
59 + - [Third-party collectors](#third-party-collectors)
60 + - [Etc](#etc)
61
62 ## Service and application collectors
63
@@ -366,6 +369,7 @@ The Netdata Agent can collect these system- and hardware-level metrics using a v
369 - [Device mapper](/collectors/proc.plugin/README.md): Gather metrics about the Linux device mapper with the proc
370 collector.
371 - [Disk space](/collectors/diskspace.plugin/README.md): Collect disk space usage metrics on Linux mount points.
372 +- [Clock synchronization](/collectors/timex.plugin/README.md): Collect the system clock synchronization status on Linux.
373 - [Files and directories](https://learn.netdata.cloud/docs/agent/collectors/go.d.plugin/modules/filecheck): Gather
374 metrics about the existence, modification time, and size of files or directories.
375 - [ioping.plugin](/collectors/ioping.plugin/README.md): Measure disk read/write latency.
collectors/Makefile.am
+1
@@ -10,6 +10,7 @@ SUBDIRS = \
10 checks.plugin \
11 cups.plugin \
12 diskspace.plugin \
13 + timex.plugin \
14 fping.plugin \
15 ioping.plugin \
16 freebsd.plugin \
collectors/REFERENCE.md
+1
@@ -96,6 +96,7 @@ This section features a list of Netdata's plugins, with a boolean setting to ena
96 # PYTHONPATH environment variable =
97 # proc = yes
98 # diskspace = yes
99 + # timex = yes
100 # cgroups = yes
101 # tc = yes
102 # idlejitter = yes
collectors/all.h
+4
@@ -12,6 +12,7 @@
12 #include "idlejitter.plugin/plugin_idlejitter.h"
13 #include "cgroups.plugin/sys_fs_cgroup.h"
14 #include "diskspace.plugin/plugin_diskspace.h"
15 +#include "timex.plugin/plugin_timex.h"
16 #include "proc.plugin/plugin_proc.h"
17 #include "tc.plugin/plugin_tc.h"
18 #include "macos.plugin/plugin_macos.h"
@@ -53,6 +54,8 @@
54 #define NETDATA_CHART_PRIO_SYSTEM_SOFT_INTR 1100 // freebsd only
55 #define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000
56 #define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000
57 +#define NETDATA_CHART_PRIO_CLOCK_SYNC_STATE 1100
58 +#define NETDATA_CHART_PRIO_CLOCK_SYNC_OFFSET 1110
59 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_QUEUES 1200 // freebsd only
60 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_MESSAGES 1201
61 #define NETDATA_CHART_PRIO_SYSTEM_IPC_MSQ_SIZE 1202
@@ -339,6 +342,7 @@
342 #define NETDATA_CHART_PRIO_CHECKS 99999
343
344 #define NETDATA_CHART_PRIO_NETDATA_DISKSPACE 132020
345 +#define NETDATA_CHART_PRIO_NETDATA_TIMEX 132030
346 #define NETDATA_CHART_PRIO_NETDATA_TC_CPU 135000
347 #define NETDATA_CHART_PRIO_NETDATA_TC_TIME 135001
348
collectors/timex.plugin/Makefile.am new
+8
@@ -0,0 +1,8 @@
1 +# SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +AUTOMAKE_OPTIONS = subdir-objects
4 +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
5 +
6 +dist_noinst_DATA = \
7 + README.md \
8 + $(NULL)
collectors/timex.plugin/README.md new
+29
@@ -0,0 +1,29 @@
1 +<!--
2 +title: "timex.plugin"
3 +description: "Monitor the system clock synchronization state."
4 +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/timex.plugin/README.md
5 +-->
6 +
7 +# timex.plugin
8 +
9 +This plugin monitors the system clock synchronization state on Linux nodes.
10 +
11 +This plugin creates two charts:
12 +
13 +- System clock synchronization state
14 +- Computed time offset between local system and reference clock
15 +
16 +## Configuration
17 +
18 +Edit the `netdata.conf` configuration file using [`edit-config`](/docs/configure/nodes.md#use-edit-config-to-edit-configuration-files) from the [Netdata config directory](/docs/configure/nodes.md#the-netdata-config-directory), which is typically at `/etc/netdata`.
19 +
20 +Scroll down to the `[plugin:timex]` section to find the available options:
21 +
22 +```
23 +[plugin:timex]
24 + # update every = 1
25 + # clock synchronization state = yes
26 + # time offset = yes
27 +```
28 +
29 +[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Ftimex.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>)
collectors/timex.plugin/plugin_timex.c new
+176
@@ -0,0 +1,176 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#include "plugin_timex.h"
4 +#include "sys/timex.h"
5 +
6 +#define PLUGIN_TIMEX_NAME "timex.plugin"
7 +
8 +#define CONFIG_SECTION_TIMEX "plugin:timex"
9 +
10 +static void timex_main_cleanup(void *ptr)
11 +{
12 + struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
13 + static_thread->enabled = NETDATA_MAIN_THREAD_EXITING;
14 +
15 + info("cleaning up...");
16 +
17 + static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
18 +}
19 +
20 +void *timex_main(void *ptr)
21 +{
22 + netdata_thread_cleanup_push(timex_main_cleanup, ptr);
23 +
24 + int vdo_cpu_netdata = config_get_boolean(CONFIG_SECTION_TIMEX, "timex plugin resource charts", CONFIG_BOOLEAN_YES);
25 +
26 + int update_every = (int)config_get_number(CONFIG_SECTION_TIMEX, "update every", 10);
27 + if (update_every < localhost->rrd_update_every)
28 + update_every = localhost->rrd_update_every;
29 +
30 + int do_sync = config_get_boolean(CONFIG_SECTION_TIMEX, "clock synchronization state", CONFIG_BOOLEAN_YES);
31 + int do_offset = config_get_boolean(CONFIG_SECTION_TIMEX, "time offset", CONFIG_BOOLEAN_YES);
32 +
33 + if (unlikely(do_sync == CONFIG_BOOLEAN_NO && do_offset == CONFIG_BOOLEAN_NO)) {
34 + info("No charts to show");
35 + goto exit;
36 + }
37 +
38 + usec_t step = update_every * USEC_PER_SEC;
39 + heartbeat_t hb;
40 + heartbeat_init(&hb);
41 + while (!netdata_exit) {
42 + usec_t duration = heartbeat_monotonic_dt_to_now_usec(&hb);
43 + heartbeat_next(&hb, step);
44 +
45 + struct timex timex_buf = {};
46 + int sync_state = 0;
47 + sync_state = adjtimex(&timex_buf);
48 +
49 + collected_number divisor = USEC_PER_MS;
50 + if (timex_buf.status & STA_NANO)
51 + divisor = NSEC_PER_MSEC;
52 +
53 + // ----------------------------------------------------------------
54 +
55 + if (do_sync) {
56 + static RRDSET *st_sync_state = NULL;
57 + static RRDDIM *rd_sync_state;
58 +
59 + if (unlikely(!st_sync_state)) {
60 + st_sync_state = rrdset_create_localhost(
61 + "system",
62 + "clock_sync_state",
63 + NULL,
64 + "clock synchronization",
65 + NULL,
66 + "System Clock Synchronization State",
67 + "state",
68 + PLUGIN_TIMEX_NAME,
69 + NULL,
70 + NETDATA_CHART_PRIO_CLOCK_SYNC_STATE,
71 + update_every,
72 + RRDSET_TYPE_LINE);
73 +
74 + rd_sync_state = rrddim_add(st_sync_state, "state", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
75 + } else {
76 + rrdset_next(st_sync_state);
77 + }
78 +
79 + rrddim_set_by_pointer(st_sync_state, rd_sync_state, sync_state != TIME_ERROR ? 1 : 0);
80 + rrdset_done(st_sync_state);
81 + }
82 +
83 + if (do_sync) {
84 + static RRDSET *st_offset = NULL;
85 + static RRDDIM *rd_offset;
86 +
87 + if (unlikely(!st_offset)) {
88 + st_offset = rrdset_create_localhost(
89 + "system",
90 + "clock_sync_offset",
91 + NULL,
92 + "clock synchronization",
93 + NULL,
94 + "Computed Time Offset Between Local System and Reference Clock",
95 + "milliseconds",
96 + PLUGIN_TIMEX_NAME,
97 + NULL,
98 + NETDATA_CHART_PRIO_CLOCK_SYNC_OFFSET,
99 + update_every,
100 + RRDSET_TYPE_LINE);
101 +
102 + rd_offset = rrddim_add(st_offset, "offset", NULL, 1, divisor, RRD_ALGORITHM_ABSOLUTE);
103 + } else {
104 + rrdset_next(st_offset);
105 + }
106 +
107 + rrddim_set_by_pointer(st_offset, rd_offset, timex_buf.offset);
108 + rrdset_done(st_offset);
109 + }
110 +
111 + if (vdo_cpu_netdata) {
112 + static RRDSET *stcpu_thread = NULL, *st_duration = NULL;
113 + static RRDDIM *rd_user = NULL, *rd_system = NULL, *rd_duration = NULL;
114 +
115 + // ----------------------------------------------------------------
116 +
117 + struct rusage thread;
118 + getrusage(RUSAGE_THREAD, &thread);
119 +
120 + if (unlikely(!stcpu_thread)) {
121 + stcpu_thread = rrdset_create_localhost(
122 + "netdata",
123 + "plugin_timex",
124 + NULL,
125 + "timex",
126 + NULL,
127 + "NetData Timex Plugin CPU usage",
128 + "milliseconds/s",
129 + PLUGIN_TIMEX_NAME,
130 + NULL,
131 + NETDATA_CHART_PRIO_NETDATA_TIMEX,
132 + update_every,
133 + RRDSET_TYPE_STACKED);
134 +
135 + rd_user = rrddim_add(stcpu_thread, "user", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
136 + rd_system = rrddim_add(stcpu_thread, "system", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_INCREMENTAL);
137 + } else {
138 + rrdset_next(stcpu_thread);
139 + }
140 +
141 + rrddim_set_by_pointer(stcpu_thread, rd_user, thread.ru_utime.tv_sec * USEC_PER_SEC + thread.ru_utime.tv_usec);
142 + rrddim_set_by_pointer(
143 + stcpu_thread, rd_system, thread.ru_stime.tv_sec * USEC_PER_SEC + thread.ru_stime.tv_usec);
144 + rrdset_done(stcpu_thread);
145 +
146 + // ----------------------------------------------------------------
147 +
148 + if (unlikely(!st_duration)) {
149 + st_duration = rrdset_create_localhost(
150 + "netdata",
151 + "plugin_timex_dt",
152 + NULL,
153 + "timex",
154 + NULL,
155 + "NetData Timex Plugin Duration",
156 + "milliseconds/run",
157 + PLUGIN_TIMEX_NAME,
158 + NULL,
159 + NETDATA_CHART_PRIO_NETDATA_TIMEX + 1,
160 + update_every,
161 + RRDSET_TYPE_AREA);
162 +
163 + rd_duration = rrddim_add(st_duration, "duration", NULL, 1, USEC_PER_MS, RRD_ALGORITHM_ABSOLUTE);
164 + } else {
165 + rrdset_next(st_duration);
166 + }
167 +
168 + rrddim_set_by_pointer(st_duration, rd_duration, duration);
169 + rrdset_done(st_duration);
170 + }
171 + }
172 +
173 +exit:
174 + netdata_thread_cleanup_pop(1);
175 + return NULL;
176 +}
collectors/timex.plugin/plugin_timex.h new
+29
@@ -0,0 +1,29 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#ifndef NETDATA_PLUGIN_TIMEX_H
4 +#define NETDATA_PLUGIN_TIMEX_H
5 +
6 +#include "../../daemon/common.h"
7 +
8 +#if (TARGET_OS == OS_LINUX)
9 +
10 +#define NETDATA_PLUGIN_HOOK_LINUX_TIMEX \
11 + { \
12 + .name = "PLUGIN[timex]", \
13 + .config_section = CONFIG_SECTION_PLUGINS, \
14 + .config_name = "timex", \
15 + .enabled = 1, \
16 + .thread = NULL, \
17 + .init_routine = NULL, \
18 + .start_routine = timex_main \
19 + },
20 +
21 +extern void *timex_main(void *ptr);
22 +
23 +#else // (TARGET_OS == OS_LINUX)
24 +
25 +#define NETDATA_PLUGIN_HOOK_LINUX_TIMEX
26 +
27 +#endif // (TARGET_OS == OS_LINUX)
28 +
29 +#endif //NETDATA_PLUGIN_TIMEX_H
configure.ac
+1
@@ -1561,6 +1561,7 @@ AC_CONFIG_FILES([
1561 collectors/charts.d.plugin/Makefile
1562 collectors/checks.plugin/Makefile
1563 collectors/diskspace.plugin/Makefile
1564 + collectors/timex.plugin/Makefile
1565 collectors/fping.plugin/Makefile
1566 collectors/ioping.plugin/Makefile
1567 collectors/freebsd.plugin/Makefile
daemon/main.c
+1
@@ -79,6 +79,7 @@ struct netdata_static_thread static_threads[] = {
79 // linux internal plugins
80 NETDATA_PLUGIN_HOOK_LINUX_PROC
81 NETDATA_PLUGIN_HOOK_LINUX_DISKSPACE
82 + NETDATA_PLUGIN_HOOK_LINUX_TIMEX
83 NETDATA_PLUGIN_HOOK_LINUX_CGROUPS
84 NETDATA_PLUGIN_HOOK_LINUX_TC
85
tests/alarm_repetition/netdata.conf_with_repetition
+1
@@ -29,6 +29,7 @@
29 [plugins]
30 proc = yes
31 diskspace = no
32 + timex = no
33 cgroups = no
34 tc = no
35 idlejitter = no
tests/alarm_repetition/netdata.conf_without_repetition
+1
@@ -29,6 +29,7 @@
29 [plugins]
30 proc = yes
31 diskspace = no
32 + timex = no
33 cgroups = no
34 tc = no
35 idlejitter = no
web/gui/dashboard_info.js
+7 -3
@@ -842,6 +842,10 @@ netdataDashboard.context = {
842 info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, is a pool of random numbers (<a href="https://en.wikipedia.org/wiki//dev/random" target="_blank">/dev/random</a>) that is mainly used in cryptography. If the pool of entropy gets empty, processes requiring random numbers may run a lot slower (it depends on the interface each program uses), waiting for the pool to be replenished. Ideally a system with high entropy demands should have a hardware device for that purpose (TPM is one such device). There are also several software-only options you may install, like <code>haveged</code>, although these are generally useful only in servers.'
843 },
844
845 + 'system.clock_sync_state': {
846 + info: 'State map: 0 - not synchronized, 1 - synchronized'
847 + },
848 +
849 'system.forks': {
850 colors: '#5555DD',
851 info: 'Number of new processes created.'
@@ -1461,13 +1465,13 @@ netdataDashboard.context = {
1465 info: 'inodes (or index nodes) are filesystem objects (e.g. files and directories). On many types of file system implementations, the maximum number of inodes is fixed at filesystem creation, limiting the maximum number of files the filesystem can hold. It is possible for a device to run out of inodes. When this happens, new files cannot be created on the device, even though there may be free space available.'
1466 },
1467
1468 + // ------------------------------------------------------------------------
1469 + // MYSQL
1470 +
1471 'mysql.net': {
1472 info: 'The amount of data sent to mysql clients (<strong>out</strong>) and received from mysql clients (<strong>in</strong>).'
1473 },
1474
1468 - // ------------------------------------------------------------------------
1469 - // MYSQL
1470 -
1475 'mysql.queries': {
1476 info: 'The number of statements executed by the server.<ul>' +
1477 '<li><strong>queries</strong> counts the statements executed within stored SQL programs.</li>' +