@cryptotaxi247 / netdata-1 / commits / d09164949

numa basic meminfo (#18822)

* numa basic meminfo * collected values are kb

Costa Tsaousis committed Oct 19, 2024 at 16:12 UTC d09164949b34f5648cbf697299aedee1a780923a
2 files changed +196 -92
src/collectors/all.h
+2 -1
@@ -112,7 +112,8 @@
112 #define NETDATA_CHART_PRIO_MEM_KSM_COW 1303
113 #define NETDATA_CHART_PRIO_MEM_BALLOON 1350
114 #define NETDATA_CHART_PRIO_MEM_NUMA 1400
115 -#define NETDATA_CHART_PRIO_MEM_NUMA_NODES 1410
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_PAGEFRAG 1450
118 #define NETDATA_CHART_PRIO_MEM_HW 1500
119 #define NETDATA_CHART_PRIO_MEM_HW_ECC_CE 1550
src/collectors/proc.plugin/sys_devices_system_node.c
+194 -91
@@ -4,12 +4,23 @@
4
5 struct node {
6 char *name;
7 - char *numastat_filename;
8 - procfile *numastat_ff;
9 - RRDSET *numastat_st;
7 +
8 + struct {
9 + char *filename;
10 + procfile *ff;
11 + RRDSET *st;
12 + } numastat;
13 +
14 + struct {
15 + char *filename;
16 + procfile *ff;
17 + RRDSET *st;
18 + } meminfo;
19 +
20 struct node *next;
21 };
22 static struct node *numa_root = NULL;
23 +static int numa_node_count = 0;
24
25 static int find_all_nodes() {
26 int numa_node_count = 0;
@@ -47,8 +58,16 @@ static int find_all_nodes() {
58 freez(m);
59 continue;
60 }
61 + m->numastat.filename = strdupz(name);
62
51 - m->numastat_filename = strdupz(name);
63 + snprintfz(name, FILENAME_MAX, "%s/%s/meminfo", dirname, de->d_name);
64 + if(stat(name, &st) == -1) {
65 + freez(m->numastat.filename);
66 + freez(m->name);
67 + freez(m);
68 + continue;
69 + }
70 + m->meminfo.filename = strdupz(name);
71
72 m->next = numa_root;
73 numa_root = m;
@@ -59,22 +78,12 @@ static int find_all_nodes() {
78 return numa_node_count;
79 }
80
62 -int do_proc_sys_devices_system_node(int update_every, usec_t dt) {
63 - (void)dt;
64 -
81 +static void do_muma_numastat(struct node *m, int update_every) {
82 static uint32_t hash_local_node = 0, hash_numa_foreign = 0, hash_interleave_hit = 0, hash_other_node = 0, hash_numa_hit = 0, hash_numa_miss = 0;
66 - static int do_numastat = -1, numa_node_count = 0;
67 - struct node *m;
68 -
69 - if(unlikely(numa_root == NULL)) {
70 - numa_node_count = find_all_nodes();
71 - if(unlikely(numa_root == NULL))
72 - return 1;
73 - }
74 -
75 - if(unlikely(do_numastat == -1)) {
76 - do_numastat = config_get_boolean_ondemand("plugin:proc:/sys/devices/system/node", "enable per-node numa metrics", CONFIG_BOOLEAN_AUTO);
83 + static bool initialized = false;
84
85 + if(unlikely(!initialized)) {
86 + initialized = true;
87 hash_local_node = simple_hash("local_node");
88 hash_numa_foreign = simple_hash("numa_foreign");
89 hash_interleave_hit = simple_hash("interleave_hit");
@@ -83,82 +92,176 @@ int do_proc_sys_devices_system_node(int update_every, usec_t dt) {
92 hash_numa_miss = simple_hash("numa_miss");
93 }
94
86 - if (do_numastat == CONFIG_BOOLEAN_YES || (do_numastat == CONFIG_BOOLEAN_AUTO && numa_node_count >= 2)) {
87 - for(m = numa_root; m; m = m->next) {
88 - if(m->numastat_filename) {
89 -
90 - if(unlikely(!m->numastat_ff)) {
91 - m->numastat_ff = procfile_open(m->numastat_filename, " ", PROCFILE_FLAG_DEFAULT);
92 -
93 - if(unlikely(!m->numastat_ff))
94 - continue;
95 - }
96 -
97 - m->numastat_ff = procfile_readall(m->numastat_ff);
98 - if(unlikely(!m->numastat_ff || procfile_lines(m->numastat_ff) < 1 || procfile_linewords(m->numastat_ff, 0) < 1))
99 - continue;
100 -
101 - if(unlikely(!m->numastat_st)) {
102 - m->numastat_st = rrdset_create_localhost(
103 - "mem"
104 - , m->name
105 - , NULL
106 - , "numa"
107 - , "mem.numa_nodes"
108 - , "NUMA events"
109 - , "events/s"
110 - , PLUGIN_PROC_NAME
111 - , "/sys/devices/system/node"
112 - , NETDATA_CHART_PRIO_MEM_NUMA_NODES
113 - , update_every
114 - , RRDSET_TYPE_LINE
115 - );
116 -
117 - rrdlabels_add(m->numastat_st->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
118 -
119 - rrdset_flag_set(m->numastat_st, RRDSET_FLAG_DETAIL);
120 -
121 - rrddim_add(m->numastat_st, "numa_hit", "hit", 1, 1, RRD_ALGORITHM_INCREMENTAL);
122 - rrddim_add(m->numastat_st, "numa_miss", "miss", 1, 1, RRD_ALGORITHM_INCREMENTAL);
123 - rrddim_add(m->numastat_st, "local_node", "local", 1, 1, RRD_ALGORITHM_INCREMENTAL);
124 - rrddim_add(m->numastat_st, "numa_foreign", "foreign", 1, 1, RRD_ALGORITHM_INCREMENTAL);
125 - rrddim_add(m->numastat_st, "interleave_hit", "interleave", 1, 1, RRD_ALGORITHM_INCREMENTAL);
126 - rrddim_add(m->numastat_st, "other_node", "other", 1, 1, RRD_ALGORITHM_INCREMENTAL);
127 -
128 - }
129 -
130 - size_t lines = procfile_lines(m->numastat_ff), l;
131 - for(l = 0; l < lines; l++) {
132 - size_t words = procfile_linewords(m->numastat_ff, l);
133 -
134 - if(unlikely(words < 2)) {
135 - if(unlikely(words))
136 - collector_error("Cannot read %s numastat line %zu. Expected 2 params, read %zu.", m->name, l, words);
137 - continue;
138 - }
139 -
140 - char *name = procfile_lineword(m->numastat_ff, l, 0);
141 - char *value = procfile_lineword(m->numastat_ff, l, 1);
142 -
143 - if (unlikely(!name || !*name || !value || !*value))
144 - continue;
145 -
146 - uint32_t hash = simple_hash(name);
147 - if(likely(
148 - (hash == hash_numa_hit && !strcmp(name, "numa_hit"))
149 - || (hash == hash_numa_miss && !strcmp(name, "numa_miss"))
150 - || (hash == hash_local_node && !strcmp(name, "local_node"))
151 - || (hash == hash_numa_foreign && !strcmp(name, "numa_foreign"))
152 - || (hash == hash_interleave_hit && !strcmp(name, "interleave_hit"))
153 - || (hash == hash_other_node && !strcmp(name, "other_node"))
154 - ))
155 - rrddim_set(m->numastat_st, name, (collected_number)str2kernel_uint_t(value));
156 - }
95 + if (m->numastat.filename) {
96 + if(unlikely(!m->numastat.ff)) {
97 + m->numastat.ff = procfile_open(m->numastat.filename, " ", PROCFILE_FLAG_DEFAULT);
98
158 - rrdset_done(m->numastat_st);
99 + if(unlikely(!m->numastat.ff))
100 + return;
101 + }
102 +
103 + m->numastat.ff = procfile_readall(m->numastat.ff);
104 + if(unlikely(!m->numastat.ff || procfile_lines(m->numastat.ff) < 1 || procfile_linewords(m->numastat.ff, 0) < 1))
105 + return;
106 +
107 + if(unlikely(!m->numastat.st)) {
108 + m->numastat.st = rrdset_create_localhost(
109 + "numa_node_stat"
110 + , m->name
111 + , NULL
112 + , "numa"
113 + , "mem.numa_node_stat"
114 + , "NUMA Node Memory Allocation Events"
115 + , "events/s"
116 + , PLUGIN_PROC_NAME
117 + , "/sys/devices/system/node"
118 + , NETDATA_CHART_PRIO_MEM_NUMA_NODES_NUMASTAT
119 + , update_every
120 + , RRDSET_TYPE_LINE
121 + );
122 +
123 + rrdlabels_add(m->numastat.st->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
124 +
125 + rrdset_flag_set(m->numastat.st, RRDSET_FLAG_DETAIL);
126 +
127 + rrddim_add(m->numastat.st, "numa_hit", "hit", 1, 1, RRD_ALGORITHM_INCREMENTAL);
128 + rrddim_add(m->numastat.st, "numa_miss", "miss", 1, 1, RRD_ALGORITHM_INCREMENTAL);
129 + rrddim_add(m->numastat.st, "local_node", "local", 1, 1, RRD_ALGORITHM_INCREMENTAL);
130 + rrddim_add(m->numastat.st, "numa_foreign", "foreign", 1, 1, RRD_ALGORITHM_INCREMENTAL);
131 + rrddim_add(m->numastat.st, "interleave_hit", "interleave", 1, 1, RRD_ALGORITHM_INCREMENTAL);
132 + rrddim_add(m->numastat.st, "other_node", "other", 1, 1, RRD_ALGORITHM_INCREMENTAL);
133 +
134 + }
135 +
136 + size_t lines = procfile_lines(m->numastat.ff), l;
137 + for(l = 0; l < lines; l++) {
138 + size_t words = procfile_linewords(m->numastat.ff, l);
139 +
140 + if(unlikely(words < 2)) {
141 + if(unlikely(words))
142 + collector_error("Cannot read %s line %zu. Expected 2 params, read %zu.", m->numastat.filename, l, words);
143 + continue;
144 }
145 +
146 + char *name = procfile_lineword(m->numastat.ff, l, 0);
147 + char *value = procfile_lineword(m->numastat.ff, l, 1);
148 +
149 + if (unlikely(!name || !*name || !value || !*value))
150 + continue;
151 +
152 + uint32_t hash = simple_hash(name);
153 + if(likely(
154 + (hash == hash_numa_hit && !strcmp(name, "numa_hit"))
155 + || (hash == hash_numa_miss && !strcmp(name, "numa_miss"))
156 + || (hash == hash_local_node && !strcmp(name, "local_node"))
157 + || (hash == hash_numa_foreign && !strcmp(name, "numa_foreign"))
158 + || (hash == hash_interleave_hit && !strcmp(name, "interleave_hit"))
159 + || (hash == hash_other_node && !strcmp(name, "other_node"))
160 + ))
161 + rrddim_set(m->numastat.st, name, (collected_number)str2kernel_uint_t(value));
162 }
163 +
164 + rrdset_done(m->numastat.st);
165 + }
166 +}
167 +
168 +static void do_numa_meminfo(struct node *m, int update_every) {
169 + static uint32_t hash_MemFree = 0, hash_MemUsed = 0;
170 + static bool initialized = false;
171 +
172 + if(unlikely(!initialized)) {
173 + initialized = true;
174 + hash_MemFree = simple_hash("MemFree");
175 + hash_MemUsed = simple_hash("MemUsed");
176 + }
177 +
178 + if (m->meminfo.filename) {
179 + if(unlikely(!m->meminfo.ff)) {
180 + m->meminfo.ff = procfile_open(m->meminfo.filename, " :", PROCFILE_FLAG_DEFAULT);
181 + if(unlikely(!m->meminfo.ff))
182 + return;
183 + }
184 +
185 + m->meminfo.ff = procfile_readall(m->meminfo.ff);
186 + if(unlikely(!m->meminfo.ff || procfile_lines(m->meminfo.ff) < 1 || procfile_linewords(m->meminfo.ff, 0) < 1))
187 + return;
188 +
189 + if(unlikely(!m->meminfo.st)) {
190 + m->meminfo.st = rrdset_create_localhost(
191 + "numa_node_mem_usage"
192 + , m->name
193 + , NULL
194 + , "numa"
195 + , "mem.numa_node_mem_usage"
196 + , "NUMA Node Memory Usage"
197 + , "bytes"
198 + , PLUGIN_PROC_NAME
199 + , "/sys/devices/system/node"
200 + , NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO
201 + , update_every
202 + , RRDSET_TYPE_STACKED
203 + );
204 +
205 + rrdlabels_add(m->meminfo.st->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
206 +
207 + rrdset_flag_set(m->meminfo.st, RRDSET_FLAG_DETAIL);
208 +
209 + rrddim_add(m->meminfo.st, "MemFree", "free", 1, 1, RRD_ALGORITHM_ABSOLUTE);
210 + rrddim_add(m->meminfo.st, "MemUsed", "used", 1, 1, RRD_ALGORITHM_ABSOLUTE);
211 + }
212 +
213 + size_t lines = procfile_lines(m->meminfo.ff), l;
214 + for(l = 0; l < lines; l++) {
215 + size_t words = procfile_linewords(m->meminfo.ff, l);
216 +
217 + if(unlikely(words < 4)) {
218 + if(unlikely(words))
219 + collector_error("Cannot read %s line %zu. Expected 4 params, read %zu.", m->meminfo.filename, l, words);
220 + continue;
221 + }
222 +
223 + char *name = procfile_lineword(m->meminfo.ff, l, 2);
224 + char *value = procfile_lineword(m->meminfo.ff, l, 3);
225 +
226 + if (unlikely(!name || !*name || !value || !*value))
227 + continue;
228 +
229 + uint32_t hash = simple_hash(name);
230 + if(likely(
231 + (hash == hash_MemFree && !strcmp(name, "MemFree"))
232 + || (hash == hash_MemUsed && !strcmp(name, "MemUsed"))
233 + ))
234 + rrddim_set(m->meminfo.st, name, (collected_number)str2kernel_uint_t(value) * 1024);
235 + }
236 +
237 + rrdset_done(m->meminfo.st);
238 + }
239 +}
240 +
241 +int do_proc_sys_devices_system_node(int update_every, usec_t dt) {
242 + (void)dt;
243 + struct node *m;
244 +
245 + static int do_numastat = -1;
246 +
247 + if(unlikely(do_numastat == -1)) {
248 + do_numastat = config_get_boolean_ondemand(
249 + "plugin:proc:/sys/devices/system/node", "enable per-node numa metrics", CONFIG_BOOLEAN_AUTO);
250 + }
251 +
252 + if(unlikely(numa_root == NULL)) {
253 + numa_node_count = find_all_nodes();
254 + if(unlikely(numa_root == NULL))
255 + return 1;
256 + }
257 +
258 + if (do_numastat == CONFIG_BOOLEAN_YES || (do_numastat == CONFIG_BOOLEAN_AUTO && numa_node_count >= 2)) {
259 + for (m = numa_root; m; m = m->next) {
260 + do_muma_numastat(m, update_every);
261 + do_numa_meminfo(m, update_every);
262 + }
263 + return 0;
264 }
265
163 - return 0;
266 + return 1;
267 }