memory plugin: Move calculation of the percentage to memory_submit().
[collectd.git] / src / memory.c
index 160e1ee..a4b21da 100644 (file)
@@ -84,7 +84,6 @@ static int pagesize;
 /* endif HAVE_LIBSTATGRAB */
 #elif HAVE_PERFSTAT
 static int pagesize;
-static perfstat_memory_total_t pmemory;
 /* endif HAVE_PERFSTAT */
 #else
 # error "No applicable input method."
@@ -156,21 +155,29 @@ static int memory_init (void)
        return (0);
 } /* int memory_init */
 
-static void memory_submit (const char *type_instance, gauge_t value)
+static void memory_submit (const char *type_instance, gauge_t value, gauge_t total)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
        vl.values = values;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "memory", sizeof (vl.plugin));
-       sstrncpy (vl.type, "memory", sizeof (vl.type));
        sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
 
-       plugin_dispatch_values (&vl);
+       if (values_absolute)
+       {
+               values[0].gauge = value;
+               sstrncpy (vl.type, "memory", sizeof (vl.type));
+               plugin_dispatch_values (&vl);
+       }
+       if (values_percentage)
+       {
+               values[0].gauge = 100.0 * value / total;
+               sstrncpy (vl.type, "percent", sizeof (vl.type));
+               plugin_dispatch_values (&vl);
+       }
 }
 
 static int memory_read (void)
@@ -224,20 +231,10 @@ static int memory_read (void)
        free     = (gauge_t) (((uint64_t) vm_data.free_count)     * ((uint64_t) pagesize));
        total    = wired + active + inactive + free;
 
-       if (values_absolute)
-       {
-               memory_submit ("wired",    wired);
-               memory_submit ("active",   active);
-               memory_submit ("inactive", inactive);
-               memory_submit ("free",     free);
-       }
-       if (values_percentage)
-       {
-               memory_submit ("percent_wired",    (gauge_t) ((float_t) wired) / total * 100);
-               memory_submit ("percent_active",   (gauge_t) ((float_t) active) / total * 100);
-               memory_submit ("percent_inactive", (gauge_t) ((float_t) inactive / total * 100);
-               memory_submit ("percent_free",     (gauge_t) ((float_t) free / total * 100);
-       }
+       memory_submit ("wired",    wired,    total);
+       memory_submit ("active",   active,   total);
+       memory_submit ("inactive", inactive, total);
+       memory_submit ("free",     free,     total);
 /* #endif HAVE_HOST_STATISTICS */
 
 #elif HAVE_SYSCTLBYNAME
@@ -262,6 +259,7 @@ static int memory_read (void)
                NULL
        };
        double sysctl_vals[8];
+       gauge_t total;
 
        int    i;
 
@@ -287,23 +285,12 @@ static int memory_read (void)
                if (!isnan (sysctl_vals[i]))
                        sysctl_vals[i] *= sysctl_vals[0];
 
-       if (values_absolute)
-       {
-               memory_submit ("free",     sysctl_vals[2]);
-               memory_submit ("wired",    sysctl_vals[3]);
-               memory_submit ("active",   sysctl_vals[4]);
-               memory_submit ("inactive", sysctl_vals[5]);
-               memory_submit ("cache",    sysctl_vals[6]);
-       }
-       if (values_percentage)
-       {
-               double total = sysctl_vals[2] + sysctl_vals[3] + sysctl_vals[4] + sysctl_vals[5] + sysctl_vals[6];
-               memory_submit ("percent_free",     (gauge_t) ((float_t) sysctl_vals[2]) / total * 100);
-               memory_submit ("percent_wired",    (gauge_t) ((float_t) sysctl_vals[3]) / total * 100);
-               memory_submit ("percent_active",   (gauge_t) ((float_t) sysctl_vals[4]) / total * 100);
-               memory_submit ("percent_inactive", (gauge_t) ((float_t) sysctl_vals[5]) / total * 100);
-               memory_submit ("percent_cache",    (gauge_t) ((float_t) sysctl_vals[6]) / total * 100);
-       }
+       total = sysctl_vals[2] + sysctl_vals[3] + sysctl_vals[4] + sysctl_vals[5] + sysctl_vals[6];
+       memory_submit ("free",     sysctl_vals[2], total);
+       memory_submit ("wired",    sysctl_vals[3], total);
+       memory_submit ("active",   sysctl_vals[4], total);
+       memory_submit ("inactive", sysctl_vals[5], total);
+       memory_submit ("cache",    sysctl_vals[6], total);
 /* #endif HAVE_SYSCTLBYNAME */
 
 #elif KERNEL_LINUX
@@ -357,24 +344,14 @@ static int memory_read (void)
                                sstrerror (errno, errbuf, sizeof (errbuf)));
        }
 
-       if (mem_total >= (mem_free + mem_buffered + mem_cached))
-       {
-               mem_used = mem_total - (mem_free + mem_buffered + mem_cached);
-               if (values_absolute)
-               {
-                       memory_submit ("used",     mem_used);
-                       memory_submit ("buffered", mem_buffered);
-                       memory_submit ("cached",   mem_cached);
-                       memory_submit ("free",     mem_free);
-               }
-               if (values_percentage)
-               {
-                       memory_submit ("percent_used",     (gauge_t) ((float_t) mem_used) / mem_total * 100);
-                       memory_submit ("percent_buffered", (gauge_t) ((float_t) mem_buffered) / mem_total * 100);
-                       memory_submit ("percent_cached",   (gauge_t) ((float_t) mem_cached) / mem_total * 100);
-                       memory_submit ("percent_free",     (gauge_t) ((float_t) mem_free) / mem_total * 100);
-               }
-       }
+       if (mem_total < (mem_free + mem_buffered + mem_cached))
+               return (0);
+
+       mem_used = mem_total - (mem_free + mem_buffered + mem_cached);
+       memory_submit ("used",     (gauge_t) mem_used,     (gauge_t) mem_total);
+       memory_submit ("buffered", (gauge_t) mem_buffered, (gauge_t) mem_total);
+       memory_submit ("cached",   (gauge_t) mem_cached,   (gauge_t) mem_total);
+       memory_submit ("free",     (gauge_t) mem_free,     (gauge_t) mem_total);
 /* #endif KERNEL_LINUX */
 
 #elif HAVE_LIBKSTAT
@@ -385,6 +362,7 @@ static int memory_read (void)
        long long mem_lock;
        long long mem_kern;
        long long mem_unus;
+       long long mem_total;
 
        long long pp_kernel;
        long long physmem;
@@ -429,7 +407,7 @@ static int memory_read (void)
        }
 
        /* mem_kern is accounted for in mem_lock */
-       if ( pp_kernel < mem_lock )
+       if (pp_kernel < mem_lock)
        {
                mem_kern = pp_kernel;
                mem_lock -= pp_kernel;
@@ -445,29 +423,22 @@ static int memory_read (void)
        mem_lock *= pagesize; /* some? ;) */
        mem_kern *= pagesize; /* it's 2011 RAM is cheap */
        mem_unus *= pagesize;
+       mem_total = mem_used + mem_free + mem_lock + mem_kern + mem_unus;
 
-       if (values_absolute)
-       {
-               memory_submit ("used",   mem_used);
-               memory_submit ("free",   mem_free);
-               memory_submit ("locked", mem_lock);
-               memory_submit ("kernel", mem_kern);
-               memory_submit ("unusable", mem_unus);
-       }
-       if (values_percentage)
-       {
-               memory_submit ("percent_used",   (gauge_t) ((float_t) mem_used) / (mem_used + mem_free + mem_lock + mem_kern + mem_unus) * 100);
-               memory_submit ("percent_free",   (gauge_t) ((float_t) mem_free) / (mem_used + mem_free + mem_lock + mem_kern + mem_unus) * 100);
-               memory_submit ("percent_locked", (gauge_t) ((float_t) mem_lock) / (mem_used + mem_free + mem_lock + mem_kern + mem_unus) * 100);
-               memory_submit ("percent_kernel", (gauge_t) ((float_t) mem_kern) / (mem_used + mem_free + mem_lock + mem_kern + mem_unus) * 100);
-               memory_submit ("percent_unusable", (gauge_t) ((float_t) mem_unus) / (mem_used + mem_free + mem_lock + mem_kern + mem_unus) * 100);
-
-       }
+       memory_submit ("used",     (gauge_t) mem_used, (gauge_t) mem_total);
+       memory_submit ("free",     (gauge_t) mem_free, (gauge_t) mem_total);
+       memory_submit ("locked",   (gauge_t) mem_lock, (gauge_t) mem_total);
+       memory_submit ("kernel",   (gauge_t) mem_kern, (gauge_t) mem_total);
+       memory_submit ("unusable", (gauge_t) mem_unus, (gauge_t) mem_total);
 /* #endif HAVE_LIBKSTAT */
 
 #elif HAVE_SYSCTL
        int mib[] = {CTL_VM, VM_METER};
        struct vmtotal vmtotal;
+       gauge_t mem_active;
+       gauge_t mem_inactive;
+       gauge_t mem_free;
+       gauge_t mem_total;
        size_t size;
 
        memset (&vmtotal, 0, sizeof (vmtotal));
@@ -481,64 +452,56 @@ static int memory_read (void)
        }
 
        assert (pagesize > 0);
-       if (values_absolute)
-       {
-               memory_submit ("active",   vmtotal.t_arm * pagesize);
-               memory_submit ("inactive", (vmtotal.t_rm - vmtotal.t_arm) * pagesize);
-               memory_submit ("free",     vmtotal.t_free * pagesize);
-       }
-       if (values_percentage)
-       {
-               memory_submit ("percent_active",   (gauge_t) ((float_t) vmtotal.t_arm) / (vmtotal.t_rm + vmtotal.t_free) * 100);
-               memory_submit ("percent_inactive", (gauge_t) ((float_t) (vmtotal.t_rm - vmtotal.t_arm) / (vmtotal.t_rm + vmtotal.t_free) * 100);
-               memory_submit ("percent_free",     (gauge_t) ((float_t) vmtotal.t_free) / (vmtotal.t_rm + vmtotal.t_free) * 100);
-       }
+       mem_active   = (gauge_t) (vmtotal.t_arm * pagesize);
+       mem_inactive = (gauge_t) ((vmtotal.t_rm - vmtotal.t_arm) * pagesize);
+       mem_free     = (gauge_t) (vmtotal.t_free * pagesize);
+       mem_total    = mem_active + mem_inactive + mem_free;
+
+       memory_submit ("active",   mem_active,   mem_total);
+       memory_submit ("inactive", mem_inactive, mem_total);
+       memory_submit ("free",     mem_free,     mem_total);
 /* #endif HAVE_SYSCTL */
 
 #elif HAVE_LIBSTATGRAB
        sg_mem_stats *ios;
+       gauge_t total;
 
-       if ((ios = sg_get_mem_stats ()) != NULL)
-       {
-               if (values_absolute)
-               {
-                       memory_submit ("used",   ios->used);
-                       memory_submit ("cached", ios->cache);
-                       memory_submit ("free",   ios->free);
-               }
-               if (values_percentage)
-               {
-                       memory_submit ("percent_used",   (gauge_t) ((float_t) ios->used) / (ios->used + ios->cache + ios->free) * 100);
-                       memory_submit ("percent_cached", (gauge_t) ((float_t) ios->cache) / (ios->used + ios->cache + ios->free) * 100);
-                       memory_submit ("percent_free",   (gauge_t) ((float_t) ios->free) / (ios->used + ios->cache + ios->free) * 100);
-               }
-       }
+       ios = sg_get_mem_stats ();
+       if (ios == NULL)
+               return (-1);
+
+       total = (gauge_t) (ios->used + ios->cache + ios->free);
+       memory_submit ("used",   (gauge_t) ios->used,  total);
+       memory_submit ("cached", (gauge_t) ios->cache, total);
+       memory_submit ("free",   (gauge_t) ios->free,  total);
 /* #endif HAVE_LIBSTATGRAB */
 
 #elif HAVE_PERFSTAT
-       if (perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0)
+       perfstat_memory_total_t pmemory;
+
+       memset (&pmemory, 0, sizeof (pmemory));
+       if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0)
        {
                char errbuf[1024];
                WARNING ("memory plugin: perfstat_memory_total failed: %s",
                        sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
-       if (values_absolute)
-       {
-               memory_submit ("used",   pmemory.real_inuse * pagesize);
-               memory_submit ("free",   pmemory.real_free * pagesize);
-               memory_submit ("cached", pmemory.numperm * pagesize);
-               memory_submit ("system", pmemory.real_system * pagesize);
-               memory_submit ("user",   pmemory.real_process * pagesize);
-       }
-       if (values_percentage)
-       {
-               memory_submit ("percent_used",   (gauge_t) ((float_t) pmemory.real_inuse) / pmemory.real_total * 100);
-               memory_submit ("percent_free",   (gauge_t) ((float_t) pmemory.real_free) / pmemory.real_total * 100);
-               memory_submit ("percent_cached", (gauge_t) ((float_t) pmemory.numperm) / pmemory.real_total * 100);
-               memory_submit ("percent_system", (gauge_t) ((float_t) pmemory.real_system) / pmemory.real_total * 100);
-               memory_submit ("percent_user",   (gauge_t) ((float_t) pmemory.real_process) / pmemory.real_total * 100);
-       }
+
+       /* Unfortunately, the AIX documentation is not very clear on how these
+        * numbers relate to one another. The only thing is states explcitly
+        * is:
+        *   real_total = real_process + real_free + numperm + real_system
+        *
+        * Another segmentation, which would be closer to the numbers reported
+        * by the "svmon" utility, would be:
+        *   real_total = real_free + real_inuse
+        *   real_inuse = "active" + real_pinned + numperm
+        */
+       memory_submit ("free",   pmemory.real_free    * pagesize, pmemory.real_total * pagesize);
+       memory_submit ("cached", pmemory.numperm      * pagesize, pmemory.real_total * pagesize);
+       memory_submit ("system", pmemory.real_system  * pagesize, pmemory.real_total * pagesize);
+       memory_submit ("user",   pmemory.real_process * pagesize, pmemory.real_total * pagesize);
 #endif /* HAVE_PERFSTAT */
 
        return (0);