Browse Source

feat(proc/numa): add numa node mem activity (#18855)

Ilya Mashchenko 4 months ago
parent
commit
5d1999b526
2 changed files with 83 additions and 48 deletions
  1. 1 0
      src/collectors/all.h
  2. 82 48
      src/collectors/proc.plugin/sys_devices_system_node.c

+ 1 - 0
src/collectors/all.h

@@ -114,6 +114,7 @@
 #define NETDATA_CHART_PRIO_MEM_NUMA                   1400
 #define NETDATA_CHART_PRIO_MEM_NUMA_NODES_NUMASTAT    1410
 #define NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO     1411
+#define NETDATA_CHART_PRIO_MEM_NUMA_NODES_ACTIVITY    1412
 #define NETDATA_CHART_PRIO_MEM_PAGEFRAG               1450
 #define NETDATA_CHART_PRIO_MEM_HW                     1500
 #define NETDATA_CHART_PRIO_MEM_HW_ECC_CE              1550

+ 82 - 48
src/collectors/proc.plugin/sys_devices_system_node.c

@@ -14,7 +14,8 @@ struct node {
     struct {
         char *filename;
         procfile *ff;
-        RRDSET *st;
+        RRDSET *st_mem_usage;
+        RRDSET *st_mem_activity;
     } meminfo;
 
     struct node *next;
@@ -141,22 +142,22 @@ static void do_muma_numastat(struct node *m, int update_every) {
                 continue;
             }
 
-            char *name  = procfile_lineword(m->numastat.ff, l, 0);
+            char *name = procfile_lineword(m->numastat.ff, l, 0);
             char *value = procfile_lineword(m->numastat.ff, l, 1);
 
             if (unlikely(!name || !*name || !value || !*value))
                 continue;
 
             uint32_t hash = simple_hash(name);
-            if(likely(
-                       (hash == hash_numa_hit       && !strcmp(name, "numa_hit"))
-                    || (hash == hash_numa_miss      && !strcmp(name, "numa_miss"))
-                    || (hash == hash_local_node     && !strcmp(name, "local_node"))
-                    || (hash == hash_numa_foreign   && !strcmp(name, "numa_foreign"))
-                    || (hash == hash_interleave_hit && !strcmp(name, "interleave_hit"))
-                    || (hash == hash_other_node     && !strcmp(name, "other_node"))
-                        ))
+
+            if ((hash == hash_numa_hit && !strcmp(name, "numa_hit")) ||
+                (hash == hash_numa_miss && !strcmp(name, "numa_miss")) ||
+                (hash == hash_local_node && !strcmp(name, "local_node")) ||
+                (hash == hash_numa_foreign && !strcmp(name, "numa_foreign")) ||
+                (hash == hash_interleave_hit && !strcmp(name, "interleave_hit")) ||
+                (hash == hash_other_node && !strcmp(name, "other_node"))) {
                 rrddim_set(m->numastat.st, name, (collected_number)str2kernel_uint_t(value));
+            }
         }
 
         rrdset_done(m->numastat.st);
@@ -164,73 +165,106 @@ static void do_muma_numastat(struct node *m, int update_every) {
 }
 
 static void do_numa_meminfo(struct node *m, int update_every) {
-    static uint32_t hash_MemFree = 0, hash_MemUsed = 0;
+    static uint32_t hash_MemFree = 0, hash_MemUsed = 0, hash_ActiveAnon = 0, hash_InactiveAnon = 0, hash_ActiveFile = 0,
+                    hash_InactiveFile = 0;
     static bool initialized = false;
-    
-    if(unlikely(!initialized)) {
+
+    if (unlikely(!initialized)) {
         initialized = true;
         hash_MemFree = simple_hash("MemFree");
         hash_MemUsed = simple_hash("MemUsed");
+        hash_ActiveAnon = simple_hash("Active(anon)");
+        hash_InactiveAnon = simple_hash("Inactive(anon)");
+        hash_ActiveFile = simple_hash("Active(file)");
+        hash_InactiveFile = simple_hash("Inactive(file)");
     }
 
     if (m->meminfo.filename) {
-        if(unlikely(!m->meminfo.ff)) {
+        if (unlikely(!m->meminfo.ff)) {
             m->meminfo.ff = procfile_open(m->meminfo.filename, " :", PROCFILE_FLAG_DEFAULT);
-            if(unlikely(!m->meminfo.ff))
+            if (unlikely(!m->meminfo.ff))
                 return;
         }
 
         m->meminfo.ff = procfile_readall(m->meminfo.ff);
-        if(unlikely(!m->meminfo.ff || procfile_lines(m->meminfo.ff) < 1 || procfile_linewords(m->meminfo.ff, 0) < 1))
+        if (unlikely(!m->meminfo.ff || procfile_lines(m->meminfo.ff) < 1 || procfile_linewords(m->meminfo.ff, 0) < 1))
             return;
 
-        if(unlikely(!m->meminfo.st)) {
-            m->meminfo.st = rrdset_create_localhost(
-                "numa_node_mem_usage"
-                , m->name
-                , NULL
-                , "numa"
-                , "mem.numa_node_mem_usage"
-                , "NUMA Node Memory Usage"
-                , "bytes"
-                , PLUGIN_PROC_NAME
-                , "/sys/devices/system/node"
-                , NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO
-                , update_every
-                , RRDSET_TYPE_STACKED
-            );
-
-            rrdlabels_add(m->meminfo.st->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
-
-            rrddim_add(m->meminfo.st, "MemFree", "free", 1, 1, RRD_ALGORITHM_ABSOLUTE);
-            rrddim_add(m->meminfo.st, "MemUsed", "used", 1, 1, RRD_ALGORITHM_ABSOLUTE);
+        if (unlikely(!m->meminfo.st_mem_usage)) {
+            m->meminfo.st_mem_usage = rrdset_create_localhost(
+                "numa_node_mem_usage",
+                m->name,
+                NULL,
+                "numa",
+                "mem.numa_node_mem_usage",
+                "NUMA Node Memory Usage",
+                "bytes",
+                PLUGIN_PROC_NAME,
+                "/sys/devices/system/node",
+                NETDATA_CHART_PRIO_MEM_NUMA_NODES_MEMINFO,
+                update_every,
+                RRDSET_TYPE_STACKED);
+
+            rrdlabels_add(m->meminfo.st_mem_usage->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
+
+            rrddim_add(m->meminfo.st_mem_usage, "MemFree", "free", 1, 1, RRD_ALGORITHM_ABSOLUTE);
+            rrddim_add(m->meminfo.st_mem_usage, "MemUsed", "used", 1, 1, RRD_ALGORITHM_ABSOLUTE);
+        }
+        if (unlikely(!m->meminfo.st_mem_activity)) {
+            m->meminfo.st_mem_activity = rrdset_create_localhost(
+                "numa_node_mem_activity",
+                m->name,
+                NULL,
+                "numa",
+                "mem.numa_node_mem_activity",
+                "NUMA Node Memory Activity",
+                "bytes",
+                PLUGIN_PROC_NAME,
+                "/sys/devices/system/node",
+                NETDATA_CHART_PRIO_MEM_NUMA_NODES_ACTIVITY,
+                update_every,
+                RRDSET_TYPE_STACKED);
+
+            rrdlabels_add(m->meminfo.st_mem_activity->rrdlabels, "numa_node", m->name, RRDLABEL_SRC_AUTO);
+
+            rrddim_add(m->meminfo.st_mem_activity, "Active(anon)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+            rrddim_add(m->meminfo.st_mem_activity, "Inactive(anon)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+            rrddim_add(m->meminfo.st_mem_activity, "Active(file)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+            rrddim_add(m->meminfo.st_mem_activity, "Inactive(file)", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
         }
 
         size_t lines = procfile_lines(m->meminfo.ff), l;
-        for(l = 0; l < lines; l++) {
+        for (l = 0; l < lines; l++) {
             size_t words = procfile_linewords(m->meminfo.ff, l);
 
-            if(unlikely(words < 4)) {
-                if(unlikely(words))
-                    collector_error("Cannot read %s line %zu. Expected 4 params, read %zu.", m->meminfo.filename, l, words);
+            if (unlikely(words < 4)) {
+                if (words)
+                    collector_error(
+                        "Cannot read %s line %zu. Expected 4 params, read %zu.", m->meminfo.filename, l, words);
                 continue;
             }
 
-            char *name  = procfile_lineword(m->meminfo.ff, l, 2);
+            char *name = procfile_lineword(m->meminfo.ff, l, 2);
             char *value = procfile_lineword(m->meminfo.ff, l, 3);
 
             if (unlikely(!name || !*name || !value || !*value))
                 continue;
 
             uint32_t hash = simple_hash(name);
-            if(likely(
-                       (hash == hash_MemFree && !strcmp(name, "MemFree"))
-                    || (hash == hash_MemUsed && !strcmp(name, "MemUsed"))
-                    ))
-                rrddim_set(m->meminfo.st, name, (collected_number)str2kernel_uint_t(value) * 1024);
-        }
 
-        rrdset_done(m->meminfo.st);
+            if ((hash == hash_MemFree && !strcmp(name, "MemFree")) ||
+                (hash == hash_MemUsed && !strcmp(name, "MemUsed"))) {
+                rrddim_set(m->meminfo.st_mem_usage, name, (collected_number)str2kernel_uint_t(value) * 1024);
+            } else if (
+                (hash == hash_ActiveAnon && !strcmp(name, "Active(anon)")) ||
+                (hash == hash_InactiveAnon && !strcmp(name, "Inactive(anon)")) ||
+                (hash == hash_ActiveFile && !strcmp(name, "Active(file)")) ||
+                (hash == hash_InactiveFile && !strcmp(name, "Inactive(file)"))) {
+                rrddim_set(m->meminfo.st_mem_activity, name, (collected_number)str2kernel_uint_t(value) * 1024);
+            }
+        }
+        rrdset_done(m->meminfo.st_mem_usage);
+        rrdset_done(m->meminfo.st_mem_activity);
     }
 }