feat(proc.plugin): add Reboot Required collector (#19109)
* feat: add Reboot Required collector * add alert * remove delay * disable if not mounted in container
Ilya Mashchenko committed
Nov 30, 2024 at 13:57 UTC
91c15627ed3346379be076244c3fbcab5ee4b589
6 files changed
+89
CMakeLists.txt
+1
@@ -1602,6 +1602,7 @@ set(PROC_PLUGIN_FILES
1602
src/collectors/proc.plugin/proc_sys_kernel_random_entropy_avail.c
1603
src/collectors/proc.plugin/proc_vmstat.c
1604
src/collectors/proc.plugin/proc_uptime.c
1605
+ src/collectors/proc.plugin/run_reboot_required.c
1606
src/collectors/proc.plugin/proc_pressure.c
1607
src/collectors/proc.plugin/proc_pressure.h
1608
src/collectors/proc.plugin/sys_kernel_mm_ksm.c
src/collectors/all.h
+1
@@ -42,6 +42,7 @@
42
#define NETDATA_CHART_PRIO_SYSTEM_FILES_NR 1000
43
#define NETDATA_CHART_PRIO_SYSTEM_ENTROPY 1000
44
#define NETDATA_CHART_PRIO_SYSTEM_UPTIME 1000
45
+#define NETDATA_CHART_PRIO_SYSTEM_REBOOT_REQUIRED 1010
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
src/collectors/proc.plugin/plugin_proc.c
+2
@@ -21,6 +21,8 @@ static struct proc_module {
21
{.name = "/proc/sys/fs/file-nr", .dim = "file-nr", .func = do_proc_sys_fs_file_nr},
22
{.name = "/proc/sys/kernel/random/entropy_avail", .dim = "entropy", .func = do_proc_sys_kernel_random_entropy_avail},
23
24
+ {.name = "/run/reboot_required", .dim = "reboot-required", .func = do_run_reboot_required},
25
+
26
// pressure metrics
27
{.name = "/proc/pressure", .dim = "pressure", .func = do_proc_pressure},
28
src/collectors/proc.plugin/plugin_proc.h
+1
@@ -47,6 +47,7 @@ int do_proc_pagetypeinfo(int update_every, usec_t dt);
47
int do_sys_class_infiniband(int update_every, usec_t dt);
48
int do_sys_class_drm(int update_every, usec_t dt);
49
int get_numa_node_count(void);
50
+int do_run_reboot_required(int update_every, usec_t dt);
51
52
// metrics that need to be shared among data collectors
53
extern unsigned long long zfs_arcstats_shrinkable_cache_size_bytes;
src/collectors/proc.plugin/run_reboot_required.c
new
+69
@@ -0,0 +1,69 @@
1
+#include "plugin_proc.h"
2
+
3
+static int is_dir_mounted(const char *path) {
4
+ struct stat stat_buf, parent_stat_buf;
5
+ char parent_path[PATH_MAX];
6
+
7
+ if (stat(path, &stat_buf) == -1) {
8
+ return -1;
9
+ }
10
+
11
+ snprintfz(parent_path, sizeof(parent_path), "%s/..", path);
12
+ if (stat(parent_path, &parent_stat_buf) == -1) {
13
+ return -1;
14
+ }
15
+
16
+ return stat_buf.st_dev != parent_stat_buf.st_dev;
17
+}
18
+
19
+int do_run_reboot_required(int update_every, usec_t dt) {
20
+ (void)dt;
21
+
22
+ static char *signal_file_path = NULL;
23
+ static RRDSET *st = NULL;
24
+ static RRDDIM *rd_required = NULL;
25
+ static RRDDIM *rd_not_required = NULL;
26
+
27
+ if (!signal_file_path) {
28
+ char filename[FILENAME_MAX + 1];
29
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/var/run");
30
+
31
+ // Disable monitoring if running inside a container and the directory is not mounted from the host
32
+ if (getenv("NETDATA_LISTENER_PORT") != NULL) {
33
+ if (!netdata_configured_host_prefix || !*netdata_configured_host_prefix || is_dir_mounted(filename) != 1) {
34
+ return 1;
35
+ }
36
+ }
37
+
38
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/var/run/reboot-required");
39
+ signal_file_path = strdupz(filename);
40
+ }
41
+
42
+ if (unlikely(!st)) {
43
+ st = rrdset_create_localhost(
44
+ "system",
45
+ "post_update_reboot_status",
46
+ NULL,
47
+ "uptime",
48
+ NULL,
49
+ "Post-Update Reboot Status",
50
+ "status",
51
+ PLUGIN_PROC_NAME,
52
+ "/run/reboot_required",
53
+ NETDATA_CHART_PRIO_SYSTEM_REBOOT_REQUIRED,
54
+ update_every,
55
+ RRDSET_TYPE_LINE);
56
+
57
+ rd_required = rrddim_add(st, "required", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
58
+ rd_not_required = rrddim_add(st, "not_required", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
59
+ }
60
+
61
+ struct stat buf;
62
+ bool exists = (stat(signal_file_path, &buf) == 0);
63
+
64
+ rrddim_set_by_pointer(st, rd_required, exists ? 1 : 0);
65
+ rrddim_set_by_pointer(st, rd_not_required, exists ? 0 : 1);
66
+ rrdset_done(st);
67
+
68
+ return 0;
69
+}
src/health/health.d/reboot_required.conf
new
+15
@@ -0,0 +1,15 @@
1
+# you can disable an alarm notification by setting the 'to' line to: silent
2
+
3
+ alarm: system_post_update_reboot_status
4
+ on: system.post_update_reboot_status
5
+ class: Errors
6
+ type: System
7
+ component: OS
8
+host labels: _os=linux
9
+ calc: $required
10
+ units: status
11
+ every: 10s
12
+ warn: $this == 1
13
+ summary: System requires reboot after package updates
14
+ info: System requires reboot after package updates
15
+ to: sysadmin