fi
# }}}
+# --with-libxenctrl {{{
+with_libxenctrl_cppflags=""
+with_libxenctrl_ldflags=""
+AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libxenctrl_cppflags="-I$withval/include"
+ with_libxenctrl_ldflags="-L$withval/lib"
+ with_libxenctrl="yes"
+ else
+ with_libxenctrl="$withval"
+ fi
+],
+[
+ with_libxenctrl="yes"
+])
+if test "x$with_libxenctrl" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+
+ AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libxenctrl" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+ LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
+
+ #Xen versions older than 3.4 has no xc_getcpuinfo()
+ AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], [])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
# --with-libxmms {{{
with_xmms_config="xmms-config"
with_xmms_cflags=""
plugin_vmem="no"
plugin_vserver="no"
plugin_wireless="no"
+plugin_xencpu="no"
plugin_zfs_arc="no"
plugin_zone="no"
plugin_zookeeper="no"
plugin_virt="yes"
fi
+if test "x$with_libxenctrl" = "xyes"
+then
+ plugin_xencpu="yes"
+fi
m4_divert_once([HELP_ENABLE], [
collectd plugins:])
AC_PLUGIN([write_riemann], [$with_riemann_c], [Riemann output plugin])
AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
+AC_PLUGIN([xencpu], [$plugin_xencpu], [Xen Host CPU usage])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics])
AC_PLUGIN([zone], [$plugin_zone], [Solaris container statistics])
libupsclient . . . . $with_libupsclient
libvarnish . . . . . $with_libvarnish
libvirt . . . . . . . $with_libvirt
+ libxenctrl . . . . . $with_libxenctrl
libxml2 . . . . . . . $with_libxml2
libxmms . . . . . . . $with_libxmms
libyajl . . . . . . . $with_libyajl
write_riemann . . . . $enable_write_riemann
write_sensu . . . . . $enable_write_sensu
write_tsdb . . . . . $enable_write_tsdb
+ xencpu . . . . . . . $enable_xencpu
xmms . . . . . . . . $enable_xmms
zfs_arc . . . . . . . $enable_zfs_arc
zone . . . . . . . . $enable_zone
--- /dev/null
+/**
+ * collectd - src/xencpu.c
+ * Copyright (C) 2016 Pavel Rochnyak
+ *
+ * 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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Pavel Rochnyak <pavel2000 ngs.ru>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <xenctrl.h>
+
+#ifdef XENCTRL_HAS_XC_INTERFACE
+
+//Xen-4.1+
+#define XC_INTERFACE_INIT_ARGS NULL,NULL,0
+xc_interface *xc_handle;
+
+#else /* XENCTRL_HAS_XC_INTERFACE */
+
+//For xen-3.4/xen-4.0
+#include <string.h>
+#define xc_strerror(xc_interface, errcode) strerror(errcode)
+#define XC_INTERFACE_INIT_ARGS
+typedef int xc_interface;
+xc_interface xc_handle = 0;
+
+#endif /* XENCTRL_HAS_XC_INTERFACE */
+
+uint32_t num_cpus = 0;
+xc_cpuinfo_t *cpu_info;
+static value_to_rate_state_t *cpu_states;
+
+static int xencpu_init (void)
+{
+ xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS);
+ if (!xc_handle)
+ {
+ ERROR ("xencpu: xc_interface_open() failed");
+ return (-1);
+ };
+
+ xc_physinfo_t *physinfo;
+
+ physinfo = calloc(1, sizeof(xc_physinfo_t));
+ if (physinfo == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for physinfo failed.");
+ xc_interface_close(xc_handle);
+ return (ENOMEM);
+ }
+
+ if (xc_physinfo(xc_handle, physinfo) < 0)
+ {
+ ERROR ("xencpu plugin: xc_physinfo() failed");
+ xc_interface_close(xc_handle);
+ free(physinfo);
+ return (-1);
+ };
+
+ num_cpus = physinfo->nr_cpus;
+ free(physinfo);
+
+ INFO ("xencpu plugin: Found %"PRIu32" processors.", num_cpus);
+
+ cpu_info = calloc(num_cpus, sizeof(xc_cpuinfo_t));
+ if (cpu_info == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for num_cpus failed.");
+ xc_interface_close(xc_handle);
+ return (ENOMEM);
+ }
+
+ cpu_states = calloc (num_cpus, sizeof (value_to_rate_state_t));
+ if (cpu_states == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for cpu_states failed.");
+ xc_interface_close(xc_handle);
+ free(cpu_info);
+ return (ENOMEM);
+ }
+
+ return (0);
+} /* static int xencpu_init */
+
+static int xencpu_shutdown (void)
+{
+ free(cpu_states);
+ free(cpu_info);
+ xc_interface_close(xc_handle);
+
+ return 0;
+} /* static int xencpu_shutdown */
+
+static void submit_value (int cpu_num, gauge_t percent)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].gauge = percent;
+
+ vl.values = values;
+ vl.values_len = 1;
+
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "xencpu", sizeof (vl.plugin));
+ sstrncpy (vl.type, "percent", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "load", sizeof (vl.type_instance));
+
+ if (cpu_num >= 0) {
+ ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+ "%i", cpu_num);
+ }
+ plugin_dispatch_values (&vl);
+} /* static void submit_value */
+
+static int xencpu_read (void)
+{
+ cdtime_t now = cdtime ();
+
+ int rc, nr_cpus;
+
+ rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus);
+ if (rc < 0) {
+ ERROR ("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, xc_strerror(xc_handle,errno));
+ return (-1);
+ }
+
+ int cpu, status;
+ for (cpu = 0; cpu < nr_cpus; cpu++) {
+ gauge_t rate = NAN;
+ value_t value = {.derive = cpu_info[cpu].idletime};
+
+ status = value_to_rate (&rate, value, DS_TYPE_DERIVE, now, &cpu_states[cpu]);
+ if (status == 0) {
+ submit_value(cpu, 100 - rate/10000000);
+ }
+ }
+
+ return (0);
+} /* static int xencpu_read */
+
+void module_register (void)
+{
+ plugin_register_init ("xencpu", xencpu_init);
+ plugin_register_read ("xencpu", xencpu_read);
+ plugin_register_shutdown ("xencpu", xencpu_shutdown);
+} /* void module_register */