feat(proc/numa): add numa node mem activity (#18855)
Ilya Mashchenko committed
Oct 23, 2024 at 16:02 UTC
5d1999b5269e9ab9eec64202383a4ad15edaf772
2 files changed
+83
-48
src/collectors/all.h
+1
@@ -114,6 +114,7 @@
114
#define NETDATA_CHART_PRIO_MEM_NUMA 1400
115
#define NETDATA_CHART_PRIO_MEM_NUMA_NODES_NUMASTAT 1410
116
#define NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO 1411
117
+#define NETDATA_CHART_PRIO_MEM_NUMA_NODES_ACTIVITY 1412
118
#define NETDATA_CHART_PRIO_MEM_PAGEFRAG 1450
119
#define NETDATA_CHART_PRIO_MEM_HW 1500
120
#define NETDATA_CHART_PRIO_MEM_HW_ECC_CE 1550
src/collectors/proc.plugin/sys_devices_system_node.c
+82
-48
@@ -14,7 +14,8 @@ struct node {
14
struct {
15
char *filename;
16
procfile *ff;
17
- RRDSET *st;
17
+ RRDSET *st_mem_usage;
18
+ RRDSET *st_mem_activity;
19
} meminfo;
20
21
struct node *next;
@@ -141,22 +142,22 @@ static void do_muma_numastat(struct node *m, int update_every) {
142
continue;
143
}
144
144
- char *name = procfile_lineword(m->numastat.ff, l, 0);
145
+ char *name = procfile_lineword(m->numastat.ff, l, 0);
146
char *value = procfile_lineword(m->numastat.ff, l, 1);
147
148
if (unlikely(!name || !*name || !value || !*value))
149
continue;
150
151
uint32_t hash = simple_hash(name);
151
- if(likely(
152
- (hash == hash_numa_hit && !strcmp(name, "numa_hit"))
153
- || (hash == hash_numa_miss && !strcmp(name, "numa_miss"))
154
- || (hash == hash_local_node && !strcmp(name, "local_node"))
155
- || (hash == hash_numa_foreign && !strcmp(name, "numa_foreign"))
156
- || (hash == hash_interleave_hit && !strcmp(name, "interleave_hit"))
157
- || (hash == hash_other_node && !strcmp(name, "other_node"))
158
- ))
152
+
153
+ if ((hash == hash_numa_hit && !strcmp(name, "numa_hit")) ||
154
+ (hash == hash_numa_miss && !strcmp(name, "numa_miss")) ||
155
+ (hash == hash_local_node && !strcmp(name, "local_node")) ||
156
+ (hash == hash_numa_foreign && !strcmp(name, "numa_foreign")) ||
157
+ (hash == hash_interleave_hit && !strcmp(name, "interleave_hit")) ||
158
+ (hash == hash_other_node && !strcmp(name, "other_node"))) {
159
rrddim_set(m->numastat.st, name, (collected_number)str2kernel_uint_t(value));
160
+ }
161
}
162
163
rrdset_done(m->numastat.st);
@@ -164,73 +165,106 @@ static void do_muma_numastat(struct node *m, int update_every) {
165
}
166
167
static void do_numa_meminfo(struct node *m, int update_every) {
167
- static uint32_t hash_MemFree = 0, hash_MemUsed = 0;
168
+ static uint32_t hash_MemFree = 0, hash_MemUsed = 0, hash_ActiveAnon = 0, hash_InactiveAnon = 0, hash_ActiveFile = 0,
169
+ hash_InactiveFile = 0;
170
static bool initialized = false;
169
-
170
- if(unlikely(!initialized)) {
171
+
172
+ if (unlikely(!initialized)) {
173
initialized = true;
174
hash_MemFree = simple_hash("MemFree");
175
hash_MemUsed = simple_hash("MemUsed");
176
+ hash_ActiveAnon = simple_hash("Active(anon)");
177
+ hash_InactiveAnon = simple_hash("Inactive(anon)");
178
+ hash_ActiveFile = simple_hash("Active(file)");
179
+ hash_InactiveFile = simple_hash("Inactive(file)");
180
}
181
182
if (m->meminfo.filename) {
177
- if(unlikely(!m->meminfo.ff)) {
183
+ if (unlikely(!m->meminfo.ff)) {
184
m->meminfo.ff = procfile_open(m->meminfo.filename, " :", PROCFILE_FLAG_DEFAULT);
179
- if(unlikely(!m->meminfo.ff))
185
+ if (unlikely(!m->meminfo.ff))
186
return;
187
}
188
189
m->meminfo.ff = procfile_readall(m->meminfo.ff);
184
- if(unlikely(!m->meminfo.ff || procfile_lines(m->meminfo.ff) < 1 || procfile_linewords(m->meminfo.ff, 0) < 1))
190
+ if (unlikely(!m->meminfo.ff || procfile_lines(m->meminfo.ff) < 1 || procfile_linewords(m->meminfo.ff, 0) < 1))
191
return;
192
187
- if(unlikely(!m->meminfo.st)) {
188
- m->meminfo.st = rrdset_create_localhost(
189
- "numa_node_mem_usage"
190
- , m->name
191
- , NULL
192
- , "numa"
193
- , "mem.numa_node_mem_usage"
194
- , "NUMA Node Memory Usage"
195
- , "bytes"
196
- , PLUGIN_PROC_NAME
197
- , "/sys/devices/system/node"
198
- , NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO
199
- , update_every
200
- , RRDSET_TYPE_STACKED
201
- );
202
-
203
- rrdlabels_add(m->meminfo.st->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
204
-
205
- rrddim_add(m->meminfo.st, "MemFree", "free", 1, 1, RRD_ALGORITHM_ABSOLUTE);
206
- rrddim_add(m->meminfo.st, "MemUsed", "used", 1, 1, RRD_ALGORITHM_ABSOLUTE);
193
+ if (unlikely(!m->meminfo.st_mem_usage)) {
194
+ m->meminfo.st_mem_usage = rrdset_create_localhost(
195
+ "numa_node_mem_usage",
196
+ m->name,
197
+ NULL,
198
+ "numa",
199
+ "mem.numa_node_mem_usage",
200
+ "NUMA Node Memory Usage",
201
+ "bytes",
202
+ PLUGIN_PROC_NAME,
203
+ "/sys/devices/system/node",
204
+ NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO,
205
+ update_every,
206
+ RRDSET_TYPE_STACKED);
207
+
208
+ rrdlabels_add(m->meminfo.st_mem_usage->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
209
+
210
+ rrddim_add(m->meminfo.st_mem_usage, "MemFree", "free", 1, 1, RRD_ALGORITHM_ABSOLUTE);
211
+ rrddim_add(m->meminfo.st_mem_usage, "MemUsed", "used", 1, 1, RRD_ALGORITHM_ABSOLUTE);
212
+ }
213
+ if (unlikely(!m->meminfo.st_mem_activity)) {
214
+ m->meminfo.st_mem_activity = rrdset_create_localhost(
215
+ "numa_node_mem_activity",
216
+ m->name,
217
+ NULL,
218
+ "numa",
219
+ "mem.numa_node_mem_activity",
220
+ "NUMA Node Memory Activity",
221
+ "bytes",
222
+ PLUGIN_PROC_NAME,
223
+ "/sys/devices/system/node",
224
+ NETDATA_CHART_PRIO_MEM_NUMA_NODES_ACTIVITY,
225
+ update_every,
226
+ RRDSET_TYPE_STACKED);
227
+
228
+ rrdlabels_add(m->meminfo.st_mem_activity->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
229
+
230
+ rrddim_add(m->meminfo.st_mem_activity, "Active(anon)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
231
+ rrddim_add(m->meminfo.st_mem_activity, "Inactive(anon)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
232
+ rrddim_add(m->meminfo.st_mem_activity, "Active(file)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
233
+ rrddim_add(m->meminfo.st_mem_activity, "Inactive(file)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
234
}
235
236
size_t lines = procfile_lines(m->meminfo.ff), l;
210
- for(l = 0; l < lines; l++) {
237
+ for (l = 0; l < lines; l++) {
238
size_t words = procfile_linewords(m->meminfo.ff, l);
239
213
- if(unlikely(words < 4)) {
214
- if(unlikely(words))
215
- collector_error("Cannot read %s line %zu. Expected 4 params, read %zu.", m->meminfo.filename, l, words);
240
+ if (unlikely(words < 4)) {
241
+ if (words)
242
+ collector_error(
243
+ "Cannot read %s line %zu. Expected 4 params, read %zu.", m->meminfo.filename, l, words);
244
continue;
245
}
246
219
- char *name = procfile_lineword(m->meminfo.ff, l, 2);
247
+ char *name = procfile_lineword(m->meminfo.ff, l, 2);
248
char *value = procfile_lineword(m->meminfo.ff, l, 3);
249
250
if (unlikely(!name || !*name || !value || !*value))
251
continue;
252
253
uint32_t hash = simple_hash(name);
226
- if(likely(
227
- (hash == hash_MemFree && !strcmp(name, "MemFree"))
228
- || (hash == hash_MemUsed && !strcmp(name, "MemUsed"))
229
- ))
230
- rrddim_set(m->meminfo.st, name, (collected_number)str2kernel_uint_t(value) * 1024);
231
- }
254
233
- rrdset_done(m->meminfo.st);
255
+ if ((hash == hash_MemFree && !strcmp(name, "MemFree")) ||
256
+ (hash == hash_MemUsed && !strcmp(name, "MemUsed"))) {
257
+ rrddim_set(m->meminfo.st_mem_usage, name, (collected_number)str2kernel_uint_t(value) * 1024);
258
+ } else if (
259
+ (hash == hash_ActiveAnon && !strcmp(name, "Active(anon)")) ||
260
+ (hash == hash_InactiveAnon && !strcmp(name, "Inactive(anon)")) ||
261
+ (hash == hash_ActiveFile && !strcmp(name, "Active(file)")) ||
262
+ (hash == hash_InactiveFile && !strcmp(name, "Inactive(file)"))) {
263
+ rrddim_set(m->meminfo.st_mem_activity, name, (collected_number)str2kernel_uint_t(value) * 1024);
264
+ }
265
+ }
266
+ rrdset_done(m->meminfo.st_mem_usage);
267
+ rrdset_done(m->meminfo.st_mem_activity);
268
}
269
}
270