Added HZ and for all systems numcpu defaults to 1. Now jiffies multiplied to 
100/HZ.
In sysctl capable systems HZ extracted from kern.clockrate stathz. In linux 
it's sysconf(_SC_CLK_TCK); For other systems it's defaults to 100 for now.

Added config options
<Plugin cpu>
        PerCpuStatistic true
        ScaleTo100      false
</Plugin>

Now summary CPU statistic always collected (it's more usefull than percore).
PerCpuStatistic - also collect data for each cpu
ScaleTo100 - scale summary cpu data to 100% (divide by numcpu).
---
 src/cpu.c |  209 +++++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 155 insertions(+), 54 deletions(-)

diff --git a/src/cpu.c b/src/cpu.c
index 12071a2..6f533e6 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -113,7 +113,6 @@ static int cpu_temp_retry_max     = 1;
 /* #endif PROCESSOR_CPU_LOAD_INFO */
 
 #elif defined(KERNEL_LINUX)
-/* no variables needed */
 /* #endif KERNEL_LINUX */
 
 #elif defined(HAVE_LIBKSTAT)
@@ -121,15 +120,14 @@ static int cpu_temp_retry_max     = 1;
 # define MAX_NUMCPU 256
 extern kstat_ctl_t *kc;
 static kstat_t *ksp[MAX_NUMCPU];
-static int numcpu;
+//static int numcpu;
 /* #endif HAVE_LIBKSTAT */
 
 #elif CAN_USE_SYSCTL
-static int numcpu;
 /* #endif CAN_USE_SYSCTL */
 
 #elif defined(HAVE_SYSCTLBYNAME)
-static int numcpu;
+//static int numcpu;
 #  ifdef HAVE_SYSCTL_KERN_CP_TIMES
 static int maxcpu;
 #  endif /* HAVE_SYSCTL_KERN_CP_TIMES */
@@ -141,10 +139,48 @@ static int maxcpu;
 
 #elif defined(HAVE_PERFSTAT)
 static perfstat_cpu_t *perfcpu;
-static int numcpu;
+//static int numcpu;
 static int pnumcpu;
 #endif /* HAVE_PERFSTAT */
 
+static const char *config_keys[] =
+{
+       "PerCpuStatistic",
+       "ScaleTo100",
+       NULL
+};
+static int config_keys_num = 2;
+
+static int numcpu = 1;
+static bool per_cpu_statistic = false;
+static bool scale = true;
+static int hz=100;
+
+
+static int cpu_config (const char *key, const char *value)
+{
+       if (strcasecmp (key, "PerCpuStatistic") == 0)
+       {
+               if (IS_TRUE (value))
+                     per_cpu_statistic = true;
+                else
+                    per_cpu_statistic = false;
+       }
+       else if (strcasecmp (key, "ScaleTo100") == 0)
+       {
+               if (IS_TRUE (value))
+                    scale = true;
+                else
+                    scale = false;
+       }
+       else
+       {
+               return (-1);
+       }
+
+       return (0);
+}
+
 static int init (void)
 {
 #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
@@ -199,6 +235,21 @@ static int init (void)
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
+
+        struct clockinfo ci;
+       size_t ci_size = sizeof (ci);
+       int mib[2] = {CTL_KERN, KERN_CLOCKRATE};
+
+       status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
+                       &ci, &ci_size, NULL, 0);
+       if (status == -1)
+       {
+               char errbuf[1024];
+               WARNING ("cpu plugin: sysctl: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
+        hz = ci.stathz;
 /* #endif CAN_USE_SYSCTL */
 
 #elif defined (HAVE_SYSCTLBYNAME)
@@ -214,6 +265,17 @@ static int init (void)
                return (-1);
        }
 
+        struct clockinfo ci;
+       size_t ci_size = sizeof (ci);
+       if (sysctlbyname ("kern.clockrate", &ci, &ci_size, NULL, 0) < 0)
+       {
+               char errbuf[1024];
+               WARNING ("cpu plugin: sysctlbyname(kern.clockrate): %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
+        hz = ci.stathz;
+
 #ifdef HAVE_SYSCTL_KERN_CP_TIMES
        numcpu_size = sizeof (maxcpu);
 
@@ -238,6 +300,11 @@ static int init (void)
        /* nothing to initialize */
 #endif /* HAVE_PERFSTAT */
 
+#if defined(KERNEL_LINUX)
+        numcpu = sysconf( _SC_NPROCESSORS_ONLN );
+        hz = sysconf(_SC_CLK_TCK);
+#endif /* KERNEL_LINUX */
+
        return (0);
 } /* int init */
 
@@ -246,13 +313,20 @@ static void submit (int cpu_num, const char 
*type_instance, derive_t value)
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = value;
+        if (hz != 100)
+           values[0].derive = (derive_t) (value * (100.0 / hz));
+        else
+           values[0].derive = value;
+
+        if (scale && cpu_num < 0)
+            values[0].derive = values[0].derive / numcpu;
 
        vl.values = values;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin));
-       ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+        if (cpu_num >= 0)
+           ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
                        "%i", cpu_num);
        sstrncpy (vl.type, "cpu", sizeof (vl.type));
        sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
@@ -359,6 +433,7 @@ static int cpu_read (void)
 
        char *fields[9];
        int numfields;
+        bool allcpu;
 
        if ((fh = fopen ("/proc/stat", "r")) == NULL)
        {
@@ -372,14 +447,20 @@ static int cpu_read (void)
        {
                if (strncmp (buf, "cpu", 3))
                        continue;
-               if ((buf[3] < '0') || (buf[3] > '9'))
+    
+                allcpu = buf[3] == ' ';
+               if ( ((!per_cpu_statistic) || (buf[3] < '0') || (buf[3] > '9')) 
&& (!allcpu) )
                        continue;
 
                numfields = strsplit (buf, fields, 9);
                if (numfields < 5)
                        continue;
 
-               cpu = atoi (fields[0] + 3);
+                if (allcpu) 
+                    cpu = -1;
+                else
+                    cpu = atoi (fields[0] + 3);
+
                user = atoll (fields[1]);
                nice = atoll (fields[2]);
                syst = atoll (fields[3]);
@@ -449,7 +530,7 @@ static int cpu_read (void)
        memset (cpuinfo, 0, sizeof (cpuinfo));
 
 #if defined(KERN_CPTIME2)
-       if (numcpu > 1) {
+       if (per_cpu_statistic && numcpu > 1) {
                for (i = 0; i < numcpu; i++) {
                        int mib[] = {CTL_KERN, KERN_CPTIME2, i};
 
@@ -464,61 +545,79 @@ static int cpu_read (void)
                                return (-1);
                        }
                }
+               for (i = 0; i < numcpu; i++) {
+                       submit (i, "user",      cpuinfo[i][CP_USER]);
+                       submit (i, "nice",      cpuinfo[i][CP_NICE]);
+                       submit (i, "system",    cpuinfo[i][CP_SYS]);
+                       submit (i, "idle",      cpuinfo[i][CP_IDLE]);
+                       submit (i, "interrupt", cpuinfo[i][CP_INTR]);
+               }
        }
-       else
 #endif /* defined(KERN_CPTIME2) */
-       {
-               int mib[] = {CTL_KERN, KERN_CPTIME};
-               long cpuinfo_tmp[CPUSTATES];
+       int mib[] = {CTL_KERN, KERN_CPTIME};
+       long cpuinfo_tmp[CPUSTATES];
 
-               cpuinfo_size = sizeof(cpuinfo_tmp);
+       cpuinfo_size = sizeof(cpuinfo_tmp);
 
-               status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
+       status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
                                        &cpuinfo_tmp, &cpuinfo_size, NULL, 0);
-               if (status == -1)
-               {
-                       char errbuf[1024];
-                       ERROR ("cpu plugin: sysctl failed: %s.",
-                                       sstrerror (errno, errbuf, sizeof 
(errbuf)));
-                       return (-1);
-               }
-
-               for(i = 0; i < CPUSTATES; i++) {
-                       cpuinfo[0][i] = cpuinfo_tmp[i];
-               }
+       if (status == -1)
+       {
+               char errbuf[1024];
+               ERROR ("cpu plugin: sysctl failed: %s.",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
        }
 
-       for (i = 0; i < numcpu; i++) {
-               submit (i, "user",      cpuinfo[i][CP_USER]);
-               submit (i, "nice",      cpuinfo[i][CP_NICE]);
-               submit (i, "system",    cpuinfo[i][CP_SYS]);
-               submit (i, "idle",      cpuinfo[i][CP_IDLE]);
-               submit (i, "interrupt", cpuinfo[i][CP_INTR]);
-       }
+       submit (-1, "user",      cpuinfo_tmp[CP_USER]);
+       submit (-1, "nice",      cpuinfo_tmp[CP_NICE]);
+       submit (-1, "system",    cpuinfo_tmp[CP_SYS]);
+       submit (-1, "idle",      cpuinfo_tmp[CP_IDLE]);
+       submit (-1, "interrupt", cpuinfo_tmp[CP_INTR]);
 /* #endif CAN_USE_SYSCTL */
 #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES)
-       long cpuinfo[maxcpu][CPUSTATES];
-       size_t cpuinfo_size;
-       int i;
-
-       memset (cpuinfo, 0, sizeof (cpuinfo));
-
-       cpuinfo_size = sizeof (cpuinfo);
-       if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0)
+       size_t cpuinfo_size;
+        if (per_cpu_statistic) {
+               long cpuinfo[maxcpu][CPUSTATES];
+               int i;
+        
+               memset (cpuinfo, 0, sizeof (cpuinfo));
+        
+               cpuinfo_size = sizeof (cpuinfo);
+               if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, 
NULL, 0) < 0)
+               {
+                       char errbuf[1024];
+                       ERROR ("cpu plugin: sysctlbyname failed: %s.",
+                                       sstrerror (errno, errbuf, sizeof 
(errbuf)));
+                       return (-1);
+               }
+
+               for (i = 0; i < numcpu; i++) {
+                       submit (i, "user", cpuinfo[i][CP_USER]);
+                       submit (i, "nice", cpuinfo[i][CP_NICE]);
+                       submit (i, "system", cpuinfo[i][CP_SYS]);
+                       submit (i, "idle", cpuinfo[i][CP_IDLE]);
+                       submit (i, "interrupt", cpuinfo[i][CP_INTR]);
+               }
+        }
+
+       long cpuinfo2[CPUSTATES];
+
+       cpuinfo_size = sizeof (cpuinfo2);
+
+       if (sysctlbyname("kern.cp_time", &cpuinfo2, &cpuinfo_size, NULL, 0) < 0)
        {
                char errbuf[1024];
                ERROR ("cpu plugin: sysctlbyname failed: %s.",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
+       submit (-1, "user", cpuinfo2[CP_USER]);
+       submit (-1, "nice", cpuinfo2[CP_NICE]);
+       submit (-1, "system", cpuinfo2[CP_SYS]);
+       submit (-1, "idle", cpuinfo2[CP_IDLE]);
+       submit (-1, "interrupt", cpuinfo2[CP_INTR]);
 
-       for (i = 0; i < numcpu; i++) {
-               submit (i, "user", cpuinfo[i][CP_USER]);
-               submit (i, "nice", cpuinfo[i][CP_NICE]);
-               submit (i, "system", cpuinfo[i][CP_SYS]);
-               submit (i, "idle", cpuinfo[i][CP_IDLE]);
-               submit (i, "interrupt", cpuinfo[i][CP_INTR]);
-       }
 /* #endif HAVE_SYSCTL_KERN_CP_TIMES */
 #elif defined(HAVE_SYSCTLBYNAME)
        long cpuinfo[CPUSTATES];
@@ -534,11 +633,11 @@ static int cpu_read (void)
                return (-1);
        }
 
-       submit (0, "user", cpuinfo[CP_USER]);
-       submit (0, "nice", cpuinfo[CP_NICE]);
-       submit (0, "system", cpuinfo[CP_SYS]);
-       submit (0, "idle", cpuinfo[CP_IDLE]);
-       submit (0, "interrupt", cpuinfo[CP_INTR]);
+       submit (-1, "user", cpuinfo[CP_USER]);
+       submit (-1, "nice", cpuinfo[CP_NICE]);
+       submit (-1, "system", cpuinfo[CP_SYS]);
+       submit (-1, "idle", cpuinfo[CP_IDLE]);
+       submit (-1, "interrupt", cpuinfo[CP_INTR]);
 /* #endif HAVE_SYSCTLBYNAME */
 
 #elif defined(HAVE_LIBSTATGRAB)
@@ -603,6 +702,8 @@ static int cpu_read (void)
 
 void module_register (void)
 {
+       plugin_register_config ("cpu", cpu_config,
+                       config_keys, config_keys_num);
        plugin_register_init ("cpu", init);
        plugin_register_read ("cpu", cpu_read);
 } /* void module_register */
-- 
1.7.4.1


_______________________________________________
collectd mailing list
collectd@verplant.org
http://mailman.verplant.org/listinfo/collectd

Reply via email to