Merge branch 'master' of git://github.com/octo/collectd
[collectd.git] / src / cpu.c
index 8a4e10e..b92b0e2 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,7 +1,8 @@
 /**
  * collectd - src/cpu.c
  * Copyright (C) 2005-2009  Florian octo Forster
- * Copyright (C) 2009 Simon Kuhnle
+ * Copyright (C) 2008       Oleg King
+ * Copyright (C) 2009       Simon Kuhnle
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,6 +19,7 @@
  *
  * Authors:
  *   Florian octo Forster <octo at verplant.org>
+ *   Oleg King <king2 at kaluga.ru>
  *   Simon Kuhnle <simon at blarzwurst.de>
  **/
 
@@ -121,6 +123,9 @@ static int numcpu;
 
 #elif defined(HAVE_SYSCTLBYNAME)
 static int numcpu;
+#  ifdef HAVE_SYSCTL_KERN_CP_TIMES
+static int maxcpu;
+#  endif /* HAVE_SYSCTL_KERN_CP_TIMES */
 /* #endif HAVE_SYSCTLBYNAME */
 
 #elif defined(HAVE_LIBSTATGRAB)
@@ -191,13 +196,25 @@ static int init (void)
        if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0)
        {
                char errbuf[1024];
-               WARNING ("cpu plugin: sysctlbyname: %s",
+               WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
 
+#ifdef HAVE_SYSCTL_KERN_CP_TIMES
+       numcpu_size = sizeof (maxcpu);
+
+       if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0)
+       {
+               char errbuf[1024];
+               WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
+#else
        if (numcpu != 1)
                NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu);
+#endif
 /* #endif HAVE_SYSCTLBYNAME */
 
 #elif defined(HAVE_LIBSTATGRAB)
@@ -218,7 +235,7 @@ static void submit (int cpu_num, const char *type_instance, counter_t value)
        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.type_instance),
+       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));
@@ -462,7 +479,30 @@ static int cpu_read (void)
                submit (i, "interrupt", cpuinfo[i][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)
+       {
+               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]);
+       }
+/* #endif HAVE_SYSCTL_KERN_CP_TIMES */
 #elif defined(HAVE_SYSCTLBYNAME)
        long cpuinfo[CPUSTATES];
        size_t cpuinfo_size;