master
c 133 lines 5.17 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define PULSE_INTERNALS 1
4 #include "pulse-daemon.h"
5
6 static void pulse_daemon_cpu_usage_do(bool extended __maybe_unused) {
7 struct rusage me;
8 getrusage(RUSAGE_SELF, &me);
9
10 {
11 static RRDSET *st_cpu = NULL;
12 static RRDDIM *rd_cpu_user = NULL,
13 *rd_cpu_system = NULL;
14
15 if (unlikely(!st_cpu)) {
16 st_cpu = rrdset_create_localhost(
17 "netdata"
18 , "server_cpu"
19 , NULL
20 , "CPU usage"
21 , NULL
22 , "Netdata CPU usage"
23 , "milliseconds/s"
24 , "netdata"
25 , "pulse"
26 , 130000
27 , localhost->rrd_update_every
28 , RRDSET_TYPE_STACKED
29 );
30
31 rd_cpu_user = rrddim_add(st_cpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
32 rd_cpu_system = rrddim_add(st_cpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
33 }
34
35 rrddim_set_by_pointer(st_cpu, rd_cpu_user, (collected_number )(me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec));
36 rrddim_set_by_pointer(st_cpu, rd_cpu_system, (collected_number )(me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec));
37 rrdset_done(st_cpu);
38 }
39 }
40
41 static void pulse_daemon_uptime_do(bool extended __maybe_unused) {
42 {
43 static time_t netdata_boottime_time = 0;
44 if (!netdata_boottime_time)
45 netdata_boottime_time = now_boottime_sec();
46
47 time_t netdata_uptime = now_boottime_sec() - netdata_boottime_time;
48
49 static RRDSET *st_uptime = NULL;
50 static RRDDIM *rd_uptime = NULL;
51
52 if (unlikely(!st_uptime)) {
53 st_uptime = rrdset_create_localhost(
54 "netdata",
55 "uptime",
56 NULL,
57 "Uptime",
58 NULL,
59 "Netdata uptime",
60 "seconds",
61 "netdata",
62 "pulse",
63 130150,
64 localhost->rrd_update_every,
65 RRDSET_TYPE_LINE);
66
67 rd_uptime = rrddim_add(st_uptime, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
68 }
69
70 rrddim_set_by_pointer(st_uptime, rd_uptime, netdata_uptime);
71 rrdset_done(st_uptime);
72 }
73 }
74
75 // Called from a single pulse daemon thread, so last_refresh_ut needs no synchronization.
76 static void pulse_daemon_timezone_do(bool extended __maybe_unused) {
77 static usec_t last_refresh_ut = 0;
78
79 usec_t now_ut = now_monotonic_usec();
80
81 // refresh every 30 minutes to pick up DST changes
82 if (now_ut - last_refresh_ut >= 30 * 60 * USEC_PER_SEC) {
83 if (system_timezone_is_user_configured()) {
84 // User explicitly configured a timezone in netdata.conf — respect it,
85 // just refresh the abbreviation and offset (handles DST transitions).
86 static bool mismatch_logged = false;
87 if (!mismatch_logged) {
88 mismatch_logged = true;
89 char sys_buf[FILENAME_MAX + 1];
90 const char *sys_tz = detect_system_timezone_name(sys_buf, sizeof(sys_buf));
91 SYSTEM_TZ tz = system_tz_get();
92 if (sys_tz && tz.timezone && strcmp(sys_tz, tz.timezone) != 0)
93 nd_log(NDLS_DAEMON, NDLP_NOTICE,
94 "TIMEZONE: configured '%s' differs from system '%s'",
95 tz.timezone, sys_tz);
96 system_tz_free(&tz);
97 }
98 SYSTEM_TZ tz = system_tz_get();
99 refresh_system_timezone(tz.timezone, true);
100 system_tz_free(&tz);
101 } else {
102 // Auto-detected timezone — re-detect to pick up system changes.
103 char buf[FILENAME_MAX + 1];
104 const char *detected = detect_system_timezone_name(buf, sizeof(buf));
105 if (detected && timezone_name_is_safe_tzdb_path(detected)) {
106 refresh_system_timezone(detected, true);
107 } else {
108 if (detected)
109 // Detected a timezone that failed the safe-path check; skip it.
110 netdata_log_error("TIMEZONE: detected unsafe timezone name '%s', ignoring", detected);
111
112 // Detection failed or was rejected — re-use the stored name with its original tzdb flag.
113 // Validate the stored name before reusing it: a previously persisted unsafe tzdb path
114 // must not reach refresh_system_timezone() and propagate to labels or ACLK.
115 SYSTEM_TZ tz = system_tz_get();
116 bool is_tzdb = system_timezone_is_tzdb_name();
117 if (!is_tzdb || timezone_name_is_safe_tzdb_path(tz.timezone))
118 refresh_system_timezone(tz.timezone, is_tzdb);
119 else
120 netdata_log_error("TIMEZONE: stored unsafe tzdb timezone name '%s', ignoring", tz.timezone ? tz.timezone : "(null)");
121 system_tz_free(&tz);
122 }
123 }
124 last_refresh_ut = now_ut;
125 }
126 }
127
128 void pulse_daemon_do(bool extended) {
129 pulse_daemon_cpu_usage_do(extended);
130 pulse_daemon_uptime_do(extended);
131 pulse_daemon_memory_do(extended);
132 pulse_daemon_timezone_do(extended);
133 }