sysinfo (WinAPI) (#17857)
thiagoftsm committed
Jun 27, 2024 at 11:58 UTC
a4adc506d39b9b9cd90af87613b31d87cc310974
7 files changed
+422
CMakeLists.txt
+4
@@ -725,6 +725,8 @@ set(LIBNETDATA_FILES
725
src/libnetdata/os/os-freebsd-wrappers.h
726
src/libnetdata/os/os-macos-wrappers.c
727
src/libnetdata/os/os-macos-wrappers.h
728
+ src/libnetdata/os/os-windows-wrappers.c
729
+ src/libnetdata/os/os-windows-wrappers.h
730
src/libnetdata/os/get_system_cpus.c
731
src/libnetdata/os/get_system_cpus.h
732
src/libnetdata/os/tinysleep.c
@@ -841,6 +843,8 @@ set(DAEMON_FILES
843
src/daemon/analytics.h
844
src/daemon/main.c
845
src/daemon/main.h
846
+ src/daemon/win_system-info.c
847
+ src/daemon/win_system-info.h
848
src/daemon/signals.c
849
src/daemon/signals.h
850
src/daemon/service.c
src/daemon/main.c
+8
@@ -7,6 +7,10 @@
7
8
#include "database/engine/page_test.h"
9
10
+#ifdef OS_WINDOWS
11
+#include "win_system-info.h"
12
+#endif
13
+
14
#ifdef ENABLE_SENTRY
15
#include "sentry-native/sentry-native.h"
16
#endif
@@ -1362,6 +1366,7 @@ static inline void coverity_remove_taint(char *s)
1366
}
1367
1368
int get_system_info(struct rrdhost_system_info *system_info) {
1369
+#if !defined(OS_WINDOWS)
1370
char *script;
1371
script = mallocz(sizeof(char) * (strlen(netdata_configured_primary_plugins_dir) + strlen("system-info.sh") + 2));
1372
sprintf(script, "%s/%s", netdata_configured_primary_plugins_dir, "system-info.sh");
@@ -1401,6 +1406,9 @@ int get_system_info(struct rrdhost_system_info *system_info) {
1406
netdata_pclose(fp_child_input, fp_child_output, command_pid);
1407
}
1408
freez(script);
1409
+#else
1410
+ netdata_windows_get_system_info(system_info);
1411
+#endif
1412
return 0;
1413
}
1414
src/daemon/win_system-info.c
new
+310
@@ -0,0 +1,310 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#include "win_system-info.h"
4
+
5
+#ifdef OS_WINDOWS
6
+
7
+// Hardware
8
+static char *netdata_windows_arch(DWORD value)
9
+{
10
+ switch (value) {
11
+ case 9:
12
+ return "x86_64";
13
+ case 5:
14
+ return "ARM";
15
+ case 12:
16
+ return "ARM64";
17
+ case 6:
18
+ return "Intel Intaniun-based";
19
+ case 0:
20
+ return "x86";
21
+ default:
22
+ return NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN;
23
+ }
24
+}
25
+
26
+static DWORD netdata_windows_cpu_frequency(HKEY lKey)
27
+{
28
+ DWORD freq = 0;
29
+ long ret = netdata_registry_get_dword_from_open_key(&freq, lKey, "~MHz");
30
+ if (ret != ERROR_SUCCESS)
31
+ return freq;
32
+
33
+ freq *= 1000000;
34
+ return freq;
35
+}
36
+
37
+static void netdata_windows_cpu_from_system_info(struct rrdhost_system_info *systemInfo)
38
+{
39
+ SYSTEM_INFO sysInfo;
40
+ GetSystemInfo(&sysInfo);
41
+
42
+ char cpuData[256];
43
+ (void)snprintf(cpuData, 255, "%d", sysInfo.dwNumberOfProcessors);
44
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_CPU_LOGICAL_CPU_COUNT", cpuData);
45
+
46
+ char *arch = netdata_windows_arch(sysInfo.wProcessorArchitecture);
47
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_ARCHITECTURE", arch);
48
+
49
+ (void)rrdhost_set_system_info_variable(
50
+ systemInfo, "NETDATA_SYSTEM_VIRTUALIZATION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
51
+
52
+ (void)rrdhost_set_system_info_variable(
53
+ systemInfo, "NETDATA_SYSTEM_VIRT_DETECTION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
54
+
55
+ (void)rrdhost_set_system_info_variable(
56
+ systemInfo, "NETDATA_SYSTEM_CONTAINER", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
57
+
58
+ (void)rrdhost_set_system_info_variable(
59
+ systemInfo, "NETDATA_SYSTEM_CONTAINER_DETECTION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
60
+
61
+}
62
+
63
+static void netdata_windows_cpu_vendor_model(struct rrdhost_system_info *systemInfo,
64
+ HKEY lKey,
65
+ char *variable,
66
+ char *key)
67
+{
68
+ char cpuData[256];
69
+ long ret = netdata_registry_get_string_from_open_key(cpuData, 255, lKey, key);
70
+ (void)rrdhost_set_system_info_variable(systemInfo,
71
+ variable,
72
+ (ret == ERROR_SUCCESS) ? cpuData : NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
73
+}
74
+
75
+static void netdata_windows_cpu_from_registry(struct rrdhost_system_info *systemInfo)
76
+{
77
+ HKEY lKey;
78
+ long ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
79
+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
80
+ 0,
81
+ KEY_READ,
82
+ &lKey);
83
+ if (ret != ERROR_SUCCESS)
84
+ return;
85
+
86
+ ULONGLONG cpuFreq = netdata_windows_cpu_frequency(lKey);
87
+ char cpuData[256];
88
+ if (cpuFreq)
89
+ (void)snprintf(cpuData, 255, "%lu", (unsigned long)cpuFreq);
90
+
91
+ (void)rrdhost_set_system_info_variable(systemInfo,
92
+ "NETDATA_SYSTEM_CPU_FREQ",
93
+ (!cpuFreq) ? NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN : cpuData);
94
+
95
+ netdata_windows_cpu_vendor_model(systemInfo, lKey, "NETDATA_SYSTEM_CPU_VENDOR", "VendorIdentifier");
96
+ netdata_windows_cpu_vendor_model(systemInfo, lKey, "NETDATA_SYSTEM_CPU_MODEL", "ProcessorNameString");
97
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_CPU_DETECTION", NETDATA_WIN_DETECTION_METHOD);
98
+}
99
+
100
+static void netdata_windows_get_cpu(struct rrdhost_system_info *systemInfo)
101
+{
102
+ netdata_windows_cpu_from_system_info(systemInfo);
103
+
104
+ netdata_windows_cpu_from_registry(systemInfo);
105
+}
106
+
107
+static void netdata_windows_get_mem(struct rrdhost_system_info *systemInfo)
108
+{
109
+ ULONGLONG size;
110
+ char memSize[256];
111
+ if (!GetPhysicallyInstalledSystemMemory(&size))
112
+ size = 0;
113
+ else
114
+ (void)snprintf(memSize, 255, "%llu", size);
115
+
116
+ (void)rrdhost_set_system_info_variable(systemInfo,
117
+ "NETDATA_SYSTEM_TOTAL_RAM",
118
+ (!size) ? NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN : memSize);
119
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_RAM_DETECTION", NETDATA_WIN_DETECTION_METHOD);
120
+}
121
+
122
+static ULONGLONG netdata_windows_get_disk_size(char *cVolume)
123
+{
124
+ HANDLE disk = CreateFile(cVolume, GENERIC_READ, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
125
+ if (!disk)
126
+ return 0;
127
+
128
+ GET_LENGTH_INFORMATION length;
129
+ DWORD ret;
130
+
131
+ if (!DeviceIoControl(disk, IOCTL_DISK_GET_LENGTH_INFO, 0, 0, &length, sizeof(length), &ret, 0))
132
+ return 0;
133
+
134
+ CloseHandle(disk);
135
+
136
+ return length.Length.QuadPart;
137
+}
138
+
139
+static void netdata_windows_get_total_disk_size(struct rrdhost_system_info *systemInfo)
140
+{
141
+ ULONGLONG total = 0;
142
+ char cVolume[8];
143
+ snprintf(cVolume, 7, "\\\\.\\C:");
144
+
145
+ DWORD lDrives = GetLogicalDrives();
146
+ if (!lDrives) {
147
+ return;
148
+ }
149
+
150
+ int i;
151
+#define ND_POSSIBLE_VOLUMES 26
152
+ for (i = 0; i < ND_POSSIBLE_VOLUMES; i++) {
153
+ if (!(lDrives & 1 << i))
154
+ continue;
155
+
156
+ cVolume[4] = 'A' + i;
157
+ total += netdata_windows_get_disk_size(cVolume);
158
+ }
159
+
160
+ char diskSize[256];
161
+ (void)snprintf(diskSize, 255, "%llu", total);
162
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_TOTAL_DISK_SIZE", diskSize);
163
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_DISK_DETECTION", NETDATA_WIN_DETECTION_METHOD);
164
+}
165
+
166
+// Host
167
+static DWORD netdata_windows_get_current_build()
168
+{
169
+ HKEY hKey;
170
+ char cBuild[64];
171
+ if (!netdata_registry_get_string(
172
+ cBuild, 63, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuild"))
173
+ return 0;
174
+
175
+ errno = 0;
176
+
177
+ DWORD version = strtol(cBuild, NULL, 10);
178
+ if (errno == ERANGE)
179
+ return 0;
180
+
181
+ return version;
182
+}
183
+
184
+static void netdata_windows_discover_os_version(char *os, size_t length, DWORD build)
185
+{
186
+ char *commonName = {"Windows"};
187
+
188
+ if (IsWindowsServer()) {
189
+ (void)snprintf(os, length, "%s Server", commonName);
190
+ return;
191
+ }
192
+
193
+#define ND_WIN_VER_LENGTH 16
194
+ char version[ND_WIN_VER_LENGTH + 1];
195
+ if (IsWindows10OrGreater()) {
196
+ // https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information
197
+ (void)snprintf(version, ND_WIN_VER_LENGTH, (build < 22000) ? "10" : "11");
198
+ } else if (IsWindows8Point1OrGreater()) {
199
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "8.1");
200
+ } else if (IsWindows8OrGreater()) {
201
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "8");
202
+ } else if (IsWindows7SP1OrGreater()) {
203
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "7 SP1");
204
+ } else if (IsWindows7OrGreater()) {
205
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "7");
206
+ } else if (IsWindowsVistaSP2OrGreater()) {
207
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "Vista SP2");
208
+ } else if (IsWindowsVistaSP1OrGreater()) {
209
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "Vista SP1");
210
+ } else if (IsWindowsVistaOrGreater()) {
211
+ (void)snprintf(version, ND_WIN_VER_LENGTH, "Vista");
212
+ }
213
+ // We are not testing older, because it is not supported anymore by Microsoft
214
+
215
+ (void)snprintf(os, length, "%s %s Client", commonName, version);
216
+}
217
+
218
+static void netdata_windows_os_version(char *out, DWORD length)
219
+{
220
+ if (netdata_registry_get_string(out,
221
+ length,
222
+ HKEY_LOCAL_MACHINE,
223
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
224
+ "ProductName"))
225
+ return;
226
+
227
+ (void)snprintf(out, length, "%s", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
228
+}
229
+
230
+static void netdata_windows_os_kernel_version(char *out, DWORD length, DWORD build)
231
+{
232
+ char version[8];
233
+ if (!netdata_registry_get_string(version,
234
+ 7,
235
+ HKEY_LOCAL_MACHINE,
236
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
237
+ "CurrentVersion"))
238
+ version[0] = '\0';
239
+
240
+ (void)snprintf(out, length, "%s (build: %u)", version, build);
241
+}
242
+
243
+static void netdata_windows_host(struct rrdhost_system_info *systemInfo)
244
+{
245
+ char osVersion[4096];
246
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_HOST_OS_NAME", "Microsoft Windows");
247
+
248
+ DWORD build = netdata_windows_get_current_build();
249
+
250
+ netdata_windows_discover_os_version(osVersion, 4095, build);
251
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_HOST_OS_ID", osVersion);
252
+
253
+ (void)rrdhost_set_system_info_variable(
254
+ systemInfo, "NETDATA_HOST_OS_ID_LIKE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
255
+
256
+ netdata_windows_os_version(osVersion, 4095);
257
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_HOST_OS_VERSION", osVersion);
258
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_HOST_OS_VERSION_ID", osVersion);
259
+
260
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_HOST_OS_DETECTION", NETDATA_WIN_DETECTION_METHOD);
261
+
262
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_KERNEL_NAME", "Windows");
263
+
264
+ netdata_windows_os_kernel_version(osVersion, 4095, build);
265
+ (void)rrdhost_set_system_info_variable(systemInfo, "NETDATA_SYSTEM_KERNEL_VERSION", osVersion);
266
+
267
+ (void)rrdhost_set_system_info_variable(
268
+ systemInfo, "NETDATA_HOST_IS_K8S_NODE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_FALSE);
269
+}
270
+
271
+// Cloud
272
+static void netdata_windows_cloud(struct rrdhost_system_info *systemInfo)
273
+{
274
+ (void)rrdhost_set_system_info_variable(
275
+ systemInfo, "NETDATA_INSTANCE_CLOUD_TYPE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
276
+ (void)rrdhost_set_system_info_variable(
277
+ systemInfo, "NETDATA_INSTANCE_CLOUD_INSTANCE_TYPE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
278
+ (void)rrdhost_set_system_info_variable(
279
+ systemInfo, "NETDATA_INSTANCE_CLOUD_INSTANCE_REGION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN);
280
+}
281
+
282
+// Container
283
+static void netdata_windows_container(struct rrdhost_system_info *systemInfo)
284
+{
285
+ (void)rrdhost_set_system_info_variable(
286
+ systemInfo, "NETDATA_CONTAINER_OS_NAME", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
287
+ (void)rrdhost_set_system_info_variable(
288
+ systemInfo, "NETDATA_CONTAINER_OS_ID", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
289
+ (void)rrdhost_set_system_info_variable(
290
+ systemInfo, "NETDATA_CONTAINER_OS_ID_LIKE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
291
+ (void)rrdhost_set_system_info_variable(
292
+ systemInfo, "NETDATA_CONTAINER_OS_VERSION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
293
+ (void)rrdhost_set_system_info_variable(
294
+ systemInfo, "NETDATA_CONTAINER_OS_VERSION_ID", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
295
+ (void)rrdhost_set_system_info_variable(
296
+ systemInfo, "NETDATA_CONTAINER_OS_DETECTION", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE);
297
+ (void)rrdhost_set_system_info_variable(
298
+ systemInfo, "NETDATA_CONTAINER_IS_OFFICIAL_IMAGE", NETDATA_DEFAULT_SYSTEM_INFO_VALUE_FALSE);
299
+}
300
+
301
+void netdata_windows_get_system_info(struct rrdhost_system_info *systemInfo)
302
+{
303
+ netdata_windows_cloud(systemInfo);
304
+ netdata_windows_container(systemInfo);
305
+ netdata_windows_host(systemInfo);
306
+ netdata_windows_get_cpu(systemInfo);
307
+ netdata_windows_get_mem(systemInfo);
308
+ netdata_windows_get_total_disk_size(systemInfo);
309
+}
310
+#endif
src/daemon/win_system-info.h
new
+20
@@ -0,0 +1,20 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#ifndef _NETDATA_WIN_SYSTEM_INFO_H_
4
+#define _NETDATA_WIN_SYSTEM_INFO_H_
5
+
6
+// the netdata database
7
+#include "database/rrd.h"
8
+
9
+#define NETDATA_DEFAULT_SYSTEM_INFO_VALUE_UNKNOWN "unknown"
10
+#define NETDATA_DEFAULT_SYSTEM_INFO_VALUE_NONE "none"
11
+#define NETDATA_DEFAULT_SYSTEM_INFO_VALUE_FALSE "false"
12
+
13
+#ifdef OS_WINDOWS
14
+#include "windows.h"
15
+#include "versionhelpers.h"
16
+
17
+void netdata_windows_get_system_info(struct rrdhost_system_info *system_info);
18
+#endif
19
+
20
+#endif // _NETDATA_WIN_SYSTEM_INFO_H_
src/libnetdata/os/os-windows-wrappers.c
new
+61
@@ -0,0 +1,61 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#include "../libnetdata.h"
4
+
5
+#if defined(OS_WINDOWS)
6
+#include <windows.h>
7
+
8
+long netdata_registry_get_dword_from_open_key(unsigned int *out, void *lKey, char *name)
9
+{
10
+ DWORD length = 260;
11
+ return RegQueryValueEx(lKey, name, NULL, NULL, (LPBYTE) out, &length);
12
+}
13
+
14
+bool netdata_registry_get_dword(unsigned int *out, void *hKey, char *subKey, char *name)
15
+{
16
+ HKEY lKey;
17
+ bool status = true;
18
+ long ret = RegOpenKeyEx(hKey,
19
+ subKey,
20
+ 0,
21
+ KEY_READ,
22
+ &lKey);
23
+ if (ret != ERROR_SUCCESS)
24
+ return false;
25
+
26
+ ret = netdata_registry_get_dword_from_open_key(out, lKey, name);
27
+ if (ret != ERROR_SUCCESS)
28
+ status = false;
29
+
30
+ RegCloseKey(lKey);
31
+
32
+ return status;
33
+}
34
+
35
+long netdata_registry_get_string_from_open_key(char *out, unsigned int length, void *lKey, char *name)
36
+{
37
+ return RegQueryValueEx(lKey, name, NULL, NULL, (LPBYTE) out, &length);
38
+}
39
+
40
+bool netdata_registry_get_string(char *out, unsigned int length, void *hKey, char *subKey, char *name)
41
+{
42
+ HKEY lKey;
43
+ bool status = true;
44
+ long ret = RegOpenKeyEx(hKey,
45
+ subKey,
46
+ 0,
47
+ KEY_READ,
48
+ &lKey);
49
+ if (ret != ERROR_SUCCESS)
50
+ return false;
51
+
52
+ ret = netdata_registry_get_string_from_open_key(out, length, lKey, name);
53
+ if (ret != ERROR_SUCCESS)
54
+ status = false;
55
+
56
+ RegCloseKey(lKey);
57
+
58
+ return status;
59
+}
60
+
61
+#endif
src/libnetdata/os/os-windows-wrappers.h
new
+18
@@ -0,0 +1,18 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#ifndef NETDATA_OS_WINDOWS_WRAPPERS_H
4
+#define NETDATA_OS_WINDOWS_WRAPPERS_H
5
+
6
+#include "../libnetdata.h"
7
+
8
+#if defined(OS_WINDOWS)
9
+#define NETDATA_WIN_DETECTION_METHOD "Windows API/Registry"
10
+
11
+long netdata_registry_get_dword_from_open_key(unsigned int *out, void *lKey, char *name);
12
+bool netdata_registry_get_dword(unsigned int *out, void *hKey, char *subKey, char *name);
13
+
14
+long netdata_registry_get_string_from_open_key(char *out, unsigned int length, void *lKey, char *name);
15
+bool netdata_registry_get_string(char *out, unsigned int length, void *hKey, char *subKey, char *name);
16
+
17
+#endif // OS_WINDOWS
18
+#endif //NETDATA_OS_WINDOWS_WRAPPERS_H
src/libnetdata/os/os.h
+1
@@ -20,6 +20,7 @@
20
#include "setenv.h"
21
#include "os-freebsd-wrappers.h"
22
#include "os-macos-wrappers.h"
23
+#include "os-windows-wrappers.h"
24
25
// =====================================================================================================================
26
// common defs for Apple/FreeBSD/Linux