@cryptotaxi247 / netdata-1 / commits / d78db4090

Windows Plugin Metrics (Thermal and Memory) (#18494)

thiagoftsm committed Sep 12, 2024 at 17:44 UTC d78db40901a258e27e91338aa57e668b7b79267b
6 files changed +277 -11
CMakeLists.txt
+1
@@ -1426,6 +1426,7 @@ set(WINDOWS_PLUGIN_FILES
1426 src/collectors/windows.plugin/perflib-dump.c
1427 src/collectors/windows.plugin/perflib-storage.c
1428 src/collectors/windows.plugin/perflib-processor.c
1429 + src/collectors/windows.plugin/perflib-thermalzone.c
1430 src/collectors/windows.plugin/perflib-objects.c
1431 src/collectors/windows.plugin/perflib-network.c
1432 src/collectors/windows.plugin/perflib-memory.c
src/collectors/all.h
+3
@@ -55,6 +55,7 @@
55 #define NETDATA_CHART_PRIO_SYSTEM_IPC_SHARED_MEM_CALLS 1207
56 #define NETDATA_CHART_PRIO_SYSTEM_PACKETS 7001 // freebsd only
57 #define NETDATA_CHART_PRIO_WINDOWS_THREADS 8001 // Windows only
58 +#define NETDATA_CHART_PRIO_WINDOWS_THERMAL_ZONES 8002 // Windows only
59
60
61 // CPU per core
@@ -76,7 +77,9 @@
77 #define NETDATA_CHART_PRIO_MEM_SYSTEM_COMMITTED 1030
78 #define NETDATA_CHART_PRIO_MEM_SWAP 1035
79 #define NETDATA_CHART_PRIO_MEM_SWAP_CALLS 1037
80 +#define NETDATA_CHART_PRIO_MEM_SWAP_PAGES 1037 // Windows only
81 #define NETDATA_CHART_PRIO_MEM_SWAPIO 1038
82 +#define NETDATA_CHART_PRIO_MEM_SYSTEM_POOL 1039 // Windows only
83 #define NETDATA_CHART_PRIO_MEM_ZSWAP 1036
84 #define NETDATA_CHART_PRIO_MEM_ZSWAPIO 1037
85 #define NETDATA_CHART_PRIO_MEM_ZSWAP_COMPRESS_RATIO 1038
src/collectors/windows.plugin/perflib-memory.c
+155 -1
@@ -7,8 +7,158 @@
7 #define _COMMON_PLUGIN_MODULE_NAME "PerflibMemory"
8 #include "../common-contexts/common-contexts.h"
9
10 +struct swap {
11 + RRDSET *operations;
12 + RRDDIM *rd_op_read;
13 + RRDDIM *rd_op_write;
14 +
15 + RRDSET *pages;
16 + RRDDIM *rd_page_read;
17 + RRDDIM *rd_page_write;
18 +
19 + COUNTER_DATA pageReadsTotal;
20 + COUNTER_DATA pageWritesTotal;
21 + COUNTER_DATA pageInputTotal;
22 + COUNTER_DATA pageOutputTotal;
23 +};
24 +
25 +struct system_pool {
26 + RRDSET *pool;
27 + RRDDIM *rd_paged;
28 + RRDDIM *rd_nonpaged;
29 +
30 + COUNTER_DATA pagedData;
31 + COUNTER_DATA nonPagedData;
32 +};
33 +
34 +struct swap localSwap = { 0 };
35 +struct system_pool localPool = { 0 };
36 +
37 +void initialize_swap_keys(struct swap *p) {
38 + // SWAP Operations
39 + p->pageReadsTotal.key = "Page Reads/sec";
40 + p->pageWritesTotal.key = "Page Writes/s";
41 +
42 + // Swap Pages
43 + p->pageInputTotal.key = "Pages Input/sec";
44 + p->pageOutputTotal.key = "Pages Output/s";
45 +}
46 +
47 +void initialize_pool_keys(struct system_pool *p) {
48 + p->pagedData.key = "Pool Paged Bytes";
49 + p->nonPagedData.key = "Pool Nonpaged Bytes";
50 +}
51 +
52 static void initialize(void) {
11 - ;
53 + initialize_swap_keys(&localSwap);
54 + initialize_pool_keys(&localPool);
55 +}
56 +
57 +static void do_memory_swap(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
58 +{
59 + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageReadsTotal);
60 + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageWritesTotal);
61 + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageInputTotal);
62 + perflibGetObjectCounter(pDataBlock, pObjectType, &localSwap.pageOutputTotal);
63 +
64 + if (!localSwap.operations) {
65 + localSwap.operations = rrdset_create_localhost(
66 + "mem"
67 + , "swap_operations", NULL
68 + , "swap"
69 + , "mem.swap_iops"
70 +
71 + , "Swap Operations"
72 + , "operations/s"
73 + , PLUGIN_WINDOWS_NAME
74 + , "PerflibMemory"
75 + , NETDATA_CHART_PRIO_MEM_SWAPIO
76 + , update_every
77 + , RRDSET_TYPE_STACKED
78 + );
79 +
80 + localSwap.rd_op_read = rrddim_add(localSwap.operations, "read", NULL,
81 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
82 + localSwap.rd_op_write = rrddim_add(localSwap.operations, "write", NULL,
83 + 1, -1, RRD_ALGORITHM_INCREMENTAL);
84 + }
85 +
86 + rrddim_set_by_pointer(localSwap.operations,
87 + localSwap.rd_op_read,
88 + (collected_number)localSwap.pageReadsTotal.current.Data);
89 +
90 + rrddim_set_by_pointer(localSwap.operations,
91 + localSwap.rd_op_write,
92 + (collected_number)localSwap.pageWritesTotal.current.Data);
93 + rrdset_done(localSwap.operations);
94 +
95 + if (!localSwap.pages) {
96 + localSwap.pages = rrdset_create_localhost(
97 + "mem"
98 + , "swap_pages", NULL
99 + , "swap"
100 + , "mem.swap_pages_io"
101 +
102 + , "Swap Pages"
103 + , "pages/s"
104 + , PLUGIN_WINDOWS_NAME
105 + , "PerflibMemory"
106 + , NETDATA_CHART_PRIO_MEM_SWAP_PAGES
107 + , update_every
108 + , RRDSET_TYPE_STACKED
109 + );
110 +
111 + localSwap.rd_page_read = rrddim_add(localSwap.pages, "read", NULL,
112 + 1, 1, RRD_ALGORITHM_INCREMENTAL);
113 + localSwap.rd_page_write = rrddim_add(localSwap.pages, "write", NULL,
114 + 1, -1, RRD_ALGORITHM_INCREMENTAL);
115 + }
116 +
117 + rrddim_set_by_pointer(localSwap.pages,
118 + localSwap.rd_page_read,
119 + (collected_number)localSwap.pageInputTotal.current.Data);
120 +
121 + rrddim_set_by_pointer(localSwap.pages,
122 + localSwap.rd_page_write,
123 + (collected_number)localSwap.pageOutputTotal.current.Data);
124 + rrdset_done(localSwap.pages);
125 +}
126 +
127 +static void do_memory_system_pool(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, int update_every)
128 +{
129 + perflibGetObjectCounter(pDataBlock, pObjectType, &localPool.nonPagedData);
130 + perflibGetObjectCounter(pDataBlock, pObjectType, &localPool.pagedData);
131 +
132 + if (!localPool.pool) {
133 + localPool.pool = rrdset_create_localhost(
134 + "mem"
135 + , "system_pool", NULL
136 + , "mem"
137 + , "mem.system_pool_size"
138 +
139 + , "System Memory Pool"
140 + , "bytes"
141 + , PLUGIN_WINDOWS_NAME
142 + , "PerflibMemory"
143 + , NETDATA_CHART_PRIO_MEM_SYSTEM_POOL
144 + , update_every
145 + , RRDSET_TYPE_STACKED
146 + );
147 +
148 + localPool.rd_paged = rrddim_add(localPool.pool, "paged", NULL,
149 + 1, 1, RRD_ALGORITHM_ABSOLUTE);
150 + localPool.rd_nonpaged = rrddim_add(localPool.pool, "pool-paged", NULL,
151 + 1, 1, RRD_ALGORITHM_ABSOLUTE);
152 + }
153 +
154 + rrddim_set_by_pointer(localPool.pool,
155 + localPool.rd_paged,
156 + (collected_number)localPool.pagedData.current.Data);
157 +
158 + rrddim_set_by_pointer(localPool.pool,
159 + localPool.rd_nonpaged,
160 + (collected_number)localPool.nonPagedData.current.Data);
161 + rrdset_done(localPool.pool);
162 }
163
164 static bool do_memory(PERF_DATA_BLOCK *pDataBlock, int update_every) {
@@ -41,6 +191,10 @@ static bool do_memory(PERF_DATA_BLOCK *pDataBlock, int update_every) {
191
192 common_mem_available(available_bytes, update_every);
193
194 + do_memory_swap(pDataBlock, pObjectType, update_every);
195 +
196 + do_memory_system_pool(pDataBlock, pObjectType, update_every);
197 +
198 return true;
199 }
200
src/collectors/windows.plugin/perflib-thermalzone.c new
+105
@@ -0,0 +1,105 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#include "windows_plugin.h"
4 +#include "windows-internals.h"
5 +
6 +typedef struct thermal_zone {
7 + RRDSET *st;
8 + RRDDIM *rd;
9 +
10 + COUNTER_DATA thermalZoneTemperature;
11 +};
12 +
13 +static inline void initialize_thermal_zone_keys(struct thermal_zone *p) {
14 + p->thermalZoneTemperature.key = "Temperature";
15 +}
16 +
17 +void dict_thermal_zone_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
18 + struct thermal_zone *p = value;
19 + initialize_thermal_zone_keys(p);
20 +}
21 +
22 +static DICTIONARY *thermal_zones = NULL;
23 +
24 +static void initialize(void) {
25 + thermal_zones = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE |
26 + DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct thermal_zone));
27 +
28 + dictionary_register_insert_callback(thermal_zones, dict_thermal_zone_insert_cb, NULL);
29 +}
30 +
31 +static bool do_thermal_zones(PERF_DATA_BLOCK *pDataBlock, int update_every) {
32 + PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, "Thermal Zone Information");
33 + if(!pObjectType) return false;
34 +
35 + PERF_INSTANCE_DEFINITION *pi = NULL;
36 + for(LONG i = 0; i < pObjectType->NumInstances ; i++) {
37 + pi = perflibForEachInstance(pDataBlock, pObjectType, pi);
38 + if(!pi) break;
39 +
40 + if(!getInstanceName(pDataBlock, pObjectType, pi, windows_shared_buffer, sizeof(windows_shared_buffer)))
41 + strncpyz(windows_shared_buffer, "[unknown]", sizeof(windows_shared_buffer) - 1);
42 +
43 + netdata_fix_chart_name(windows_shared_buffer);
44 + struct thermal_zone *p = dictionary_set(thermal_zones, windows_shared_buffer, NULL, sizeof(*p));
45 +
46 + perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &p->thermalZoneTemperature);
47 +
48 + // https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/design-guide
49 + if(!p->st) {
50 + char id[RRD_ID_LENGTH_MAX + 1];
51 + snprintfz(id, RRD_ID_LENGTH_MAX, "thermalzone_%s_temperature", windows_shared_buffer);
52 + p->st = rrdset_create_localhost(
53 + "system"
54 + , id, NULL
55 + , "thermalzone"
56 + , "system.thermalzone_temperature"
57 + , "Thermal zone temperature"
58 + , "Celsius"
59 + , PLUGIN_WINDOWS_NAME
60 + , "ThermalZone"
61 + , NETDATA_CHART_PRIO_WINDOWS_THERMAL_ZONES
62 + , update_every
63 + , RRDSET_TYPE_LINE
64 + );
65 +
66 + p->rd = rrddim_add(p->st,
67 + id,
68 + "temperature",
69 + 1,
70 + 1,
71 + RRD_ALGORITHM_ABSOLUTE);
72 +
73 + rrdlabels_add(p->st->rrdlabels, "thermalzone", windows_shared_buffer, RRDLABEL_SRC_AUTO);
74 + }
75 +
76 + // Convert to Celsius before to plot
77 + NETDATA_DOUBLE kTemperature = (NETDATA_DOUBLE)p->thermalZoneTemperature.current.Data;
78 + kTemperature -= 273.15;
79 +
80 + rrddim_set_by_pointer(p->st, p->rd, (collected_number)kTemperature);
81 + rrdset_done(p->st);
82 + }
83 +
84 + return true;
85 +}
86 +
87 +int do_PerflibThermalZone(int update_every, usec_t dt __maybe_unused) {
88 + static bool initialized = false;
89 +
90 + if(unlikely(!initialized)) {
91 + initialize();
92 + initialized = true;
93 + }
94 +
95 + DWORD id = RegistryFindIDByName("Thermal Zone Information");
96 + if(id == PERFLIB_REGISTRY_NAME_NOT_FOUND)
97 + return -1;
98 +
99 + PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
100 + if(!pDataBlock) return -1;
101 +
102 + do_thermal_zones(pDataBlock, update_every);
103 +
104 + return 0;
105 +}
src/collectors/windows.plugin/windows_plugin.c
+12 -10
@@ -13,18 +13,20 @@ static struct proc_module {
13 } win_modules[] = {
14
15 // system metrics
16 - {.name = "GetSystemUptime", .dim = "GetSystemUptime", .func = do_GetSystemUptime},
17 - {.name = "GetSystemRAM", .dim = "GetSystemRAM", .func = do_GetSystemRAM},
16 + {.name = "GetSystemUptime", .dim = "GetSystemUptime", .enabled = CONFIG_BOOLEAN_YES, .func = do_GetSystemUptime},
17 + {.name = "GetSystemRAM", .dim = "GetSystemRAM", .enabled = CONFIG_BOOLEAN_YES, .func = do_GetSystemRAM},
18
19 // the same is provided by PerflibProcessor, with more detailed analysis
20 - //{.name = "GetSystemCPU", .dim = "GetSystemCPU", .func = do_GetSystemCPU},
20 + //{.name = "GetSystemCPU", .dim = "GetSystemCPU", .enabled = CONFIG_BOOLEAN_YES, .func = do_GetSystemCPU},
21
22 - {.name = "PerflibProcesses", .dim = "PerflibProcesses", .func = do_PerflibProcesses},
23 - {.name = "PerflibProcessor", .dim = "PerflibProcessor", .func = do_PerflibProcessor},
24 - {.name = "PerflibMemory", .dim = "PerflibMemory", .func = do_PerflibMemory},
25 - {.name = "PerflibStorage", .dim = "PerflibStorage", .func = do_PerflibStorage},
26 - {.name = "PerflibNetwork", .dim = "PerflibNetwork", .func = do_PerflibNetwork},
27 - {.name = "PerflibObjects", .dim = "PerflibObjects", .func = do_PerflibObjects},
22 + {.name = "PerflibProcesses", .dim = "PerflibProcesses", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibProcesses},
23 + {.name = "PerflibProcessor", .dim = "PerflibProcessor", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibProcessor},
24 + {.name = "PerflibMemory", .dim = "PerflibMemory", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibMemory},
25 + {.name = "PerflibStorage", .dim = "PerflibStorage", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibStorage},
26 + {.name = "PerflibNetwork", .dim = "PerflibNetwork", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibNetwork},
27 + {.name = "PerflibObjects", .dim = "PerflibObjects", .enabled = CONFIG_BOOLEAN_YES, .func = do_PerflibObjects},
28 +
29 + {.name = "PerflibThermalZone", .dim = "PerflibThermalZone", .enabled = CONFIG_BOOLEAN_NO, .func = do_PerflibThermalZone},
30
31 // the terminator of this array
32 {.name = NULL, .dim = NULL, .func = NULL}
@@ -66,7 +68,7 @@ void *win_plugin_main(void *ptr) {
68 for(i = 0; win_modules[i].name; i++) {
69 struct proc_module *pm = &win_modules[i];
70
69 - pm->enabled = config_get_boolean("plugin:windows", pm->name, CONFIG_BOOLEAN_YES);
71 + pm->enabled = config_get_boolean("plugin:windows", pm->name, pm->enabled);
72 pm->rd = NULL;
73
74 worker_register_job_name(i, win_modules[i].dim);
src/collectors/windows.plugin/windows_plugin.h
+1
@@ -24,6 +24,7 @@ int do_PerflibProcesses(int update_every, usec_t dt);
24 int do_PerflibProcessor(int update_every, usec_t dt);
25 int do_PerflibMemory(int update_every, usec_t dt);
26 int do_PerflibObjects(int update_every, usec_t dt);
27 +int do_PerflibThermalZone(int update_every, usec_t dt);
28
29 #include "perflib.h"
30