# tests stuff
src/tests/.deps/
src/tests/mock/.deps/
+
+# new daemon repo
+src/daemon/.deps/
+src/daemon/.dirstamp
+src/daemon/collectd
Kevin Bowling <kbowling at llnw.com>
- write_tsdb plugin for http://opentsdb.net/
+Kimo Rosenbaum <kimor79 at yahoo.com>
+ - openldap plugin.
+
Kris Nielander <nielander at fox-it.com>
- tail_csv plugin.
- RPM specfile update.
- libmnl support in the netlink plugin.
- linux support in the zfs_arc plugin.
+ - openldap plugin.
Marco Chiappero <marco at absence.it>
- uptime plugin.
- SMF manifest for collectd.
Richard W. M. Jones <rjones at redhat.com>
- - libvirt plugin.
+ - virt plugin.
- uuid plugin.
Roman Klesel <roman.klesel at noris.de>
- python plugin.
Tim Laszlo <tim.laszlo at gmail.com>
- - drbd plugin
+ - drbd plugin.
Thomas Meson <zllak at hycik.org>
- Graphite support for the AMQP plugin.
Tommie Gannert <d00-tga at d.kth.se>
- PID-file patch.
+Vincent Bernat <vincent at bernat.im>
+ - smart plugin.
+
Vincent Stehlé <vincent.stehle at free.fr>
- hddtemp plugin.
Detailed CPU statistics of the “Logical Partitions” virtualization
technique built into IBM's POWER processors.
- - libvirt
- CPU, memory, disk and network I/O statistics from virtual machines.
-
- lvm
Size of “Logical Volumes” (LV) and “Volume Groups” (VG) of Linux'
“Logical Volume Manager” (LVM).
Read onewire sensors using the owcapu library of the owfs project.
Please read in collectd.conf(5) why this plugin is experimental.
+ - openldap
+ Read monitoring information from OpenLDAP's cn=Monitor subtree.
+
- openvpn
RX and TX of each client in openvpn-status.log (status-version 2).
<http://openvpn.net/index.php/documentation/howto.html>
to have its measurements fed to collectd. This includes multimeters,
sound level meters, thermometers, and much more.
+ - smart
+ Collect SMART statistics, notably load cycle count, temperature
+ and bad sectors.
+
- snmp
Read values from SNMP (Simple Network Management Protocol) enabled
network devices such as switches, routers, thermometers, rack monitoring
- varnish
Various statistics from Varnish, an HTTP accelerator.
+ - virt
+ CPU, memory, disk and network I/O statistics from virtual machines.
+
- vmem
Virtual memory statistics, e. g. the number of page-ins/-outs or the
number of pagefaults.
particular.
<http://developer.apple.com/corefoundation/>
+ * libatasmart (optional)
+ Used by the `smart' plugin.
+ <http://git.0pointer.de/?p=libatasmart.git>
+
* libclntsh (optional)
Used by the `oracle' plugin.
- * libcredis (optional)
- Used by the `redis' plugin. Please note that you require a 0.2.2 version
- or higher. <http://code.google.com/p/credis/>
+ * libhiredis (optional)
+ Used by the redis plugin. Please note that you require a 0.10.0 version
+ or higher. <https://github.com/redis/hiredis>
* libcurl (optional)
If you want to use the `apache', `ascent', `bind', `curl', `curl_json',
libjvm” below.
<http://openjdk.java.net/> (and others)
+ * libldap (optional)
+ Used by the `openldap' plugin.
+ <http://www.openldap.org/>
+
* liblvm2 (optional)
Used by the `lvm' plugin.
<ftp://sources.redhat.com/pub/lvm2/>
* libxml2 (optional)
Parse XML data. This is needed for the `ascent', `bind', `curl_xml' and
- `libvirt' plugins.
+ `virt' plugins.
<http://xmlsoft.org/>
* libxmms (optional)
#endif
])
-AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h locale.h)
+AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h sys/vmmeter.h kvm.h wordexp.h locale.h)
# For the dns plugin
AC_CHECK_HEADERS(arpa/nameser.h)
# undef _LARGEFILE64_SOURCE
#endif
#include <sys/stat.h>
+#include <sys/param.h>
#include <sys/swap.h>
+#include <unistd.h>
]]],
[[[
int num = swapctl(0, NULL);
# undef _LARGEFILE64_SOURCE
#endif
#include <sys/stat.h>
+#include <sys/param.h>
#include <sys/swap.h>
+#include <unistd.h>
]]],
[[[
int num = swapctl(0, NULL, 0);
#include <sys/user.h>
])
-AC_CHECK_MEMBERS([struct kinfo_proc.kp_proc, struct kinfo_proc.kp_eproc],
+AC_CHECK_MEMBERS([struct kinfo_proc.p_pid, struct kinfo_proc.p_vm_rssize],
[
AC_DEFINE(HAVE_STRUCT_KINFO_PROC_OPENBSD, 1,
[Define if struct kinfo_proc exists in the OpenBSD variant.])
AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
[#define _BSD_SOURCE
+#define _DEFAULT_SOURCE
#if HAVE_STDINT_H
# include <stdint.h>
#endif
])
AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [],
[#define _BSD_SOURCE
+#define _DEFAULT_SOURCE
#if HAVE_STDINT_H
# include <stdint.h>
#endif
AM_CONDITIONAL(BUILD_WITH_LIBAQUAERO5, test "x$with_libaquaero5" = "xyes")
# }}}
-# --with-libcredis {{{
-AC_ARG_WITH(libcredis, [AS_HELP_STRING([--with-libcredis@<:@=PREFIX@:>@], [Path to libcredis.])],
+# --with-libhiredis {{{
+AC_ARG_WITH(libhiredis, [AS_HELP_STRING([--with-libhiredis@<:@=PREFIX@:>@],
+ [Path to libhiredis.])],
[
if test "x$withval" = "xyes"
then
- with_libcredis="yes"
+ with_libhiredis="yes"
else if test "x$withval" = "xno"
then
- with_libcredis="no"
+ with_libhiredis="no"
else
- with_libcredis="yes"
- LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS -I$withval/include"
- LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS -L$withval/lib"
+ with_libhiredis="yes"
+ LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS -I$withval/include"
+ LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS -L$withval/lib"
fi; fi
],
-[with_libcredis="yes"])
+[with_libhiredis="yes"])
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
-CPPFLAGS="$CPPFLAGS $LIBCREDIS_CPPFLAGS"
-LDFLAGS="$LDFLAGS $LIBCREDIS_LDFLAGS"
+CPPFLAGS="$CPPFLAGS $LIBHIREDIS_CPPFLAGS"
+LDFLAGS="$LDFLAGS $LIBHIREDIS_LDFLAGS"
-if test "x$with_libcredis" = "xyes"
+if test "x$with_libhiredis" = "xyes"
then
- if test "x$LIBCREDIS_CPPFLAGS" != "x"
+ if test "x$LIBHIREDIS_CPPFLAGS" != "x"
then
- AC_MSG_NOTICE([libcredis CPPFLAGS: $LIBCREDIS_CPPFLAGS])
+ AC_MSG_NOTICE([libhiredis CPPFLAGS: $LIBHIREDIS_CPPFLAGS])
fi
- AC_CHECK_HEADERS(credis.h,
- [with_libcredis="yes"],
- [with_libcredis="no (credis.h not found)"])
+ AC_CHECK_HEADERS(hiredis/hiredis.h,
+ [with_libhiredis="yes"],
+ [with_libhiredis="no (hiredis.h not found)"])
fi
-if test "x$with_libcredis" = "xyes"
+if test "x$with_libhiredis" = "xyes"
then
- if test "x$LIBCREDIS_LDFLAGS" != "x"
+ if test "x$LIBHIREDIS_LDFLAGS" != "x"
then
- AC_MSG_NOTICE([libcredis LDFLAGS: $LIBCREDIS_LDFLAGS])
+ AC_MSG_NOTICE([libhiredis LDFLAGS: $LIBHIREDIS_LDFLAGS])
fi
- AC_CHECK_LIB(credis, credis_info,
- [with_libcredis="yes"],
- [with_libcredis="no (symbol 'credis_info' not found)"])
+ AC_CHECK_LIB(hiredis, redisCommand,
+ [with_libhiredis="yes"],
+ [with_libhiredis="no (symbol 'redisCommand' not found)"])
fi
CPPFLAGS="$SAVE_CPPFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
-if test "x$with_libcredis" = "xyes"
+if test "x$with_libhiredis" = "xyes"
then
- BUILD_WITH_LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS"
- BUILD_WITH_LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS"
- AC_SUBST(BUILD_WITH_LIBCREDIS_CPPFLAGS)
- AC_SUBST(BUILD_WITH_LIBCREDIS_LDFLAGS)
+ BUILD_WITH_LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS"
+ BUILD_WITH_LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS"
+ AC_SUBST(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBHIREDIS_LDFLAGS)
fi
-AM_CONDITIONAL(BUILD_WITH_LIBCREDIS, test "x$with_libcredis" = "xyes")
+AM_CONDITIONAL(BUILD_WITH_LIBHIREDIS, test "x$with_libhiredis" = "xyes")
# }}}
# --with-libcurl {{{
AM_CONDITIONAL(BUILD_WITH_JAVA, test "x$with_java" = "xyes")
# }}}
+# --with-libldap {{{
+AC_ARG_WITH(libldap, [AS_HELP_STRING([--with-libldap@<:@=PREFIX@:>@], [Path to libldap.])],
+[
+ if test "x$withval" = "xyes"
+ then
+ with_libldap="yes"
+ else if test "x$withval" = "xno"
+ then
+ with_libldap="no"
+ else
+ with_libldap="yes"
+ LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS -I$withval/include"
+ LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS -L$withval/lib"
+ fi; fi
+],
+[with_libldap="yes"])
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+
+CPPFLAGS="$CPPFLAGS $LIBLDAP_CPPFLAGS"
+LDFLAGS="$LDFLAGS $LIBLDAP_LDFLAGS"
+
+if test "x$with_libldap" = "xyes"
+then
+ if test "x$LIBLDAP_CPPFLAGS" != "x"
+ then
+ AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS])
+ fi
+ AC_CHECK_HEADERS(ldap.h,
+ [with_libldap="yes"],
+ [with_libldap="no ('ldap.h' not found)"])
+fi
+if test "x$with_libldap" = "xyes"
+then
+ if test "x$LIBLDAP_LDFLAGS" != "x"
+ then
+ AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS])
+ fi
+ AC_CHECK_LIB(ldap, ldap_initialize,
+ [with_libldap="yes"],
+ [with_libldap="no (symbol 'ldap_initialize' not found)"])
+
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+if test "x$with_libldap" = "xyes"
+then
+ BUILD_WITH_LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS"
+ BUILD_WITH_LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS"
+ AC_SUBST(BUILD_WITH_LIBLDAP_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBLDAP_LDFLAGS)
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes")
+# }}}
+
# --with-liblvm2app {{{
with_liblvm2app_cppflags=""
with_liblvm2app_ldflags=""
LDFLAGS="$SAVE_LDFLAGS"
fi
+if test "x$with_libstatgrab" = "xyes"
+then
+ SAVE_CFLAGS="$CFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+
+ CFLAGS="$CFLAGS $with_libstatgrab_cflags"
+ LDFLAGS="$LDFLAGS $with_libstatgrab_ldflags"
+
+ AC_CACHE_CHECK([if libstatgrab >= 0.90],
+ [c_cv_have_libstatgrab_0_90],
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[[
+#include <stdio.h>
+#include <statgrab.h>
+]]],
+[[[
+ if (sg_init()) return 0;
+]]]
+ )],
+ [c_cv_have_libstatgrab_0_90="no"],
+ [c_cv_have_libstatgrab_0_90="yes"]
+ )
+ )
+
+ CFLAGS="$SAVE_CFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes")
if test "x$with_libstatgrab" = "xyes"
then
BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags"
AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS)
AC_SUBST(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+ if test "x$c_cv_have_libstatgrab_0_90" = "xyes"
+ then
+ AC_DEFINE(HAVE_LIBSTATGRAB_0_90, 1, [Define to 1 if libstatgrab version >= 0.90])
+ fi
fi
# }}}
if test "x$with_libvarnish" = "xyes"
then
SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
- AC_CHECK_HEADERS(varnish/varnishapi.h, [], [with_libvarnish="no (varnish/varnishapi.h not found)"])
-
- CPPFLAGS="$SAVE_CPPFLAGS"
-fi
-if test "x$with_libvarnish" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- #SAVE_LDFLAGS="$LDFLAGS"
CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
- #LDFLAGS="$LDFLAGS $with_libvarnish_libs"
- AC_CHECK_HEADERS(varnish/vsc.h,
- [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])],
- [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])])
+ AC_CHECK_HEADERS(varnish/vapi/vsc.h,
+ [AC_DEFINE([HAVE_VARNISH_V4], [1], [Varnish 4 API support])],
+ [AC_CHECK_HEADERS(varnish/vsc.h,
+ [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])],
+ [AC_CHECK_HEADERS(varnish/varnishapi.h,
+ [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])],
+ [with_libvarnish="no (found none of the varnish header files)"])])])
CPPFLAGS="$SAVE_CPPFLAGS"
- #LDFLAGS="$SAVE_LDFLAGS"
fi
if test "x$with_libvarnish" = "xyes"
then
fi
# }}}
+# --with-libatasmart {{{
+with_libatasmart_cppflags=""
+with_libatasmart_ldflags=""
+AC_ARG_WITH(libatasmart, [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libatasmart_cppflags="-I$withval/include"
+ with_libatasmart_ldflags="-L$withval/lib"
+ with_libatasmart="yes"
+ else
+ with_libatasmart="$withval"
+ fi
+],
+[
+ if test "x$ac_system" = "xLinux"
+ then
+ with_libatasmart="yes"
+ else
+ with_libatasmart="no (Linux only library)"
+ fi
+])
+if test "x$with_libatasmart" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
+
+ AC_CHECK_HEADERS(atasmart.h, [with_libatasmart="yes"], [with_libatasmart="no (atasmart.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libatasmart" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
+ LDFLAGS="$LDFLAGS $with_libatasmart_ldflags"
+
+ AC_CHECK_LIB(atasmart, sk_disk_open, [with_libatasmart="yes"], [with_libatasmart="no (Symbol 'sk_disk_open' not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libatasmart" = "xyes"
+then
+ BUILD_WITH_LIBATASMART_CPPFLAGS="$with_libatasmart_cppflags"
+ BUILD_WITH_LIBATASMART_LDFLAGS="$with_libatasmart_ldflags"
+ BUILD_WITH_LIBATASMART_LIBS="-latasmart"
+ AC_SUBST(BUILD_WITH_LIBATASMART_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBATASMART_LDFLAGS)
+ AC_SUBST(BUILD_WITH_LIBATASMART_LIBS)
+ AC_DEFINE(HAVE_LIBATASMART, 1, [Define if libatasmart is present and usable.])
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBATASMART, test "x$with_libatasmart" = "xyes")
+# }}}
+
PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
[with_libnotify="yes"],
[if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
plugin_processes="yes"
fi
+if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_openbsd" = "xyes"
+then
+ plugin_processes="yes"
+fi
+
if test "x$with_kvm_getswapinfo" = "xyes"
then
plugin_swap="yes"
AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
AC_PLUGIN([olsrd], [yes], [olsrd statistics])
AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
+AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
AC_PLUGIN([python], [$with_python], [Embed a Python interpreter])
-AC_PLUGIN([redis], [$with_libcredis], [Redis plugin])
+AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin])
AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
AC_PLUGIN([serial], [$plugin_serial], [serial port traffic])
AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
+AC_PLUGIN([smart], [$with_libatasmart], [SMART statistics])
AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
AC_PLUGIN([statsd], [yes], [StatsD plugin])
AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin])
AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
-AC_PLUGIN([write_redis], [$with_libcredis], [Redis output plugin])
+AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
AC_PLUGIN([write_riemann], [$have_protoc_c], [Riemann output plugin])
AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
Libraries:
intel mic . . . . . . $with_mic
libaquaero5 . . . . . $with_libaquaero5
+ libatasmart . . . . . $with_libatasmart
libcurl . . . . . . . $with_libcurl
libdbi . . . . . . . $with_libdbi
- libcredis . . . . . . $with_libcredis
+ libhiredis . . . . . $with_libhiredis
libesmtp . . . . . . $with_libesmtp
libganglia . . . . . $with_libganglia
libgcrypt . . . . . . $with_libgcrypt
libjvm . . . . . . . $with_java
libkstat . . . . . . $with_kstat
libkvm . . . . . . . $with_libkvm
+ libldap . . . . . . . $with_libldap
liblvm2app . . . . . $with_liblvm2app
libmemcached . . . . $with_libmemcached
libmnl . . . . . . . $with_libmnl
nut . . . . . . . . . $enable_nut
olsrd . . . . . . . . $enable_olsrd
onewire . . . . . . . $enable_onewire
+ openldap . . . . . . $enable_openldap
openvpn . . . . . . . $enable_openvpn
oracle . . . . . . . $enable_oracle
perl . . . . . . . . $enable_perl
sensors . . . . . . . $enable_sensors
serial . . . . . . . $enable_serial
sigrok . . . . . . . $enable_sigrok
+ smart . . . . . . . . $enable_smart
snmp . . . . . . . . $enable_snmp
statsd . . . . . . . $enable_statsd
swap . . . . . . . . $enable_swap
%{?el6:%global _has_libmodbus 1}
%{?el6:%global _has_libudev 1}
%{?el6:%global _has_iproute 1}
+%{?el6:%global _has_atasmart 1}
%{?el7:%global _has_libyajl 1}
%{?el7:%global _has_recent_libpcap 1}
%{?el7:%global _has_varnish4 1}
%{?el7:%global _has_broken_libmemcached 1}
%{?el7:%global _has_iproute 1}
+%{?el7:%global _has_atasmart 1}
# plugins enabled by default
%define with_aggregation 0%{!?_without_aggregation:1}
%define with_ipvs 0%{!?_without_ipvs:0%{?_has_ip_vs_h}}
%define with_irq 0%{!?_without_irq:1}
%define with_java 0%{!?_without_java:1}
-%define with_libvirt 0%{!?_without_libvirt:1}
+%define with_virt 0%{!?_without_virt:1}
%define with_load 0%{!?_without_load:1}
%define with_logfile 0%{!?_without_logfile:1}
%define with_log_logstash 0%{!?_without_log_logstash:0%{?_has_libyajl}}
%define with_numa 0%{!?_without_numa:1}
%define with_nut 0%{!?_without_nut:1}
%define with_olsrd 0%{!?_without_olsrd:1}
+%define with_openldap 0%{!?_without_openldap:1}
%define with_openvpn 0%{!?_without_openvpn:1}
%define with_perl 0%{!?_without_perl:1}
%define with_pinba 0%{!?_without_pinba:1}
%define with_rrdtool 0%{!?_without_rrdtool:1}
%define with_sensors 0%{!?_without_sensors:1}
%define with_serial 0%{!?_without_serial:1}
+%define with_smart 0%{!?_without_smart:0%{?_has_atasmart}}
%define with_snmp 0%{!?_without_snmp:1}
%define with_statsd 0%{!?_without_statsd:1}
%define with_swap 0%{!?_without_swap:1}
in an embedded JVM.
%endif
-%if %{with_libvirt}
-%package libvirt
-Summary: Libvirt plugin for collectd
-Group: System Environment/Daemons
-Requires: %{name}%{?_isa} = %{version}-%{release}
-BuildRequires: libvirt-devel
-%description libvirt
-This plugin collects information from virtualized guests.
-%endif
-
%if %{with_log_logstash}
%package log_logstash
Summary: log_logstash plugin for collectd
This plugin for collectd provides Network UPS Tools support.
%endif
+%if %{with_openldap}
+%package openldap
+Summary: Openldap plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: openldap-devel
+%description openldap
+This plugin reads monitoring information from OpenLDAP's cn=Monitor subtree.
+%endif
+
%if %{with_perl}
%package perl
Summary: Perl plugin for collectd
thermometers, and much more.
%endif
+%if %{with_smart}
+%package smart
+Summary: SMART plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: libatasmart-devel
+%description smart
+Collect SMART statistics, notably load cycle count, temperature and bad
+sectors.
+%endif
+
%if %{with_snmp}
%package snmp
Summary: SNMP plugin for collectd
The Varnish plugin collects information about Varnish, an HTTP accelerator.
%endif
+%if %{with_virt}
+%package virt
+Summary: Virt plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: libvirt-devel
+%description virt
+This plugin collects information from virtualized guests.
+%endif
+
%if %{with_write_http}
%package write_http
Summary: Write-HTTP plugin for collectd
%define _with_java --disable-java
%endif
-%if %{with_libvirt}
-%define _with_libvirt --enable-libvirt
+%if %{with_virt}
+%define _with_virt --enable-virt
%else
-%define _with_libvirt --disable-libvirt
+%define _with_virt --disable-virt
%endif
%if %{with_load}
%define _with_onewire --disable-onewire
%endif
+%if %{with_openldap}
+%define _with_openldap --enable-openldap
+%else
+%define _with_openldap --disable-openldap
+%endif
+
%if %{with_openvpn}
%define _with_openvpn --enable-openvpn
%else
%define _with_sigrok --disable-sigrok
%endif
+%if %{with_smart}
+%define _with_smart --enable-smart
+%else
+%define _with_smart --disable-smart
+%endif
+
%if %{with_snmp}
%define _with_snmp --enable-snmp
%else
%{?_with_iptables} \
%{?_with_ipvs} \
%{?_with_java} \
- %{?_with_libvirt} \
+ %{?_with_virt} \
%{?_with_log_logstash} \
%{?_with_lpar} \
%{?_with_lvm} \
%{?_with_notify_email} \
%{?_with_nut} \
%{?_with_onewire} \
+ %{?_with_openldap} \
%{?_with_oracle} \
%{?_with_perl} \
%{?_with_pf} \
%{?_with_rrdtool} \
%{?_with_sensors} \
%{?_with_sigrok} \
+ %{?_with_smart} \
%{?_with_snmp} \
%{?_with_tape} \
%{?_with_tokyotyrant} \
%{_mandir}/man5/collectd-java.5*
%endif
-%if %{with_libvirt}
-%files libvirt
-%{_libdir}/%{name}/libvirt.so
+%if %{with_virt}
+%files virt
+%{_libdir}/%{name}/virt.so
%endif
%if %{with_log_logstash}
%{_libdir}/%{name}/nut.so
%endif
+%if %{with_openldap}
+%files openldap
+%{_libdir}/%{name}/openldap.so
+%endif
+
%if %{with_perl}
%files perl
%doc perl-examples/*
%{_libdir}/%{name}/sigrok.so
%endif
+%if %{with_smart}
+%files smart
+%{_libdir}/%{name}/smart.so
+%endif
+
%if %{with_snmp}
%files snmp
%{_mandir}/man5/collectd-snmp.5*
%changelog
# * TODO 5.5.0-1
# - New upstream version
-# - New plugins enabled by default: drbd, log_logstash, write_tsdb
+# - New plugins enabled by default: drbd, log_logstash, write_tsdb, smart, openldap
# - New plugins disabled by default: barometer, write_kafka
# - Enable zfs_arc, now supported on Linux
# - Install disk plugin in an dedicated package, as it depends on libudev
--- /dev/null
+[Unit]
+Description=Collectd
+After=local-fs.target network.target
+Requires=local-fs.target network.target
+
+[Service]
+ExecStart=/usr/sbin/collectd
+
+# Tell systemd it will receive a notification from collectd over it's control
+# socket once the daemon is ready. See systemd.service(5) for more details.
+Type=notify
+NotifyAccess=main
+
+# Restart the collectd daemon after a 10 seconds delay, in case it crashes.
+Restart=always
+RestartSec=10
+
+# Send all console messages to syslog.
+StandardOutput=syslog
+StandardError=syslog
+
+[Install]
+WantedBy=multi-user.target
# these cannot be started at boot time by the system without
# arcane trickery. Also a root user will not see these tasks/jobs
# by default. set*id is a reasonable and secure compromise.
+# These options are not supported on early upstart versions.
#setuid nobody
#setgid nobody
# shell commands via `sh -e`.
env DAEMON=/usr/sbin/collectd
-# Tell upstart to watch for forking when tracking the pid for us.
-expect fork
+# Tell upstart to wait for collectd to SIGSTOP itself, signaling it is ready
+# to run.
+expect stop
# prevent thrashing - 10 restarts in 5 seconds
respawn
respawn limit 10 5
-# Make a log available in /var/log/upstart/collectd.log
-console log
+# Uncomment to make a log available in /var/log/upstart/collectd.log
+# (not supported on early upstart versions).
+#console log
# The daemon will not start if the configuration is invalid.
pre-start exec $DAEMON -t
collectdmon_CPPFLAGS = $(AM_CPPFLAGS)
collectd_nagios_SOURCES = collectd-nagios.c
-collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd
+collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
collectd_nagios_LDADD =
if BUILD_WITH_LIBSOCKET
collectd_nagios_LDADD += -lsocket
collectdctl_SOURCES = collectdctl.c
-collectdctl_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd
+collectdctl_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
collectdctl_LDADD =
if BUILD_WITH_LIBSOCKET
collectdctl_LDADD += -lsocket
collectd_tg_SOURCES = collectd-tg.c \
daemon/utils_heap.c daemon/utils_heap.h
-collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd
+collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
collectd_tg_LDADD =
if BUILD_WITH_LIBSOCKET
collectd_tg_LDADD += -lsocket
if BUILD_AIX
collectd_tg_LDADD += -lm
endif
+if BUILD_WITH_LIBPTHREAD
+collectd_tg_LDADD += -lpthread
+endif
collectd_tg_LDADD += libcollectdclient/libcollectdclient.la
collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la
aggregation_la_SOURCES = aggregation.c \
utils_vl_lookup.c utils_vl_lookup.h
aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-aggregation_la_LIBADD =
+aggregation_la_LIBADD = -lm
endif
if BUILD_PLUGIN_AMQP
onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
+if BUILD_PLUGIN_OPENLDAP
+pkglib_LTLIBRARIES += openldap.la
+openldap_la_SOURCES = openldap.c
+openldap_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBLDAP_LDFLAGS)
+openldap_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS)
+openldap_la_LIBADD = -lldap
+endif
+
if BUILD_PLUGIN_OPENVPN
pkglib_LTLIBRARIES += openvpn.la
openvpn_la_SOURCES = openvpn.c
if BUILD_PLUGIN_REDIS
pkglib_LTLIBRARIES += redis.la
redis_la_SOURCES = redis.c
-redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBCREDIS_LDFLAGS)
-redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS)
-redis_la_LIBADD = -lcredis
+redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
+redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
+redis_la_LIBADD = -lhiredis
endif
if BUILD_PLUGIN_ROUTEROS
sigrok_la_LIBADD = -lsigrok
endif
+if BUILD_PLUGIN_SMART
+if BUILD_WITH_LIBUDEV
+pkglib_LTLIBRARIES += smart.la
+smart_la_SOURCES = smart.c \
+ utils_ignorelist.c utils_ignorelist.h
+smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS)
+smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS)
+smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev
+endif
+endif
+
if BUILD_PLUGIN_SNMP
pkglib_LTLIBRARIES += snmp.la
snmp_la_SOURCES = snmp.c
if BUILD_PLUGIN_WRITE_REDIS
pkglib_LTLIBRARIES += write_redis.la
write_redis_la_SOURCES = write_redis.c
-write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBCREDIS_LDFLAGS)
-write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS)
-write_redis_la_LIBADD = -lcredis
+write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
+write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
+write_redis_la_LIBADD = -lhiredis
endif
if BUILD_PLUGIN_WRITE_RIEMANN
check_PROGRAMS = test_common test_utils_avltree test_utils_heap test_utils_mount test_utils_vl_lookup
test_common_SOURCES = tests/test_common.c \
- common.h common.c \
+ daemon/common.h daemon/common.c \
tests/mock/plugin.c \
tests/mock/utils_cache.c \
tests/mock/utils_time.c
test_common_LDADD =
test_utils_avltree_SOURCES = tests/test_utils_avltree.c \
- utils_avltree.c utils_avltree.h
+ daemon/utils_avltree.c daemon/utils_avltree.h
test_utils_avltree_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL)
test_utils_avltree_LDFLAGS = -export-dynamic
test_utils_avltree_LDADD =
test_utils_heap_SOURCES = tests/test_utils_heap.c \
- utils_heap.c utils_heap.h
+ daemon/utils_heap.c daemon/utils_heap.h
test_utils_heap_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL)
test_utils_heap_LDFLAGS = -export-dynamic
test_utils_heap_LDADD =
test_utils_mount_SOURCES = tests/test_utils_mount.c \
utils_mount.c utils_mount.h \
- common.c common.h \
+ daemon/common.c daemon/common.h \
tests/mock/plugin.c \
tests/mock/utils_cache.c \
tests/mock/utils_time.c
test_utils_vl_lookup_SOURCES = tests/test_utils_vl_lookup.c \
utils_vl_lookup.h utils_vl_lookup.c \
- utils_avltree.c utils_avltree.h \
- common.c common.h \
+ daemon/utils_avltree.c daemon/utils_avltree.h \
+ daemon/common.c daemon/common.h \
tests/mock/plugin.c \
tests/mock/utils_cache.c \
tests/mock/utils_time.c
battery_submit ("0", "current", current);
if (!isnan (voltage))
battery_submit ("0", "voltage", voltage);
+
+ return (0);
} /* }}} int battery_read */
/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
The callback will be called without arguments.
-=item register_read(callback[, interval][, data][, name]) -> identifier
+=item register_read(callback[, interval][, data][, name]) -> I<identifier>
This function takes an additional parameter: I<interval>. It specifies the
time between calls to the callback function.
or a callback function. The identifier will be constructed in the same way as
for the register functions.
-=item B<flush>(I<plugin[, I<timeout>][, I<identifier>]) -> None
+=item B<get_dataset>(I<name>) -> I<definition>
+
+Returns the definition of a dataset specified by I<name>. I<definition> is a list
+of tuples, each representing one data source. Each tuple has 4 values:
+
+=over 4
+
+=item name
+
+A string, the name of the data source.
+
+=item type
+
+A string that is equal to either of the variables B<DS_TYPE_COUNTER>,
+B<DS_TYPE_GAUGE>, B<DS_TYPE_DERIVE> or B<DS_TYPE_ABSOLUTE>.
+
+=item min
+
+A float or None, the minimum value.
+
+=item max
+
+A float or None, the maximum value.
+
+=back
+
+=item B<flush>(I<plugin>[, I<timeout>][, I<identifier>]) -> None
Flush one or all plugins. I<timeout> and the specified I<identifiers> are
passed on to the registered flush-callbacks. If omitted, the timeout defaults
#@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
#@BUILD_PLUGIN_OLSRD_TRUE@LoadPlugin olsrd
#@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
+#@BUILD_PLUGIN_OPENLDAP_TRUE@LoadPlugin openldap
#@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
#@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
#@BUILD_PLUGIN_PERL_TRUE@<LoadPlugin perl>
#@BUILD_PLUGIN_SENSORS_TRUE@LoadPlugin sensors
#@BUILD_PLUGIN_SERIAL_TRUE@LoadPlugin serial
#@BUILD_PLUGIN_SIGROK_TRUE@LoadPlugin sigrok
+#@BUILD_PLUGIN_SMART_TRUE@LoadPlugin smart
#@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
#@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
#@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
# IgnoreSelected false
#</Plugin>
+#<Plugin openldap>
+# <Instance "localhost">
+# URL "ldap://localhost:389"
+# StartTLS false
+# VerifyHost true
+# CACert "/path/to/ca.crt"
+# Timeout -1
+# Version 3
+# </Instance>
+#</Plugin>
+
#<Plugin openvpn>
# StatusFile "/etc/openvpn/openvpn-status.log"
# ImprovedNamingSchema false
# </Device>
#</Plugin>
+#<Plugin smart>
+# Disk "/^[hs]d[a-f][0-9]?$/"
+# IgnoreSelected false
+#</Plugin>
+
#<Plugin snmp>
# <Data "powerplus_voltge_input">
# Type "voltage"
#<Plugin tcpconns>
# ListeningPorts false
+# AllPortsSummary false
# LocalPort "25"
# RemotePort "25"
#</Plugin>
# If you prefer defining another instance you can do
# so by using <Instance "myinstance">
# <Instance>
-# CollectCache true
# CollectBackend true
-# CollectBan false # Varnish 3 only
+# CollectBan false # Varnish 3 and above
+# CollectCache true
# CollectConnections true
# CollectDirectorDNS false # Varnish 3 only
-# CollectSHM true
# CollectESI false
# CollectFetch false
# CollectHCB false
# CollectObjects false
# CollectPurge false # Varnish 2 only
# CollectSession false
+# CollectSHM true
# CollectSMA false # Varnish 2 only
# CollectSMS false
# CollectSM false # Varnish 2 only
# CollectStruct false
# CollectTotals false
-# CollectUptime false
+# CollectUptime false # Varnish 3 and above
# CollectVCL false
+# CollectVSM false # Varnish 4 only
# CollectWorkers false
# </Instance>
#</Plugin>
BaseDir "/var/lib/collectd"
PIDFile "/run/collectd.pid"
Interval 10.0
-
+
LoadPlugin cpu
LoadPlugin load
-
+
<LoadPlugin df>
Interval 3600
</LoadPlugin>
<Plugin df>
ValuesPercentage true
</Plugin>
-
+
LoadPlugin ping
<Plugin ping>
Host "example.org"
change, though this is unlikely. Oh, and if you want to help improving this
plugin, just send a short notice to the mailing list. ThanksE<nbsp>:)
+=head2 Plugin C<openldap>
+
+To use the C<openldap> plugin you first need to configure the I<OpenLDAP>
+server correctly. The backend database C<monitor> needs to be loaded and
+working. See slapd-monitor(5) for the details.
+
+The configuration of the C<openldap> plugin consists of one or more B<Instance>
+blocks. Each block requires one string argument as the instance name. For
+example:
+
+ <Plugin "openldap">
+ <Instance "foo">
+ URL "ldap://localhost/"
+ </Instance>
+ <Instance "bar">
+ URL "ldaps://localhost/"
+ </Instance>
+ </Plugin>
+
+The instance name will be used as the I<plugin instance>. To emulate the old
+(versionE<nbsp>4) behavior, you can use an empty string (""). In order for the
+plugin to work correctly, each instance name must be unique. This is not
+enforced by the plugin and it is your responsibility to ensure it is.
+
+The following options are accepted within each B<Instance> block:
+
+=over 4
+
+=item B<URL> I<ldap://host/binddn>
+
+Sets the URL to use to connect to the I<OpenLDAP> server. This option is
+I<mandatory>.
+
+=item B<StartTLS> B<true|false>
+
+Defines whether TLS must be used when connecting to the I<OpenLDAP> server.
+Disabled by default.
+
+=item B<VerifyHost> B<true|false>
+
+Enables or disables peer host name verification. If enabled, the plugin checks
+if the C<Common Name> or a C<Subject Alternate Name> field of the SSL
+certificate matches the host name provided by the B<URL> option. If this
+identity check fails, the connection is aborted. Enabled by default.
+
+=item B<CACert> I<File>
+
+File that holds one or more SSL certificates. If you want to use TLS/SSL you
+may possibly need this option. What CA certificates are checked by default
+depends on the distribution you use and can be changed with the usual ldap
+client configuration mechanisms. See ldap.conf(5) for the details.
+
+=item B<Timeout> I<Seconds>
+
+Sets the timeout value for ldap operations. Defaults to B<-1> which results in
+an infinite timeout.
+
+=item B<Version> I<Version>
+
+An integer which sets the LDAP protocol version number to use when connecting
+to the I<OpenLDAP> server. Defaults to B<3> for using I<LDAPv3>.
+
+=back
+
=head2 Plugin C<openvpn>
The OpenVPN plugin reads a status file maintained by OpenVPN and gathers
=back
+=head2 Plugin C<smart>
+
+The C<smart> plugin collects SMART information from physical
+disks. Values collectd include temperature, power cycle count, poweron
+time and bad sectors. Also, all SMART attributes are collected along
+with the normalized current value, the worst value, the threshold and
+a human readable value.
+
+Using the following two options you can ignore some disks or configure the
+collection only of specific disks.
+
+=over 4
+
+=item B<Disk> I<Name>
+
+Select the disk I<Name>. Whether it is collected or ignored depends on the
+B<IgnoreSelected> setting, see below. As with other plugins that use the
+daemon's ignorelist functionality, a string that starts and ends with a slash
+is interpreted as a regular expression. Examples:
+
+ Disk "sdd"
+ Disk "/hda[34]/"
+
+=item B<IgnoreSelected> B<true>|B<false>
+
+Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
+statements, are ignored or if all other disks are ignored. The behavior
+(hopefully) is intuitive: If no B<Disk> option is configured, all disks are
+collected. If at least one B<Disk> option is given and no B<IgnoreSelected> or
+set to B<false>, B<only> matching disks will be collected. If B<IgnoreSelected>
+is set to B<true>, all disks are collected B<except> the ones matched.
+
+=back
+
=head2 Plugin C<snmp>
Since the configuration of the C<snmp plugin> is a little more complicated than
how many connections a web proxy holds to web servers. You have to give the
port in numeric form.
+=item B<AllPortsSummary> I<true>|I<false>
+
+If this option is set to I<true> a summary of statistics from all connections
+are collectd. This option defaults to I<false>.
+
=back
=head2 Plugin C<thermal>
=head2 Plugin C<varnish>
The I<varnish plugin> collects information about Varnish, an HTTP accelerator.
+It collects a subset of the values displayed by L<varnishstat(1)>, and
+organizes them in categories which can be enabled or disabled. Currently only
+metrics shown in L<varnishstat(1)>'s I<MAIN> section are collected. The exact
+meaning of each metric can be found in L<varnish-counters(7)>.
Synopsis:
<Plugin "varnish">
<Instance "example">
+ CollectBackend true
+ CollectBan false
CollectCache true
CollectConnections true
- CollectBackend true
- CollectSHM true
+ CollectDirectorDNS false
CollectESI false
CollectFetch false
CollectHCB false
+ CollectObjects false
+ CollectPurge false
+ CollectSession false
+ CollectSHM true
CollectSMA false
CollectSMS false
CollectSM false
+ CollectStruct false
CollectTotals false
+ CollectUptime false
+ CollectVCL false
+ CollectVSM false
CollectWorkers false
</Instance>
</Plugin>
=over 4
-=item B<CollectCache> B<true>|B<false>
-
-Cache hits and misses. True by default.
-
-=item B<CollectConnections> B<true>|B<false>
-
-Number of client connections received, accepted and dropped. True by default.
-
=item B<CollectBackend> B<true>|B<false>
Back-end connection statistics, such as successful, reused,
and closed connections. True by default.
-=item B<CollectSHM> B<true>|B<false>
-
-Statistics about the shared memory log, a memory region to store
-log messages which is flushed to disk when full. True by default.
-
=item B<CollectBan> B<true>|B<false>
Statistics about ban operations, such as number of bans added, retired, and
number of objects tested against ban operations. Only available with Varnish
-3.x. False by default.
+3.x and above. False by default.
+
+=item B<CollectCache> B<true>|B<false>
+
+Cache hits and misses. True by default.
+
+=item B<CollectConnections> B<true>|B<false>
+
+Number of client connections received, accepted and dropped. True by default.
=item B<CollectDirectorDNS> B<true>|B<false>
=item B<CollectSession> B<true>|B<false>
Client session statistics. Number of past and current sessions, session herd and
-linger counters, etc. False by default.
+linger counters, etc. False by default. Note that if using Varnish 4.x, some
+metrics found in the Connections and Threads sections with previous versions of
+Varnish have been moved here.
+
+=item B<CollectSHM> B<true>|B<false>
+
+Statistics about the shared memory log, a memory region to store
+log messages which is flushed to disk when full. True by default.
=item B<CollectSMA> B<true>|B<false>
=item B<CollectUptime> B<true>|B<false>
-Varnish uptime. False by default.
+Varnish uptime. Only available with Varnish 3.x and above. False by default.
=item B<CollectVCL> B<true>|B<false>
Number of total (available + discarded) VCL (config files). False by default.
+=item B<CollectVSM> B<true>|B<false>
+
+Collect statistics about Varnish's shared memory usage (used by the logging and
+statistics subsystems). Only available with Varnish 4.x. False by default.
+
=item B<CollectWorkers> B<true>|B<false>
Collect statistics about worker threads. False by default.
=item B<HostnameFormat> B<name|uuid|hostname|...>
-When the libvirt plugin logs data, it sets the hostname of the collected data
+When the virt plugin logs data, it sets the hostname of the collected data
according to this setting. The default is to use the guest name as provided by
the hypervisor, which is equal to setting B<name>.
=item B<InterfaceFormat> B<name>|B<address>
-When the libvirt plugin logs interface data, it sets the name of the collected
+When the virt plugin logs interface data, it sets the name of the collected
data according to this setting. The default is to use the path as provided by
the hypervisor (the "dev" property of the target node), which is equal to
setting B<name>.
=item B<PluginInstanceFormat> B<name|uuid>
-When the libvirt plugin logs data, it sets the plugin_instance of the collected
+When the virt plugin logs data, it sets the plugin_instance of the collected
data according to this setting. The default is to use the guest name as provided
by the hypervisor, which is equal to setting B<name>.
Specify the protocol to use when communicating with I<Riemann>. Defaults to
B<UDP>.
+=item B<Batch> B<true>|B<false>
+
+If set to B<true> and B<Protocol> is set to B<TCP>,
+events will be batched in memory and flushed at
+regular intervals or when B<BatchMaxSize> is exceeded.
+
+Notifications are not batched and sent as soon as possible.
+
+Defaults to false
+
+=item B<BatchMaxSize> I<size>
+
+Maximum payload size for a riemann packet. Defaults to 8192
+
=item B<StoreRates> B<true>|B<false>
If set to B<true> (the default), convert counter values to rates. If set to
Don't fork to the background. I<collectd> will also B<not> close standard file
descriptors, detach from the session nor write a pid file. This is mainly
-thought for 'supervising' init replacements such as I<runit>.
+thought for 'supervising' init replacements such as I<runit>. If using
+I<upstart> or I<systemd> though, starting with version 5.5.0 I<collectd> is
+able to notify these two init replacements, and B<does> require forking to the
+background for process supervision. The F<contrib/> directory has sample
+I<upstart> and I<systemd> configuration files.
=item B<-h>
/* Legacy behavior: Dispatches the raw derive values without any aggregation. */
static void cpu_commit_without_aggregation (void) /* {{{ */
{
- size_t cpu_num;
+ int state;
- for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ for (state = 0; state < CPU_STATE_ACTIVE; state++)
{
- int state;
-
- for (state = 0; state < CPU_STATE_ACTIVE; state++)
- {
- cpu_state_t *s = get_cpu_state (cpu_num, state);
+ size_t cpu_num;
+ if (report_by_cpu) {
+ for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ {
+ cpu_state_t *s = get_cpu_state (cpu_num, state);
- if (!s->has_value)
- continue;
+ if (!s->has_value)
+ continue;
- submit_derive ((int) cpu_num, (int) state, s->conv.last_value.derive);
+ submit_derive ((int) cpu_num, (int) state, s->conv.last_value.derive);
+ }
+ } else {
+ derive_t derive_total = 0;
+ for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ {
+ cpu_state_t *s = get_cpu_state (cpu_num, state);
+
+ if (!s->has_value)
+ continue;
+
+ derive_total += s->conv.last_value.derive;
+
+ }
+ submit_derive (-1, (int) state, derive_total);
}
}
} /* }}} void cpu_commit_without_aggregation */
};
size_t cpu_num;
- if (report_by_cpu && report_by_state && !report_percent)
+ if (report_by_state && !report_percent)
{
cpu_commit_without_aggregation ();
return;
}
for (i = 0; i < numcpu; i++) {
- cpu_state (i, CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER]);
- cpu_state (i, CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE]);
- cpu_state (i, CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS]);
- cpu_state (i, CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE]);
- cpu_state (i, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR]);
+ cpu_stage (i, CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now);
+ cpu_stage (i, CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now);
+ cpu_stage (i, CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now);
+ cpu_stage (i, CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE], now);
+ cpu_stage (i, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR], now);
}
/* }}} #endif CAN_USE_SYSCTL */
}
for (i = 0; i < numcpu; i++) {
- cpu_state (i, CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER]);
- cpu_state (i, CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE]);
- cpu_state (i, CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS]);
- cpu_state (i, CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE]);
- cpu_state (i, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR]);
+ cpu_stage (i, CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now);
+ cpu_stage (i, CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now);
+ cpu_stage (i, CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now);
+ cpu_stage (i, CPU_STATE_IDLE, (derive_t) cpuinfo[i][CP_IDLE], now);
+ cpu_stage (i, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[i][CP_INTR], now);
}
/* }}} #endif HAVE_SYSCTL_KERN_CP_TIMES */
return (-1);
}
- cpu_state (0, CPU_STATE_USER, (derive_t) cpuinfo[CP_USER]);
- cpu_state (0, CPU_STATE_NICE, (derive_t) cpuinfo[CP_NICE]);
- cpu_state (0, CPU_STATE_SYSTEM, (derive_t) cpuinfo[CP_SYS]);
- cpu_state (0, CPU_STATE_IDLE, (derive_t) cpuinfo[CP_IDLE]);
- cpu_state (0, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[CP_INTR]);
+ cpu_stage (0, CPU_STATE_USER, (derive_t) cpuinfo[CP_USER], now);
+ cpu_stage (0, CPU_STATE_NICE, (derive_t) cpuinfo[CP_NICE], now);
+ cpu_stage (0, CPU_STATE_SYSTEM, (derive_t) cpuinfo[CP_SYS], now);
+ cpu_stage (0, CPU_STATE_IDLE, (derive_t) cpuinfo[CP_IDLE], now);
+ cpu_stage (0, CPU_STATE_INTERRUPT, (derive_t) cpuinfo[CP_INTR], now);
/* }}} #endif HAVE_SYSCTLBYNAME */
#elif defined(HAVE_LIBSTATGRAB) /* {{{ */
AM_CFLAGS = -Wall -Werror
endif
-AM_CPPFLAGS = -DPREFIX='"${prefix}"'
+AM_CPPFLAGS = -I$(top_srcdir)/src
+AM_CPPFLAGS += -DPREFIX='"${prefix}"'
AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"'
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netdb.h>
#include <pthread.h>
sstrerror (errno, errbuf, sizeof (errbuf)));
return (-1);
}
-
+
dirlen = strlen (dir);
while ((dirlen > 0) && (dir[dirlen - 1] == '/'))
dir[--dirlen] = '\0';
static void exit_usage (int status)
{
printf ("Usage: "PACKAGE" [OPTIONS]\n\n"
-
+
"Available options:\n"
" General:\n"
" -C <file> Configuration file.\n"
#endif
#if HAVE_LIBSTATGRAB
- if (sg_init ())
+ if (sg_init (
+# if HAVE_LIBSTATGRAB_0_90
+ 0
+# endif
+ ))
{
ERROR ("sg_init: %s", sg_str_error (sg_get_error ()));
return (-1);
} /* static int pidfile_remove (const char *file) */
#endif /* COLLECT_DAEMON */
+#ifdef KERNEL_LINUX
+int notify_upstart (void)
+{
+ const char *upstart_job = getenv("UPSTART_JOB");
+
+ if (upstart_job == NULL)
+ return 0;
+
+ if (strcmp(upstart_job, "collectd") != 0)
+ return 0;
+
+ WARNING ("supervised by upstart, will stop to signal readyness");
+ raise(SIGSTOP);
+ unsetenv("UPSTART_JOB");
+
+ return 1;
+}
+
+int notify_systemd (void)
+{
+ int fd = -1;
+ const char *notifysocket = getenv("NOTIFY_SOCKET");
+ struct sockaddr_un su;
+ struct iovec iov;
+ struct msghdr hdr;
+
+ if (notifysocket == NULL)
+ return 0;
+
+ if ((strchr("@/", notifysocket[0])) == NULL ||
+ strlen(notifysocket) < 2)
+ return 0;
+
+ WARNING ("supervised by systemd, will signal readyness");
+ if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
+ WARNING ("cannot contact systemd socket %s", notifysocket);
+ return 0;
+ }
+
+ bzero(&su, sizeof(su));
+ su.sun_family = AF_UNIX;
+ sstrncpy (su.sun_path, notifysocket, sizeof(su.sun_path));
+
+ if (notifysocket[0] == '@')
+ su.sun_path[0] = 0;
+
+ bzero(&iov, sizeof(iov));
+ iov.iov_base = "READY=1";
+ iov.iov_len = strlen("READY=1");
+
+ bzero(&hdr, sizeof(hdr));
+ hdr.msg_name = &su;
+ hdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) +
+ strlen(notifysocket);
+ hdr.msg_iov = &iov;
+ hdr.msg_iovlen = 1;
+
+ unsetenv("NOTIFY_SOCKET");
+ if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) {
+ WARNING ("cannot send notification to systemd");
+ close(fd);
+ return 0;
+ }
+ close(fd);
+ return 1;
+}
+#endif /* KERNEL_LINUX */
+
int main (int argc, char **argv)
{
struct sigaction sig_int_action;
sig_chld_action.sa_handler = SIG_IGN;
sigaction (SIGCHLD, &sig_chld_action, NULL);
- if (daemonize)
+ /*
+ * Only daemonize if we're not being supervised
+ * by upstart or systemd (when using Linux).
+ */
+ if (daemonize
+#ifdef KERNEL_LINUX
+ && notify_upstart() == 0 && notify_systemd() == 0
+#endif
+ )
{
if ((pid = fork ()) == -1)
{
#include "utils_time.h"
#include "utils_random.h"
-#if HAVE_PTHREAD_H
-# include <pthread.h>
-#endif
-
#include <ltdl.h>
/*
#include "meta_data.h"
#include "utils_time.h"
+#if HAVE_PTHREAD_H
+# include <pthread.h>
+#endif
+
#define PLUGIN_FLAGS_GLOBAL 0x0001
#define DATA_MAX_NAME_LEN 64
#elif defined(HAVE_LIBSTATGRAB)
sg_disk_io_stats *ds;
- int disks, counter;
+# if HAVE_LIBSTATGRAB_0_90
+ size_t disks;
+# else
+ int disks;
+#endif
+ int counter;
char name[DATA_MAX_NAME_LEN];
if ((ds = sg_get_disk_io_stats(&disks)) == NULL)
* Mirko Buffoni <briareos at eswat.org>
**/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#include "collectd.h"
* Peter Holik <peter at holik.at>
**/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE /* For setgroups */
#include "collectd.h"
BUILT_SOURCES = collectd/lcc_features.h
libcollectdclient_la_SOURCES = client.c network.c network_buffer.c
-libcollectdclient_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd -I$(top_srcdir)/src/daemon
+libcollectdclient_la_CPPFLAGS = $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/src/libcollectdclient/collectd \
+ -I$(top_builddir)/src/libcollectdclient/collectd \
+ -I$(top_srcdir)/src/daemon
libcollectdclient_la_LDFLAGS = -version-info 1:0:0
libcollectdclient_la_LIBADD =
if BUILD_WITH_LIBGCRYPT
/* Re enable deprecation warnings */
# pragma GCC diagnostic warning "-Wdeprecated-declarations"
# endif
+# if GCRYPT_VERSION_NUMBER < 0x010600
GCRY_THREAD_OPTION_PTHREAD_IMPL;
+# endif
#endif
#include "collectd/network_buffer.h"
need_init = 0;
#if HAVE_LIBGCRYPT
+# if GCRYPT_VERSION_NUMBER < 0x010600
gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+# endif
if (!gcry_check_version (GCRYPT_VERSION))
return (0);
BOOL_FALSE (false|no|off)
COMMENT #.*
PORT (6(5(5(3[0-5]|[0-2][0-9])|[0-4][0-9][0-9])|[0-4][0-9][0-9][0-9])|[1-5][0-9][0-9][0-9][0-9]|[1-9][0-9]?[0-9]?[0-9]?)
+
IP_BYTE (2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])
IPV4_ADDR {IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}\.{IP_BYTE}(:{PORT})?
+/* IPv6 address according to http://www.ietf.org/rfc/rfc2373.txt
+ * This supports embedded IPv4 addresses as well but does not strictly check
+ * for the right prefix (::0:<v4> or ::FFFF:<v4>) because there are too many
+ * ways to correctly represent the zero bytes. It's up to the user to check
+ * for valid addresses. */
+HEX16 ([0-9A-Fa-f]{1,4})
+V6_PART ({HEX16}:{HEX16}|{IPV4_ADDR})
+IPV6_BASE ({HEX16}:){6}{V6_PART}|::({HEX16}:){5}{V6_PART}|({HEX16})?::({HEX16}:){4}{V6_PART}|(({HEX16}:){0,1}{HEX16})?::({HEX16}:){3}{V6_PART}|(({HEX16}:){0,2}{HEX16})?::({HEX16}:){2}{V6_PART}|(({HEX16}:){0,3}{HEX16})?::{HEX16}:{V6_PART}|(({HEX16}:){0,4}{HEX16})?::{V6_PART}|(({HEX16}:){0,5}{HEX16})?::{HEX16}|(({HEX16}:){0,6}{HEX16})?::
+IPV6_ADDR ({IPV6_BASE})|(\[{IPV6_BASE}\](:{PORT})?)
+
%%
{WHITE_SPACE} |
{COMMENT} {/* ignore */}
{BOOL_FALSE} {yylval.boolean = 0; return (BFALSE);}
{IPV4_ADDR} {yylval.string = yytext; return (UNQUOTED_STRING);}
+{IPV6_ADDR} {yylval.string = yytext; return (UNQUOTED_STRING);}
{NUMBER} {yylval.number = strtod (yytext, NULL); return (NUMBER);}
* Vedran Bartonicek <vbartoni at gmail.com>
**/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#include "collectd.h"
}
dm_list_iterate_items(lvl, lvs) {
- lvm_submit(vg_name, lvm_lv_get_name(lvl->lv), lvm_lv_get_size(lvl->lv));
- }
-
- dm_list_iterate_items(lvl, lvs) {
name = lvm_lv_get_name(lvl->lv);
attrs = get_lv_property_string(lvl->lv, "lv_attr");
size = lvm_lv_get_size(lvl->lv);
#ifdef HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
#endif
+#ifdef HAVE_SYS_VMMETER_H
+# include <sys/vmmeter.h>
+#endif
#ifdef HAVE_MACH_KERN_RETURN_H
# include <mach/kern_return.h>
else if (strcmp (key, "Innodb_buffer_pool_pages_dirty") == 0)
gauge_submit ("mysql_bpool_pages", "dirty", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_flushed") == 0)
- counter_submit ("mysql_bpool_counters", "flushed", val, db);
+ counter_submit ("mysql_bpool_pages", "flushed", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_free") == 0)
gauge_submit ("mysql_bpool_pages", "free", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_misc") == 0)
else if (strcmp (key, "Innodb_data_reads") == 0)
counter_submit ("mysql_innodb_data", "reads", val, db);
else if (strcmp (key, "Innodb_data_writes") == 0)
- counter_submit ("mysql_bpool_counters", "writes", val, db);
+ counter_submit ("mysql_innodb_data", "writes", val, db);
else if (strcmp (key, "Innodb_data_written") == 0)
counter_submit ("mysql_innodb_data", "written", val, db);
* Aman Gupta <aman at tmm1.net>
**/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE /* For struct ip_mreq */
#include "collectd.h"
/* Re enable deprecation warnings */
# pragma GCC diagnostic warning "-Wdeprecated-declarations"
# endif
+# if GCRYPT_VERSION_NUMBER < 0x010600
GCRY_THREAD_OPTION_PTHREAD_IMPL;
+# endif
#endif
#ifndef IPV6_ADD_MEMBERSHIP
* above doesn't count, as it doesn't implicitly initalize Libgcrypt.
*
* tl;dr: keep all these gry_* statements in this exact order please. */
+# if GCRYPT_VERSION_NUMBER < 0x010600
gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+# endif
gcry_check_version (NULL);
gcry_control (GCRYCTL_INIT_SECMEM, 32768);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
network_config_ttl = tmp;
else {
WARNING ("network plugin: The `TimeToLive' must be between 1 and 255.");
- return (-1);
+ return (-1);
}
return (0);
* Florian octo Forster <octo at collectd.org>
**/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE /* For NI_MAXHOST */
#include "collectd.h"
poll_s.fd = sd;
poll_s.events = POLLIN | POLLPRI;
poll_s.revents = 0;
-
+
DEBUG ("Polling for %ims", timeout);
status = poll (&poll_s, 1, timeout);
DEBUG ("recv'd %i bytes", status);
- /*
+ /*
* Do some sanity checks first
*/
if (status < RESP_HEADER_SIZE)
req.err_nitems = ERR_NITEMS (0, req_items);
req.mbz_itemsize = MBZ_ITEMSIZE (req_size);
-
+
if (req_data != NULL)
memcpy ((void *) req.data, (const void *) req_data, req_data_len);
--- /dev/null
+/**
+ * collectd - src/openldap.c
+ * Copyright (C) 2011 Kimo Rosenbaum
+ * Copyright (C) 2014 Marc Fournier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Kimo Rosenbaum <kimor79 at yahoo.com>
+ * Marc Fournier <marc.fournier at camptocamp.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+
+#include <lber.h>
+#include <ldap.h>
+
+struct ldap_s /* {{{ */
+{
+ char *name;
+
+ char *cacert;
+ char *host;
+ int state;
+ _Bool starttls;
+ int timeout;
+ char *url;
+ _Bool verifyhost;
+ int version;
+
+ LDAP *ld;
+};
+typedef struct ldap_s ldap_t; /* }}} */
+
+static void ldap_free (ldap_t *st) /* {{{ */
+{
+ if (st == NULL)
+ return;
+
+ sfree (st->cacert);
+ sfree (st->host);
+ sfree (st->name);
+ sfree (st->url);
+ if (st->ld)
+ ldap_memfree (st->ld);
+ sfree (st);
+} /* }}} void ldap_free */
+
+/* initialize ldap for each host */
+static int ldap_init_host (ldap_t *st) /* {{{ */
+{
+ LDAP *ld;
+ int rc;
+ rc = ldap_initialize (&ld, st->url);
+ if (rc != LDAP_SUCCESS)
+ {
+ ERROR ("openldap plugin: ldap_initialize failed: %s",
+ ldap_err2string (rc));
+ st->state = 0;
+ ldap_unbind_ext_s (ld, NULL, NULL);
+ return (-1);
+ }
+
+ st->ld = ld;
+
+ ldap_set_option (st->ld, LDAP_OPT_PROTOCOL_VERSION, &st->version);
+
+ ldap_set_option (st->ld, LDAP_OPT_TIMEOUT,
+ &(const struct timeval){st->timeout, 0});
+
+ if (st->cacert != NULL)
+ ldap_set_option (st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert);
+
+ if (st->verifyhost == 0)
+ {
+ int never = LDAP_OPT_X_TLS_NEVER;
+ ldap_set_option (st->ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &never);
+ }
+
+ if (st->starttls != 0)
+ {
+ rc = ldap_start_tls_s (ld, NULL, NULL);
+ if (rc != LDAP_SUCCESS)
+ {
+ ERROR ("openldap plugin: Failed to start tls on %s: %s",
+ st->url, ldap_err2string (rc));
+ st->state = 0;
+ ldap_unbind_ext_s (st->ld, NULL, NULL);
+ return (-1);
+ }
+ }
+
+ struct berval cred;
+ cred.bv_val = "";
+ cred.bv_len = 0;
+
+ rc = ldap_sasl_bind_s (st->ld, NULL, NULL, &cred, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS)
+ {
+ ERROR ("openldap plugin: Failed to bind to %s: %s",
+ st->url, ldap_err2string (rc));
+ st->state = 0;
+ ldap_unbind_ext_s (st->ld, NULL, NULL);
+ return (-1);
+ }
+ else
+ {
+ DEBUG ("openldap plugin: Successfully connected to %s",
+ st->url);
+ st->state = 1;
+ return (0);
+ }
+} /* }}} static ldap_init_host */
+
+static void ldap_submit_value (const char *type, const char *type_instance, /* {{{ */
+ value_t value, ldap_t *st)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = &value;
+ vl.values_len = 1;
+
+ if ((st->host == NULL)
+ || (strcmp ("", st->host) == 0)
+ || (strcmp ("localhost", st->host) == 0))
+ {
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ }
+ else
+ {
+ sstrncpy (vl.host, st->host, sizeof (vl.host));
+ }
+
+ sstrncpy (vl.plugin, "openldap", sizeof (vl.plugin));
+ if (st->name != NULL)
+ sstrncpy (vl.plugin_instance, st->name,
+ sizeof (vl.plugin_instance));
+
+ sstrncpy (vl.type, type, sizeof (vl.type));
+ if (type_instance != NULL)
+ sstrncpy (vl.type_instance, type_instance,
+ sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+} /* }}} void ldap_submit_value */
+
+static void ldap_submit_derive (const char *type, const char *type_instance, /* {{{ */
+ derive_t d, ldap_t *st)
+{
+ value_t v;
+ v.derive = d;
+ ldap_submit_value (type, type_instance, v, st);
+} /* }}} void ldap_submit_derive */
+
+static void ldap_submit_gauge (const char *type, const char *type_instance, /* {{{ */
+ gauge_t g, ldap_t *st)
+{
+ value_t v;
+ v.gauge = g;
+ ldap_submit_value (type, type_instance, v, st);
+} /* }}} void ldap_submit_gauge */
+
+static int ldap_read_host (user_data_t *ud) /* {{{ */
+{
+ ldap_t *st;
+ LDAPMessage *e, *result;
+ char *dn;
+ int rc;
+ int status;
+
+ char *attrs[9] = { "monitorCounter",
+ "monitorOpCompleted",
+ "monitorOpInitiated",
+ "monitoredInfo",
+ "olmBDBEntryCache",
+ "olmBDBDNCache",
+ "olmBDBIDLCache",
+ "namingContexts",
+ NULL };
+
+ if ((ud == NULL) || (ud->data == NULL))
+ {
+ ERROR ("openldap plugin: ldap_read_host: Invalid user data.");
+ return (-1);
+ }
+
+ st = (ldap_t *) ud->data;
+
+ status = ldap_init_host (st);
+ if (status != 0)
+ return (-1);
+
+ rc = ldap_search_ext_s (st->ld, "cn=Monitor", LDAP_SCOPE_SUBTREE,
+ "(|(!(cn=* *))(cn=Database*))", attrs, 0,
+ NULL, NULL, NULL, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
+ {
+ ERROR ("openldap plugin: Failed to execute search: %s",
+ ldap_err2string (rc));
+ ldap_msgfree (result);
+ ldap_unbind_ext_s (st->ld, NULL, NULL);
+ return (-1);
+ }
+
+ for (e = ldap_first_entry (st->ld, result); e != NULL;
+ e = ldap_next_entry (st->ld, e))
+ {
+ if ((dn = ldap_get_dn (st->ld, e)) != NULL)
+ {
+ unsigned long long counter = 0;
+ unsigned long long opc = 0;
+ unsigned long long opi = 0;
+ unsigned long long info = 0;
+
+ struct berval counter_data;
+ struct berval opc_data;
+ struct berval opi_data;
+ struct berval info_data;
+ struct berval olmbdb_data;
+ struct berval nc_data;
+
+ struct berval **counter_list;
+ struct berval **opc_list;
+ struct berval **opi_list;
+ struct berval **info_list;
+ struct berval **olmbdb_list;
+ struct berval **nc_list;
+
+ if ((counter_list = ldap_get_values_len (st->ld, e,
+ "monitorCounter")) != NULL)
+ {
+ counter_data = *counter_list[0];
+ counter = atoll (counter_data.bv_val);
+ }
+
+ if ((opc_list = ldap_get_values_len (st->ld, e,
+ "monitorOpCompleted")) != NULL)
+ {
+ opc_data = *opc_list[0];
+ opc = atoll (opc_data.bv_val);
+ }
+
+ if ((opi_list = ldap_get_values_len (st->ld, e,
+ "monitorOpInitiated")) != NULL)
+ {
+ opi_data = *opi_list[0];
+ opi = atoll (opi_data.bv_val);
+ }
+
+ if ((info_list = ldap_get_values_len (st->ld, e,
+ "monitoredInfo")) != NULL)
+ {
+ info_data = *info_list[0];
+ info = atoll (info_data.bv_val);
+ }
+
+ if (strcmp (dn, "cn=Total,cn=Connections,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("total_connections", NULL,
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Current,cn=Connections,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("current_connections", NULL,
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Operations,cn=Monitor") == 0)
+ {
+ ldap_submit_derive ("operations",
+ "completed", opc, st);
+ ldap_submit_derive ("operations",
+ "initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Bind,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "bind-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "bind-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=UnBind,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "unbind-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "unbind-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Search,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "search-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "search-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Compare,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "compare-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "compare-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Modify,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "modify-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "modify-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Modrdn,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "modrdn-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "modrdn-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Add,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "add-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "add-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Delete,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "delete-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "delete-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Abandon,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "abandon-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "abandon-initiated", opi, st);
+ }
+ else if (strcmp (dn,
+ "cn=Extended,cn=Operations,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("operations",
+ "extended-completed", opc, st);
+ ldap_submit_derive ("operations",
+ "extended-initiated", opi, st);
+ }
+ else if ((strncmp (dn, "cn=Database", 11) == 0)
+ && ((nc_list = ldap_get_values_len
+ (st->ld, e, "namingContexts")) != NULL))
+ {
+ nc_data = *nc_list[0];
+ char typeinst[DATA_MAX_NAME_LEN];
+
+ if ((olmbdb_list = ldap_get_values_len (st->ld, e,
+ "olmBDBEntryCache")) != NULL)
+ {
+ olmbdb_data = *olmbdb_list[0];
+ ssnprintf (typeinst, sizeof (typeinst),
+ "bdbentrycache-%s", nc_data.bv_val);
+ ldap_submit_gauge ("cache_size", typeinst,
+ atoll (olmbdb_data.bv_val), st);
+ ldap_value_free_len (olmbdb_list);
+ }
+
+ if ((olmbdb_list = ldap_get_values_len (st->ld, e,
+ "olmBDBDNCache")) != NULL)
+ {
+ olmbdb_data = *olmbdb_list[0];
+ ssnprintf (typeinst, sizeof (typeinst),
+ "bdbdncache-%s", nc_data.bv_val);
+ ldap_submit_gauge ("cache_size", typeinst,
+ atoll (olmbdb_data.bv_val), st);
+ ldap_value_free_len (olmbdb_list);
+ }
+
+ if ((olmbdb_list = ldap_get_values_len (st->ld, e,
+ "olmBDBIDLCache")) != NULL)
+ {
+ olmbdb_data = *olmbdb_list[0];
+ ssnprintf (typeinst, sizeof (typeinst),
+ "bdbidlcache-%s", nc_data.bv_val);
+ ldap_submit_gauge ("cache_size", typeinst,
+ atoll (olmbdb_data.bv_val), st);
+ ldap_value_free_len (olmbdb_list);
+ }
+
+ ldap_value_free_len (nc_list);
+ }
+ else if (strcmp (dn,
+ "cn=Bytes,cn=Statistics,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "statistics-bytes",
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=PDU,cn=Statistics,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "statistics-pdu",
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Entries,cn=Statistics,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "statistics-entries",
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Referrals,cn=Statistics,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "statistics-referrals",
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Open,cn=Threads,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("threads", "threads-open",
+ info, st);
+ }
+ else if (strcmp (dn,
+ "cn=Starting,cn=Threads,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("threads", "threads-starting",
+ info, st);
+ }
+ else if (strcmp (dn,
+ "cn=Active,cn=Threads,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("threads", "threads-active",
+ info, st);
+ }
+ else if (strcmp (dn,
+ "cn=Pending,cn=Threads,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("threads", "threads-pending",
+ info, st);
+ }
+ else if (strcmp (dn,
+ "cn=Backload,cn=Threads,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_gauge ("threads", "threads-backload",
+ info, st);
+ }
+ else if (strcmp (dn,
+ "cn=Read,cn=Waiters,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "waiters-read",
+ counter, st);
+ }
+ else if (strcmp (dn,
+ "cn=Write,cn=Waiters,cn=Monitor")
+ == 0)
+ {
+ ldap_submit_derive ("derive", "waiters-write",
+ counter, st);
+ }
+
+ ldap_value_free_len (counter_list);
+ ldap_value_free_len (opc_list);
+ ldap_value_free_len (opi_list);
+ ldap_value_free_len (info_list);
+ }
+
+ ldap_memfree (dn);
+ }
+
+ ldap_msgfree (result);
+ ldap_unbind_ext_s (st->ld, NULL, NULL);
+ return (0);
+} /* }}} int ldap_read_host */
+
+/* Configuration handling functions {{{
+ *
+ * <Plugin ldap>
+ * <Instance "plugin_instance1">
+ * URL "ldap://localhost"
+ * ...
+ * </Instance>
+ * </Plugin>
+ */
+
+static int ldap_config_add (oconfig_item_t *ci) /* {{{ */
+{
+ ldap_t *st;
+ int i;
+ int status;
+
+ st = malloc (sizeof (*st));
+ if (st == NULL)
+ {
+ ERROR ("openldap plugin: malloc failed.");
+ return (-1);
+ }
+ memset (st, 0, sizeof (*st));
+
+ status = cf_util_get_string (ci, &st->name);
+ if (status != 0)
+ {
+ sfree (st);
+ return (status);
+ }
+
+ st->starttls = 0;
+ st->timeout = -1;
+ st->verifyhost = 1;
+ st->version = LDAP_VERSION3;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("CACert", child->key) == 0)
+ status = cf_util_get_string (child, &st->cacert);
+ else if (strcasecmp ("StartTLS", child->key) == 0)
+ status = cf_util_get_boolean (child, &st->starttls);
+ else if (strcasecmp ("Timeout", child->key) == 0)
+ status = cf_util_get_int (child, &st->timeout);
+ else if (strcasecmp ("URL", child->key) == 0)
+ status = cf_util_get_string (child, &st->url);
+ else if (strcasecmp ("VerifyHost", child->key) == 0)
+ status = cf_util_get_boolean (child, &st->verifyhost);
+ else if (strcasecmp ("Version", child->key) == 0)
+ status = cf_util_get_int (child, &st->version);
+ else
+ {
+ WARNING ("openldap plugin: Option `%s' not allowed here.",
+ child->key);
+ status = -1;
+ }
+
+ if (status != 0)
+ break;
+ }
+
+ /* Check if struct is complete.. */
+ if ((status == 0) && (st->url == NULL))
+ {
+ ERROR ("openldap plugin: Instance `%s': "
+ "No URL has been configured.",
+ st->name);
+ status = -1;
+ }
+
+ /* Check if URL is valid */
+ if ((status == 0) && (st->url != NULL))
+ {
+ LDAPURLDesc *ludpp;
+ int rc;
+
+ if ((rc = ldap_url_parse (st->url, &ludpp)) != 0)
+ {
+ ERROR ("openldap plugin: Instance `%s': "
+ "Invalid URL: `%s'",
+ st->name, st->url);
+ status = -1;
+ }
+ else
+ {
+ st->host = strdup (ludpp->lud_host);
+ }
+
+ ldap_free_urldesc (ludpp);
+ }
+
+ if (status == 0)
+ {
+ user_data_t ud;
+ char callback_name[3*DATA_MAX_NAME_LEN];
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = st;
+
+ memset (callback_name, 0, sizeof (callback_name));
+ ssnprintf (callback_name, sizeof (callback_name),
+ "openldap/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default"),
+
+ status = plugin_register_complex_read (/* group = */ NULL,
+ /* name = */ callback_name,
+ /* callback = */ ldap_read_host,
+ /* interval = */ NULL,
+ /* user_data = */ &ud);
+ }
+
+ if (status != 0)
+ {
+ ldap_free (st);
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int ldap_config_add */
+
+static int ldap_config (oconfig_item_t *ci) /* {{{ */
+{
+ int i;
+ int status = 0;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("Instance", child->key) == 0)
+ ldap_config_add (child);
+ else
+ WARNING ("openldap plugin: The configuration option "
+ "\"%s\" is not allowed here. Did you "
+ "forget to add an <Instance /> block "
+ "around the configuration?",
+ child->key);
+ } /* for (ci->children) */
+
+ return (status);
+} /* }}} int ldap_config */
+
+/* }}} End of configuration handling functions */
+
+static int ldap_init (void) /* {{{ */
+{
+ /* Initialize LDAP library while still single-threaded as recommended in
+ * ldap_initialize(3) */
+ int debug_level;
+ ldap_get_option (NULL, LDAP_OPT_DEBUG_LEVEL, &debug_level);
+ return (0);
+} /* }}} int ldap_init */
+
+void module_register (void) /* {{{ */
+{
+ plugin_register_complex_config ("openldap", ldap_config);
+ plugin_register_init ("openldap", ldap_init);
+} /* }}} void module_register */
# endif
/* #endif KERNEL_LINUX */
-#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
+#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
# include <kvm.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# include <sys/user.h>
# include <sys/proc.h>
-/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
+/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
#elif HAVE_PROCINFO_H
# include <procinfo.h>
static long pagesize_g;
/* #endif KERNEL_LINUX */
-#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
+#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
static int pagesize;
-/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
+/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
#elif HAVE_PROCINFO_H
static struct procentry64 procentry[MAXPROCENTRY];
pagesize_g, CONFIG_HZ);
/* #endif KERNEL_LINUX */
-#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
+#elif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
pagesize = getpagesize();
-/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
+/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD) */
#elif HAVE_PROCINFO_H
pagesize = getpagesize();
ps_submit_proc_list (ps_ptr);
/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
+#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD
+ int running = 0;
+ int sleeping = 0;
+ int zombies = 0;
+ int stopped = 0;
+ int onproc = 0;
+ int idle = 0;
+ int dead = 0;
+
+ kvm_t *kd;
+ char errbuf[1024];
+ struct kinfo_proc *procs; /* array of processes */
+ struct kinfo_proc *proc_ptr = NULL;
+ int count; /* returns number of processes */
+ int i;
+
+ procstat_t *ps_ptr;
+ procstat_entry_t pse;
+
+ ps_list_reset ();
+
+ /* Open the kvm interface, get a descriptor */
+ kd = kvm_open (NULL, NULL, NULL, 0, errbuf);
+ if (kd == NULL)
+ {
+ ERROR ("processes plugin: Cannot open kvm interface: %s",
+ errbuf);
+ return (0);
+ }
+
+ /* Get the list of processes. */
+ procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &count);
+ if (procs == NULL)
+ {
+ ERROR ("processes plugin: Cannot get kvm processes list: %s",
+ kvm_geterr(kd));
+ kvm_close (kd);
+ return (0);
+ }
+
+ /* Iterate through the processes in kinfo_proc */
+ for (i = 0; i < count; i++)
+ {
+ /* Create only one process list entry per _process_, i.e.
+ * filter out threads (duplicate PID entries). */
+ if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid))
+ {
+ char cmdline[CMDLINE_BUFFER_SIZE] = "";
+ _Bool have_cmdline = 0;
+
+ proc_ptr = &(procs[i]);
+ /* Don't probe zombie processes */
+ if (!P_ZOMBIE(proc_ptr))
+ {
+ char **argv;
+ int argc;
+ int status;
+
+ /* retrieve the arguments */
+ argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0);
+ argc = 0;
+ if ((argv != NULL) && (argv[0] != NULL))
+ {
+ while (argv[argc] != NULL)
+ argc++;
+
+ status = strjoin (cmdline, sizeof (cmdline), argv, argc, " ");
+ if (status < 0)
+ WARNING ("processes plugin: Command line did not fit into buffer.");
+ else
+ have_cmdline = 1;
+ }
+ } /* if (process has argument list) */
+
+ pse.id = procs[i].p_pid;
+ pse.age = 0;
+
+ pse.num_proc = 1;
+ pse.num_lwp = 1; /* XXX: accumulate p_tid values for a single p_pid ? */
+
+ pse.vmem_rss = procs[i].p_vm_rssize * pagesize;
+ pse.vmem_data = procs[i].p_vm_dsize * pagesize;
+ pse.vmem_code = procs[i].p_vm_tsize * pagesize;
+ pse.stack_size = procs[i].p_vm_ssize * pagesize;
+ pse.vmem_size = pse.stack_size + pse.vmem_code + pse.vmem_data;
+ pse.vmem_minflt = 0;
+ pse.vmem_minflt_counter = procs[i].p_uru_minflt;
+ pse.vmem_majflt = 0;
+ pse.vmem_majflt_counter = procs[i].p_uru_majflt;
+
+ pse.cpu_user = 0;
+ pse.cpu_system = 0;
+ pse.cpu_user_counter = procs[i].p_uutime_usec +
+ (1000000lu * procs[i].p_uutime_sec);
+ pse.cpu_system_counter = procs[i].p_ustime_usec +
+ (1000000lu * procs[i].p_ustime_sec);
+
+ /* no I/O data */
+ pse.io_rchar = -1;
+ pse.io_wchar = -1;
+ pse.io_syscr = -1;
+ pse.io_syscw = -1;
+
+ ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse);
+ } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
+
+ switch (procs[i].p_stat)
+ {
+ case SSTOP: stopped++; break;
+ case SSLEEP: sleeping++; break;
+ case SRUN: running++; break;
+ case SIDL: idle++; break;
+ case SONPROC: onproc++; break;
+ case SDEAD: dead++; break;
+ case SZOMB: zombies++; break;
+ }
+ }
+
+ kvm_close(kd);
+
+ ps_submit_state ("running", running);
+ ps_submit_state ("sleeping", sleeping);
+ ps_submit_state ("zombies", zombies);
+ ps_submit_state ("stopped", stopped);
+ ps_submit_state ("onproc", onproc);
+ ps_submit_state ("idle", idle);
+ ps_submit_state ("dead", dead);
+
+ for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+ ps_submit_proc_list (ps_ptr);
+/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD */
+
#elif HAVE_PROCINFO_H
/* AIX */
int running = 0;
static char log_doc[] = "This function sends a string to all logging plugins.";
+static char get_ds_doc[] = "get_dataset(name) -> definition\n"
+ "\n"
+ "Returns the definition of a dataset specified by name.\n"
+ "\n"
+ "'name' is a string specifying the dataset to query.\n"
+ "'definition' is a list of 4-tuples. Every tuple represents a \n"
+ " data source within the data set and its 4 values are the \n"
+ " name, type, min and max value.\n"
+ " 'name' is a string.\n"
+ " 'type' is a string that is equal to either DS_TYPE_COUNTER,\n"
+ " DS_TYPE_GAUGE, DS_TYPE_DERIVE or DS_TYPE_ABSOLUTE.\n"
+ " 'min' and 'max' are either a float or None.";
+
static char flush_doc[] = "flush([plugin][, timeout][, identifier]) -> None\n"
"\n"
"Flushes the cache of another plugin.";
return cpy_string_to_unicode_or_bytes(buf);
}
-static PyObject *cpy_flush(cpy_callback_t **list_head, PyObject *args, PyObject *kwds) {
+static PyObject *float_or_none(float number) {
+ if (isnan(number)) {
+ Py_RETURN_NONE;
+ }
+ return PyFloat_FromDouble(number);
+}
+
+static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
+ int i;
+ char *name;
+ const data_set_t *ds;
+ PyObject *list, *tuple;
+
+ if (PyArg_ParseTuple(args, "et", NULL, &name) == 0) return NULL;
+ ds = plugin_get_ds(name);
+ PyMem_Free(name);
+ if (ds == NULL) {
+ PyErr_Format(PyExc_TypeError, "Dataset %s not found", name);
+ return NULL;
+ }
+ list = PyList_New(ds->ds_num); /* New reference. */
+ for (i = 0; i < ds->ds_num; ++i) {
+ tuple = PyTuple_New(4);
+ PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name));
+ PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
+ PyTuple_SET_ITEM(tuple, 2, float_or_none(ds->ds[i].min));
+ PyTuple_SET_ITEM(tuple, 3, float_or_none(ds->ds[i].max));
+ PyList_SET_ITEM(list, i, tuple);
+ }
+ return list;
+}
+
+static PyObject *cpy_flush(PyObject *self, PyObject *args, PyObject *kwds) {
int timeout = -1;
char *plugin = NULL, *identifier = NULL;
static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
{"notice", cpy_notice, METH_VARARGS, log_doc},
{"warning", cpy_warning, METH_VARARGS, log_doc},
{"error", cpy_error, METH_VARARGS, log_doc},
+ {"get_dataset", (PyCFunction) cpy_get_dataset, METH_VARARGS, get_ds_doc},
{"flush", (PyCFunction) cpy_flush, METH_VARARGS | METH_KEYWORDS, flush_doc},
{"register_log", (PyCFunction) cpy_register_log, METH_VARARGS | METH_KEYWORDS, reg_log_doc},
{"register_init", (PyCFunction) cpy_register_init, METH_VARARGS | METH_KEYWORDS, reg_init_doc},
PyModule_AddIntConstant(module, "NOTIF_FAILURE", NOTIF_FAILURE);
PyModule_AddIntConstant(module, "NOTIF_WARNING", NOTIF_WARNING);
PyModule_AddIntConstant(module, "NOTIF_OKAY", NOTIF_OKAY);
+ PyModule_AddStringConstant(module, "DS_TYPE_COUNTER", DS_TYPE_TO_STRING(DS_TYPE_COUNTER));
+ PyModule_AddStringConstant(module, "DS_TYPE_GAUGE", DS_TYPE_TO_STRING(DS_TYPE_GAUGE));
+ PyModule_AddStringConstant(module, "DS_TYPE_DERIVE", DS_TYPE_TO_STRING(DS_TYPE_DERIVE));
+ PyModule_AddStringConstant(module, "DS_TYPE_ABSOLUTE", DS_TYPE_TO_STRING(DS_TYPE_ABSOLUTE));
return 0;
}
#include "configfile.h"
#include <pthread.h>
-#include <credis.h>
+#include <sys/time.h>
+#include <hiredis/hiredis.h>
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
#define REDIS_DEF_TIMEOUT 2000
#define MAX_REDIS_NODE_NAME 64
#define MAX_REDIS_PASSWD_LENGTH 512
+#define MAX_REDIS_VAL_SIZE 256
/* Redis plugin configuration example:
*
* <Node "mynode">
* Host "localhost"
* Port "6379"
- * Timeout 2000
+ * Timeout 2
+ * Password "foobar"
* </Node>
* </Plugin>
*/
char host[HOST_NAME_MAX];
char passwd[MAX_REDIS_PASSWD_LENGTH];
int port;
- int timeout;
+ struct timeval timeout;
redis_node_t *next;
};
return (0);
} /* }}} */
+
static int redis_config_node (oconfig_item_t *ci) /* {{{ */
{
redis_node_t rn;
int i;
int status;
+ int timeout;
memset (&rn, 0, sizeof (rn));
sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host));
rn.port = REDIS_DEF_PORT;
- rn.timeout = REDIS_DEF_TIMEOUT;
+ rn.timeout.tv_usec = REDIS_DEF_TIMEOUT;
status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name));
if (status != 0)
}
}
else if (strcasecmp ("Timeout", option->key) == 0)
- status = cf_util_get_int (option, &rn.timeout);
+ {
+ status = cf_util_get_int (option, &timeout);
+ if (status == 0) rn.timeout.tv_usec = timeout;
+ }
else if (strcasecmp ("Password", option->key) == 0)
status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd));
else
} /* }}} */
__attribute__ ((nonnull(2)))
-static void redis_submit_g (char *plugin_instance,
- const char *type, const char *type_instance,
- gauge_t value) /* {{{ */
-{
- 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, "redis", sizeof (vl.plugin));
- if (plugin_instance != NULL)
- sstrncpy (vl.plugin_instance, plugin_instance,
- sizeof (vl.plugin_instance));
- sstrncpy (vl.type, type, sizeof (vl.type));
- if (type_instance != NULL)
- sstrncpy (vl.type_instance, type_instance,
- sizeof (vl.type_instance));
-
- plugin_dispatch_values (&vl);
-} /* }}} */
-
- __attribute__ ((nonnull(2)))
-static void redis_submit_d (char *plugin_instance,
+static void redis_submit (char *plugin_instance,
const char *type, const char *type_instance,
- derive_t value) /* {{{ */
+ value_t value) /* {{{ */
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = value;
+ values[0] = value;
vl.values = values;
vl.values_len = 1;
static int redis_init (void) /* {{{ */
{
- redis_node_t rn = { "default", REDIS_DEF_HOST, REDIS_DEF_PASSWD,
- REDIS_DEF_PORT, REDIS_DEF_TIMEOUT, /* next = */ NULL };
+ redis_node_t rn = {
+ .name = "default",
+ .host = REDIS_DEF_HOST,
+ .port = REDIS_DEF_PORT,
+ .timeout.tv_sec = 0,
+ .timeout.tv_usec = REDIS_DEF_TIMEOUT,
+ .next = NULL
+};
if (nodes_head == NULL)
redis_node_add (&rn);
return (0);
} /* }}} int redis_init */
+int redis_handle_info (char *node, char const *info_line, char const *type, char const *type_instance, char const *field_name, int ds_type) /* {{{ */
+{
+ char *str = strstr (info_line, field_name);
+ static char buf[MAX_REDIS_VAL_SIZE];
+ value_t val;
+ if (str)
+ {
+ int i;
+
+ str += strlen (field_name) + 1; /* also skip the ':' */
+ for(i=0;(*str && (isdigit(*str) || *str == '.'));i++,str++)
+ buf[i] = *str;
+ buf[i] ='\0';
+
+ if(parse_value (buf, &val, ds_type) == -1)
+ {
+ WARNING ("redis plugin: Unable to parse field `%s'.", field_name);
+ return (-1);
+ }
+
+ redis_submit (node, type, type_instance, val);
+ return (0);
+ }
+ return (-1);
+
+} /* }}} int redis_handle_info */
+
static int redis_read (void) /* {{{ */
{
redis_node_t *rn;
for (rn = nodes_head; rn != NULL; rn = rn->next)
{
- REDIS rh;
- REDIS_INFO info;
-
- int status;
+ redisContext *rh;
+ redisReply *rr;
DEBUG ("redis plugin: querying info from node `%s' (%s:%d).", rn->name, rn->host, rn->port);
- rh = credis_connect (rn->host, rn->port, rn->timeout);
+ rh = redisConnectWithTimeout ((char *)rn->host, rn->port, rn->timeout);
if (rh == NULL)
{
ERROR ("redis plugin: unable to connect to node `%s' (%s:%d).", rn->name, rn->host, rn->port);
if (strlen (rn->passwd) > 0)
{
DEBUG ("redis plugin: authenticanting node `%s' passwd(%s).", rn->name, rn->passwd);
- status = credis_auth(rh, rn->passwd);
- if (status != 0)
+ rr = redisCommand (rh, "AUTH %s", rn->passwd);
+
+ if (rr == NULL || rr->type != REDIS_REPLY_STATUS)
{
WARNING ("redis plugin: unable to authenticate on node `%s'.", rn->name);
- credis_close (rh);
+ if (rr != NULL)
+ freeReplyObject (rr);
+
+ redisFree (rh);
continue;
}
}
- memset (&info, 0, sizeof (info));
- status = credis_info (rh, &info);
- if (status != 0)
+ if ((rr = redisCommand(rh, "INFO")) == NULL)
{
- WARNING ("redis plugin: unable to get info from node `%s'.", rn->name);
- credis_close (rh);
+ WARNING ("redis plugin: unable to connect to node `%s'.", rn->name);
+ redisFree (rh);
continue;
}
- /* typedef struct _cr_info {
- * char redis_version[CREDIS_VERSION_STRING_SIZE];
- * int bgsave_in_progress;
- * int connected_clients;
- * int connected_slaves;
- * unsigned int used_memory;
- * long long changes_since_last_save;
- * int last_save_time;
- * long long total_connections_received;
- * long long total_commands_processed;
- * int uptime_in_seconds;
- * int uptime_in_days;
- * int role;
- * } REDIS_INFO; */
-
- DEBUG ("redis plugin: received info from node `%s': connected_clients = %d; "
- "connected_slaves = %d; used_memory = %lu; changes_since_last_save = %lld; "
- "bgsave_in_progress = %d; total_connections_received = %lld; "
- "total_commands_processed = %lld; uptime_in_seconds = %ld", rn->name,
- info.connected_clients, info.connected_slaves, info.used_memory,
- info.changes_since_last_save, info.bgsave_in_progress,
- info.total_connections_received, info.total_commands_processed,
- info.uptime_in_seconds);
-
- redis_submit_g (rn->name, "current_connections", "clients", info.connected_clients);
- redis_submit_g (rn->name, "current_connections", "slaves", info.connected_slaves);
- redis_submit_g (rn->name, "memory", "used", info.used_memory);
- redis_submit_g (rn->name, "volatile_changes", NULL, info.changes_since_last_save);
- redis_submit_d (rn->name, "total_connections", NULL, info.total_connections_received);
- redis_submit_d (rn->name, "total_operations", NULL, info.total_commands_processed);
-
- credis_close (rh);
+ redis_handle_info (rn->name, rr->str, "uptime", NULL, "uptime_in_seconds", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "current_connections", "clients", "connected_clients", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "blocked_clients", NULL, "blocked_clients", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "memory", NULL, "used_memory", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "memory_lua", NULL, "used_memory_lua", DS_TYPE_GAUGE);
+ /* changes_since_last_save: Deprecated in redis version 2.6 and above */
+ redis_handle_info (rn->name, rr->str, "volatile_changes", NULL, "changes_since_last_save", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "total_connections", NULL, "total_connections_received", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "total_operations", NULL, "total_commands_processed", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "expired_keys", NULL, "expired_keys", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "pubsub", "channels", "pubsub_channels", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "pubsub", "patterns", "pubsub_patterns", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "current_connections", "slaves", "connected_slaves", DS_TYPE_GAUGE);
+
+ freeReplyObject (rr);
+ redisFree (rh);
}
return 0;
--- /dev/null
+/**
+ * collectd - src/smart.c
+ * Copyright (C) 2014 Vincent Bernat
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Vincent Bernat <vbe at exoscale.ch>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+#include <atasmart.h>
+#include <libudev.h>
+
+static const char *config_keys[] =
+{
+ "Disk",
+ "IgnoreSelected"
+};
+
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+static ignorelist_t *ignorelist = NULL;
+
+static int smart_config (const char *key, const char *value)
+{
+ if (ignorelist == NULL)
+ ignorelist = ignorelist_create (/* invert = */ 1);
+ if (ignorelist == NULL)
+ return (1);
+
+ if (strcasecmp ("Disk", key) == 0)
+ {
+ ignorelist_add (ignorelist, value);
+ }
+ else if (strcasecmp ("IgnoreSelected", key) == 0)
+ {
+ int invert = 1;
+ if (IS_TRUE (value))
+ invert = 0;
+ ignorelist_set_invert (ignorelist, invert);
+ }
+ else
+ {
+ return (-1);
+ }
+
+ return (0);
+} /* int smart_config */
+
+static void smart_submit (const char *dev, char *type, char *type_inst, double value)
+{
+ 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, "smart", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, type, sizeof (vl.type));
+ sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedData *a,
+ void* userdata)
+{
+ const char *dev = userdata;
+ value_t values[4];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ if (!a->current_value_valid || !a->worst_value_valid) return;
+ values[0].gauge = a->current_value;
+ values[1].gauge = a->worst_value;
+ values[2].gauge = a->threshold_valid?a->threshold:0;
+ values[3].gauge = a->pretty_value;
+
+ vl.values = values;
+ vl.values_len = 4;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "smart_attribute", sizeof (vl.type));
+ sstrncpy (vl.type_instance, a->name, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+
+ if (a->threshold_valid && a->current_value <= a->threshold)
+ {
+ notification_t notif = { NOTIF_WARNING,
+ cdtime (),
+ "",
+ "",
+ "smart", "",
+ "smart_attribute",
+ "",
+ NULL };
+ sstrncpy (notif.host, hostname_g, sizeof (notif.host));
+ sstrncpy (notif.plugin_instance, dev, sizeof (notif.plugin_instance));
+ sstrncpy (notif.type_instance, a->name, sizeof (notif.type_instance));
+ ssnprintf (notif.message, sizeof (notif.message),
+ "attribute %s is below allowed threshold (%d < %d)",
+ a->name, a->current_value, a->threshold);
+ plugin_dispatch_notification (¬if);
+ }
+}
+
+static void smart_handle_disk (const char *dev)
+{
+ SkDisk *d = NULL;
+ SkBool awake = FALSE;
+ SkBool available = FALSE;
+ const char *shortname;
+ const SkSmartParsedData *spd;
+ uint64_t poweron, powercycles, badsectors, temperature;
+
+ shortname = strrchr(dev, '/');
+ if (!shortname) return;
+ shortname++;
+ if (ignorelist_match (ignorelist, shortname) != 0) {
+ DEBUG ("smart plugin: ignoring %s.", dev);
+ return;
+ }
+
+ DEBUG ("smart plugin: checking SMART status of %s.",
+ dev);
+
+ if (sk_disk_open (dev, &d) < 0)
+ {
+ ERROR ("smart plugin: unable to open %s.", dev);
+ return;
+ }
+ if (sk_disk_identify_is_available (d, &available) < 0 || !available)
+ {
+ DEBUG ("smart plugin: disk %s cannot be identified.", dev);
+ goto end;
+ }
+ if (sk_disk_smart_is_available (d, &available) < 0 || !available)
+ {
+ DEBUG ("smart plugin: disk %s has no SMART support.", dev);
+ goto end;
+ }
+ if (sk_disk_check_sleep_mode (d, &awake) < 0 || !awake)
+ {
+ DEBUG ("smart plugin: disk %s is sleeping.", dev);
+ goto end;
+ }
+ if (sk_disk_smart_read_data (d) < 0)
+ {
+ ERROR ("smart plugin: unable to get SMART data for disk %s.", dev);
+ goto end;
+ }
+ if (sk_disk_smart_parse (d, &spd) < 0)
+ {
+ ERROR ("smart plugin: unable to parse SMART data for disk %s.", dev);
+ goto end;
+ }
+
+ /* Get some specific values */
+ if (sk_disk_smart_get_power_on (d, &poweron) < 0)
+ {
+ WARNING ("smart plugin: unable to get milliseconds since power on for %s.",
+ dev);
+ }
+ else
+ smart_submit (shortname, "smart_poweron", "", poweron / 1000.);
+
+ if (sk_disk_smart_get_power_cycle (d, &powercycles) < 0)
+ {
+ WARNING ("smart plugin: unable to get number of power cycles for %s.",
+ dev);
+ }
+ else
+ smart_submit (shortname, "smart_powercycles", "", powercycles);
+
+ if (sk_disk_smart_get_bad (d, &badsectors) < 0)
+ {
+ WARNING ("smart plugin: unable to get number of bad sectors for %s.",
+ dev);
+ }
+ else
+ smart_submit (shortname, "smart_badsectors", "", badsectors);
+
+ if (sk_disk_smart_get_temperature (d, &temperature) < 0)
+ {
+ WARNING ("smart plugin: unable to get temperature for %s.",
+ dev);
+ }
+ else
+ smart_submit (shortname, "smart_temperature", "", temperature / 1000. - 273.15);
+
+ /* Grab all attributes */
+ if (sk_disk_smart_parse_attributes(d, smart_handle_disk_attribute,
+ (char *)shortname) < 0)
+ {
+ ERROR ("smart plugin: unable to handle SMART attributes for %s.",
+ dev);
+ }
+
+end:
+ sk_disk_free(d);
+}
+
+static int smart_read (void)
+{
+ struct udev *handle_udev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ struct udev_device *dev;
+
+ /* Use udev to get a list of disks */
+ handle_udev = udev_new();
+ if (!handle_udev)
+ {
+ ERROR ("smart plugin: unable to initialize udev.");
+ return (-1);
+ }
+ enumerate = udev_enumerate_new (handle_udev);
+ udev_enumerate_add_match_subsystem (enumerate, "block");
+ udev_enumerate_add_match_property (enumerate, "DEVTYPE", "disk");
+ udev_enumerate_scan_devices (enumerate);
+ devices = udev_enumerate_get_list_entry (enumerate);
+ udev_list_entry_foreach (dev_list_entry, devices)
+ {
+ const char *path, *devpath;
+ path = udev_list_entry_get_name (dev_list_entry);
+ dev = udev_device_new_from_syspath (handle_udev, path);
+ devpath = udev_device_get_devnode (dev);
+
+ /* Query status with libatasmart */
+ smart_handle_disk (devpath);
+ }
+
+ udev_enumerate_unref (enumerate);
+ udev_unref (handle_udev);
+
+ return (0);
+} /* int smart_read */
+
+void module_register (void)
+{
+ plugin_register_config ("smart", smart_config,
+ config_keys, config_keys_num);
+ plugin_register_read ("smart", smart_read);
+} /* void module_register */
{
ERROR("snmp plugin: Can't allocate memory");
strarray_free(dd->ignores, dd->ignores_len);
- return (ENOMEM);
+ return (ENOMEM);
}
}
return 0;
snmp_free_pdu (res);
res = NULL;
+ /* snmp_synch_response already freed our PDU */
+ req = NULL;
sfree (errstr);
csnmp_host_close_session (host);
{
"ListeningPorts",
"LocalPort",
- "RemotePort"
+ "RemotePort",
+ "AllPortsSummary"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
static int port_collect_listening = 0;
+static int port_collect_total = 0;
static port_entry_t *port_list_head = NULL;
+static uint32_t count_total[TCP_STATE_MAX + 1];
#if KERNEL_LINUX
#if HAVE_STRUCT_LINUX_INET_DIAG_REQ
} linux_source = SRC_DUNNO;
#endif
+static void conn_prepare_vl (value_list_t *vl, value_t *values)
+{
+ vl->values = values;
+ vl->values_len = 1;
+ sstrncpy (vl->host, hostname_g, sizeof (vl->host));
+ sstrncpy (vl->plugin, "tcpconns", sizeof (vl->plugin));
+ sstrncpy (vl->type, "tcp_connections", sizeof (vl->type));
+}
+
static void conn_submit_port_entry (port_entry_t *pe)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
int i;
- vl.values = values;
- vl.values_len = 1;
- sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- sstrncpy (vl.plugin, "tcpconns", sizeof (vl.plugin));
- sstrncpy (vl.type, "tcp_connections", sizeof (vl.type));
+ conn_prepare_vl (&vl, values);
if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING))
|| (pe->flags & PORT_COLLECT_LOCAL))
}
} /* void conn_submit */
+static void conn_submit_port_total (void)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+ int i;
+
+ conn_prepare_vl (&vl, values);
+
+ sstrncpy (vl.plugin_instance, "all", sizeof (vl.plugin_instance));
+
+ for (i = 1; i <= TCP_STATE_MAX; i++)
+ {
+ vl.values[0].gauge = count_total[i];
+
+ sstrncpy (vl.type_instance, tcp_state[i], sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+ }
+}
+
static void conn_submit_all (void)
{
port_entry_t *pe;
+ if (port_collect_total)
+ conn_submit_port_total ();
+
for (pe = port_list_head; pe != NULL; pe = pe->next)
conn_submit_port_entry (pe);
} /* void conn_submit_all */
port_entry_t *prev = NULL;
port_entry_t *pe = port_list_head;
+ memset (&count_total, '\0', sizeof(count_total));
+
while (pe != NULL)
{
/* If this entry was created while reading the files (ant not when handling
return (-1);
}
+ count_total[state]++;
+
/* Listening sockets */
if ((state == TCP_STATE_LISTEN) && (port_collect_listening != 0))
{
else
pe->flags |= PORT_COLLECT_REMOTE;
}
+ else if (strcasecmp (key, "AllPortsSummary") == 0)
+ {
+ if (IS_TRUE (value))
+ port_collect_total = 1;
+ else
+ port_collect_total = 0;
+ }
else
{
return (-1);
#if KERNEL_LINUX
static int conn_init (void)
{
- if (port_list_head == NULL)
+ if (port_collect_total == 0 && port_list_head == NULL)
port_collect_listening = 1;
return (0);
static int conn_read (void)
{
struct inpcbtable table;
+#if !defined(__OpenBSD__) && (defined(__NetBSD_Version__) && __NetBSD_Version__ <= 699002700)
struct inpcb *head;
+#endif
struct inpcb *next;
struct inpcb inpcb;
struct tcpcb tcpcb;
if (status != 0)
return (-1);
+#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700)
+ /* inpt_queue is a TAILQ on OpenBSD */
+ /* Get the first pcb */
+ next = (struct inpcb *)TAILQ_FIRST (&table.inpt_queue);
+ while (next)
+#else
/* Get the `head' pcb */
head = (struct inpcb *) &(inpcbtable_ptr->inpt_queue);
/* Get the first pcb */
next = (struct inpcb *)CIRCLEQ_FIRST (&table.inpt_queue);
while (next != head)
+#endif
{
/* Read the pcb pointed to by `next' into `inpcb' */
kread ((u_long) next, &inpcb, sizeof (inpcb));
/* Advance `next' */
+#if defined(__OpenBSD__) || (defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700)
+ /* inpt_queue is a TAILQ on OpenBSD */
+ next = (struct inpcb *)TAILQ_NEXT (&inpcb, inp_queue);
+#else
next = (struct inpcb *)CIRCLEQ_NEXT (&inpcb, inp_queue);
+#endif
/* Ignore sockets, that are not connected. */
#ifdef __NetBSD__
ath_stat value:DERIVE:0:U
backends value:GAUGE:0:65535
bitrate value:GAUGE:0:4294967295
+blocked_clients value:GAUGE:0:U
bytes value:GAUGE:0:U
cache_eviction value:DERIVE:0:U
cache_operation value:DERIVE:0:U
cache_ratio value:GAUGE:0:100
cache_result value:DERIVE:0:U
cache_size value:GAUGE:0:U
+changes_since_last_save value:GAUGE:0:U
charge value:GAUGE:0:U
compression_ratio value:GAUGE:0:2
compression uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
email_count value:GAUGE:0:U
email_size value:GAUGE:0:U
entropy value:GAUGE:0:4294967295
+expired_keys value:GAUGE:0:U
fanspeed value:GAUGE:0:U
file_size value:GAUGE:0:U
files value:GAUGE:0:U
memcached_octets rx:DERIVE:0:U, tx:DERIVE:0:U
memcached_ops value:DERIVE:0:U
memory value:GAUGE:0:281474976710656
+memory_lua value:GAUGE:0:281474976710656
multimeter value:GAUGE:U:U
mutex_operations value:DERIVE:0:U
mysql_commands value:DERIVE:0:U
ps_stacksize value:GAUGE:0:9223372036854775807
ps_state value:GAUGE:0:65535
ps_vm value:GAUGE:0:9223372036854775807
+pubsub value:GAUGE:0:U
queue_length value:GAUGE:0:U
records value:GAUGE:0:U
requests value:GAUGE:0:U
signal_noise value:GAUGE:U:0
signal_power value:GAUGE:U:0
signal_quality value:GAUGE:0:U
+smart_poweron value:GAUGE:0:U
+smart_powercycles value:GAUGE:0:U
+smart_badsectors value:GAUGE:0:U
+smart_temperature value:GAUGE:-300:300
+smart_attribute current:GAUGE:0:255, worst:GAUGE:0:255, threshold:GAUGE:0:255, pretty:GAUGE:0:U
snr value:GAUGE:0:U
spam_check value:GAUGE:0:U
spam_score value:GAUGE:U:U
#elif HAVE_LIBSTATGRAB
sg_user_stats *us;
+# if HAVE_LIBSTATGRAB_0_90
+ size_t num_entries;
+ us = sg_get_user_stats (&num_entries);
+# else
us = sg_get_user_stats ();
+# endif
if (us == NULL)
return (-1);
- users_submit ((gauge_t) us->num_entries);
+ users_submit ((gauge_t)
+# if HAVE_LIBSTATGRAB_0_90
+ num_entries);
+# else
+ us->num_entries);
+# endif
/* #endif HAVE_LIBSTATGRAB */
#else
* Copyright (C) 2006 Florian octo Forster
* Copyright (C) 2002 The Measurement Factory, Inc.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* Florian octo Forster <octo at collectd.org>
*/
+#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#include "collectd.h"
#include "plugin.h"
#include "configfile.h"
-#include <varnish/varnishapi.h>
+#if HAVE_VARNISH_V4
+#include <varnish/vapi/vsm.h>
+#include <varnish/vapi/vsc.h>
+typedef struct VSC_C_main c_varnish_stats_t;
+#endif
#if HAVE_VARNISH_V3
-# include <varnish/vsc.h>
+#include <varnish/varnishapi.h>
+#include <varnish/vsc.h>
typedef struct VSC_C_main c_varnish_stats_t;
#endif
#if HAVE_VARNISH_V2
+#include <varnish/varnishapi.h>
typedef struct varnish_stats c_varnish_stats_t;
#endif
#endif
_Bool collect_struct;
_Bool collect_totals;
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
_Bool collect_uptime;
#endif
_Bool collect_vcl;
_Bool collect_workers;
+#if HAVE_VARNISH_V4
+ _Bool collect_vsm;
+#endif
};
typedef struct user_config_s user_config_t; /* }}} */
if (conf->collect_connections)
{
+#ifndef HAVE_VARNISH_V4
/* Client connections accepted */
varnish_submit_derive (conf->instance, "connections", "connections", "accepted", stats->client_conn);
/* Connection dropped, no sess */
varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , stats->client_drop);
+#endif
/* Client requests received */
varnish_submit_derive (conf->instance, "connections", "connections", "received", stats->client_req);
}
varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero" , stats->fetch_zero);
/* Fetch failed */
varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed" , stats->fetch_failed);
-#if HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
/* Fetch no body (1xx) */
varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", stats->fetch_1xx);
/* Fetch no body (204) */
#endif
/* HTTP header overflows */
varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow", stats->losthdr);
+#if HAVE_VARNISH_V4
+ /* N purged objects */
+ varnish_submit_derive (conf->instance, "objects", "total_objects", "purged", stats->n_obj_purged);
+#else
/* Objects sent with sendfile */
varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile", stats->n_objsendfile);
/* Objects sent with write */
varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write", stats->n_objwrite);
/* Objects overflowing workspace */
varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", stats->n_objoverflow);
+#endif
}
#if HAVE_VARNISH_V2
/* N duplicate purges removed */
varnish_submit_derive (conf->instance, "purge", "total_operations", "duplicate", stats->n_purge_dups);
}
-#else
+#endif
+#if HAVE_VARNISH_V3
if (conf->collect_ban)
{
/* N total active bans */
varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", stats->n_ban_dups);
}
#endif
+#if HAVE_VARNISH_V4
+ if (conf->collect_ban)
+ {
+ /* N total active bans */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "total", stats->bans);
+ /* N new bans added */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "added", stats->bans_added);
+ /* N bans using obj */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "obj", stats->bans_obj);
+ /* N bans using req */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "req", stats->bans_req);
+ /* N new bans completed */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "completed", stats->bans_completed);
+ /* N old bans deleted */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", stats->bans_deleted);
+ /* N objects tested */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "tested", stats->bans_tested);
+ /* N duplicate bans removed */
+ varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", stats->bans_dups);
+ }
+#endif
if (conf->collect_session)
{
varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline", stats->sess_pipeline);
/* Session Read Ahead */
varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", stats->sess_readahead);
+#if HAVE_VARNISH_V4
+ /* Sessions accepted */
+ varnish_submit_derive (conf->instance, "session", "total_operations", "accepted", stats->sess_conn);
+ /* Sessions dropped for thread */
+ varnish_submit_derive (conf->instance, "session", "total_operations", "dropped", stats->sess_drop);
+ /* Sessions accept failure */
+ varnish_submit_derive (conf->instance, "session", "total_operations", "failed", stats->sess_fail);
+ /* Sessions pipe overflow */
+ varnish_submit_derive (conf->instance, "session", "total_operations", "overflow", stats->sess_pipe_overflow);
+ /* Sessions queued for thread */
+ varnish_submit_derive (conf->instance, "session", "total_operations", "queued", stats->sess_queued);
+#else
/* Session Linger */
varnish_submit_derive (conf->instance, "session", "total_operations", "linger", stats->sess_linger);
+#endif
/* Session herd */
varnish_submit_derive (conf->instance, "session", "total_operations", "herd", stats->sess_herd);
}
if (conf->collect_struct)
{
+#if !HAVE_VARNISH_V4
/* N struct sess_mem */
varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem", stats->n_sess_mem);
/* N struct sess */
varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess", stats->n_sess);
+#endif
/* N struct object */
varnish_submit_gauge (conf->instance, "struct", "objects", "object", stats->n_object);
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
/* N unresurrected objects */
varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject", stats->n_vampireobject);
/* N struct objectcore */
varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore", stats->n_objectcore);
+ /* N struct waitinglist */
+ varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist", stats->n_waitinglist);
#endif
/* N struct objecthead */
varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead", stats->n_objecthead);
varnish_submit_derive (conf->instance, "totals", "total_operations", "pass", stats->s_pass);
/* Total fetch */
varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", stats->s_fetch);
+#if HAVE_VARNISH_V4
+ /* Total synth */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth", stats->s_synth);
+ /* Request header bytes */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header", stats->s_req_hdrbytes);
+ /* Request body byte */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body", stats->s_req_bodybytes);
+ /* Response header bytes */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header", stats->s_resp_hdrbytes);
+ /* Response body byte */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body", stats->s_resp_bodybytes);
+ /* Pipe request header bytes */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header", stats->s_pipe_hdrbytes);
+ /* Piped bytes from client */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in", stats->s_pipe_in);
+ /* Piped bytes to client */
+ varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out", stats->s_pipe_out);
+ /* Number of purge operations */
+ varnish_submit_derive (conf->instance, "totals", "total_operations", "purges", stats->n_purges);
+#else
/* Total header bytes */
varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", stats->s_hdrbytes);
/* Total body byte */
varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes", stats->s_bodybytes);
+#endif
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+ /* Gzip operations */
+ varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip", stats->n_gzip);
+ /* Gunzip operations */
+ varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip", stats->n_gunzip);
+#endif
}
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
if (conf->collect_uptime)
{
/* Client uptime */
varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl", stats->n_vcl_avail);
/* N vcl discarded */
varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", stats->n_vcl_discard);
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+ /* Loaded VMODs */
+ varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod", stats->vmods);
+#endif
}
if (conf->collect_workers)
{
+#ifdef HAVE_VARNISH_V4
+ /* total number of threads */
+ varnish_submit_gauge (conf->instance, "workers", "threads", "worker", stats->threads);
+ /* threads created */
+ varnish_submit_derive (conf->instance, "workers", "total_threads", "created", stats->threads_created);
+ /* thread creation failed */
+ varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", stats->threads_failed);
+ /* threads hit max */
+ varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", stats->threads_limited);
+ /* threads destroyed */
+ varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", stats->threads_destroyed);
+ /* length of session queue */
+ varnish_submit_derive (conf->instance, "workers", "queue_length", "threads", stats->thread_queue_len);
+#else
/* worker threads */
varnish_submit_gauge (conf->instance, "workers", "threads", "worker", stats->n_wrk);
/* worker threads created */
/* worker threads limited */
varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", stats->n_wrk_max);
/* dropped work requests */
- varnish_submit_derive (conf->instance, "workers", "total_requests", "dropped", stats->n_wrk_drop);
+ varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", stats->n_wrk_drop);
#ifdef HAVE_VARNISH_V2
/* queued work requests */
varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", stats->n_wrk_queue);
/* overflowed work requests */
varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", stats->n_wrk_overflow);
-#else
+#else /* HAVE_VARNISH_V3 */
/* queued work requests */
varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", stats->n_wrk_queued);
/* work request queue length */
varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", stats->n_wrk_lqueue);
#endif
+#endif
+ }
+
+#if HAVE_VARNISH_V4
+ if (conf->collect_vsm)
+ {
+ /* Free VSM space */
+ varnish_submit_gauge (conf->instance, "vsm", "bytes", "free", stats->vsm_free);
+ /* Used VSM space */
+ varnish_submit_gauge (conf->instance, "vsm", "bytes", "used", stats->vsm_used);
+ /* Cooling VSM space */
+ varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling", stats->vsm_cooling);
+ /* Overflow VSM space */
+ varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow", stats->vsm_overflow);
+ /* Total overflowed VSM space */
+ varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", stats->vsm_overflowed);
}
+#endif
+
} /* }}} void varnish_monitor */
-#if HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
static int varnish_read (user_data_t *ud) /* {{{ */
{
struct VSM_data *vd;
conf = ud->data;
vd = VSM_New();
+#if HAVE_VARNISH_V3
VSC_Setup(vd);
+#endif
if (conf->instance != NULL)
{
}
}
+#if HAVE_VARNISH_V3
if (VSC_Open (vd, /* diag = */ 1))
+#else /* if HAVE_VARNISH_V4 */
+ if (VSM_Open (vd))
+#endif
{
ERROR ("varnish plugin: Unable to load statistics.");
return (-1);
}
+#if HAVE_VARNISH_V3
stats = VSC_Main(vd);
+#else /* if HAVE_VARNISH_V4 */
+ stats = VSC_Main(vd, NULL);
+#endif
varnish_monitor (conf, stats);
VSM_Close (vd);
conf->collect_sms = 0;
conf->collect_struct = 0;
conf->collect_totals = 0;
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
conf->collect_uptime = 0;
#endif
conf->collect_vcl = 0;
conf->collect_workers = 0;
+#if HAVE_VARNISH_V4
+ conf->collect_vsm = 0;
+#endif
return (0);
} /* }}} int varnish_config_apply_default */
cf_util_get_boolean (child, &conf->collect_struct);
else if (strcasecmp ("CollectTotals", child->key) == 0)
cf_util_get_boolean (child, &conf->collect_totals);
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
else if (strcasecmp ("CollectUptime", child->key) == 0)
cf_util_get_boolean (child, &conf->collect_uptime);
#endif
cf_util_get_boolean (child, &conf->collect_vcl);
else if (strcasecmp ("CollectWorkers", child->key) == 0)
cf_util_get_boolean (child, &conf->collect_workers);
+#if HAVE_VARNISH_V4
+ else if (strcasecmp ("CollectVSM", child->key) == 0)
+ cf_util_get_boolean (child, &conf->collect_vsm);
+#endif
else
{
WARNING ("Varnish plugin: Ignoring unknown "
#endif
&& !conf->collect_struct
&& !conf->collect_totals
-#ifdef HAVE_VARNISH_V3
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
&& !conf->collect_uptime
#endif
&& !conf->collect_vcl
- && !conf->collect_workers)
+ && !conf->collect_workers
+#if HAVE_VARNISH_V4
+ && !conf->collect_vsm
+#endif
+ )
{
WARNING ("Varnish plugin: No metric has been configured for "
"instance \"%s\". Disabling this instance.",
static int32_t kafka_partition(const rd_kafka_topic_t *, const void *, size_t,
int32_t, void *, void *);
-#ifdef HAVE_LIBRDKAFKA_LOGGER
+#if defined HAVE_LIBRDKAFKA_LOGGER || defined HAVE_LIBRDKAFKA_LOG_CB
static void kafka_log(const rd_kafka_t *, int, const char *, const char *);
static void kafka_log(const rd_kafka_t *rkt, int level,
#include "configfile.h"
#include <pthread.h>
-#include <credis.h>
+#include <sys/time.h>
+#include <hiredis/hiredis.h>
struct wr_node_s
{
char *host;
int port;
- int timeout;
+ struct timeval timeout;
- REDIS conn;
+ redisContext *conn;
pthread_mutex_t lock;
};
typedef struct wr_node_s wr_node_t;
char ident[512];
char key[512];
char value[512];
+ char time[24];
size_t value_size;
char *value_ptr;
int status;
+ redisReply *rr;
int i;
status = FORMAT_VL (ident, sizeof (ident), vl);
if (status != 0)
return (status);
ssnprintf (key, sizeof (key), "collectd/%s", ident);
+ ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
memset (value, 0, sizeof (value));
value_size = sizeof (value);
} \
} while (0)
- APPEND ("%lu", (unsigned long) vl->time);
+ APPEND (time);
+ APPEND (":");
+
for (i = 0; i < ds->ds_num; i++)
{
if (ds->ds[i].type == DS_TYPE_COUNTER)
if (node->conn == NULL)
{
- node->conn = credis_connect (node->host, node->port, node->timeout);
+ node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout);
if (node->conn == NULL)
{
ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed.",
}
}
- /* "credis_zadd" doesn't handle a NULL pointer gracefully, so I'd rather
- * have a meaningful assertion message than a normal segmentation fault. */
assert (node->conn != NULL);
- status = credis_zadd (node->conn, key, (double) vl->time, value);
+ rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value);
+ if (rr==NULL)
+ WARNING("ZADD command error. key:%s", key);
- credis_sadd (node->conn, "collectd/values", ident);
+ rr = redisCommand (node->conn, "SADD collectd/values %s", ident);
+ if (rr==NULL)
+ WARNING("SADD command error. ident:%s", ident);
pthread_mutex_unlock (&node->lock);
if (node->conn != NULL)
{
- credis_close (node->conn);
+ redisFree (node->conn);
node->conn = NULL;
}
static int wr_config_node (oconfig_item_t *ci) /* {{{ */
{
wr_node_t *node;
+ int timeout;
int status;
int i;
memset (node, 0, sizeof (*node));
node->host = NULL;
node->port = 0;
- node->timeout = 1000;
+ node->timeout.tv_sec = 0;
+ node->timeout.tv_usec = 1000;
node->conn = NULL;
pthread_mutex_init (&node->lock, /* attr = */ NULL);
status = 0;
}
}
- else if (strcasecmp ("Timeout", child->key) == 0)
- status = cf_util_get_int (child, &node->timeout);
+ else if (strcasecmp ("Timeout", child->key) == 0) {
+ status = cf_util_get_int (child, &timeout);
+ if (status == 0) node->timeout.tv_usec = timeout;
+ }
else
WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
child->key);
#define RIEMANN_HOST "localhost"
#define RIEMANN_PORT "5555"
#define RIEMANN_TTL_FACTOR 2.0
+#define RIEMANN_BATCH_MAX 8192
int write_riemann_threshold_check(const data_set_t *, const value_list_t *, int *);
struct riemann_host {
char *name;
char *event_service_prefix;
-#define F_CONNECT 0x01
+#define F_CONNECT 0x01
uint8_t flags;
- pthread_mutex_t lock;
- _Bool notifications;
- _Bool check_thresholds;
+ pthread_mutex_t lock;
+ _Bool batch_mode;
+ _Bool notifications;
+ _Bool check_thresholds;
_Bool store_rates;
_Bool always_append_ds;
char *node;
char *service;
_Bool use_tcp;
- int s;
+ int s;
double ttl_factor;
-
- int reference_count;
+ Msg *batch_msg;
+ cdtime_t batch_init;
+ int batch_max;
+ int reference_count;
};
static char **riemann_tags;
return (msg);
} /* }}} Msg *riemann_value_list_to_protobuf */
+
+/*
+ * Always call while holding host->lock !
+ */
+static int riemann_batch_flush_nolock (cdtime_t timeout,
+ struct riemann_host *host)
+{
+ cdtime_t now;
+ int status = 0;
+
+ if (timeout > 0) {
+ now = cdtime ();
+ if ((host->batch_init + timeout) > now)
+ return status;
+ }
+ riemann_send_msg(host, host->batch_msg);
+ riemann_msg_protobuf_free(host->batch_msg);
+
+ if (host->use_tcp && ((status = riemann_recv_ack(host)) != 0))
+ riemann_disconnect (host);
+
+ host->batch_init = cdtime();
+ host->batch_msg = NULL;
+ return status;
+}
+
+static int riemann_batch_flush (cdtime_t timeout,
+ const char *identifier __attribute__((unused)),
+ user_data_t *user_data)
+{
+ struct riemann_host *host;
+ int status;
+
+ if (user_data == NULL)
+ return (-EINVAL);
+
+ host = user_data->data;
+ pthread_mutex_lock (&host->lock);
+ status = riemann_batch_flush_nolock (timeout, host);
+ if (status != 0)
+ ERROR ("write_riemann plugin: riemann_send failed with status %i",
+ status);
+
+ pthread_mutex_unlock(&host->lock);
+ return status;
+}
+
+static int riemann_batch_add_value_list (struct riemann_host *host, /* {{{ */
+ data_set_t const *ds,
+ value_list_t const *vl,
+ int *statuses)
+{
+ size_t i;
+ Event **events;
+ Msg *msg;
+ size_t len;
+ int ret;
+
+ msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
+ if (msg == NULL)
+ return -1;
+
+ pthread_mutex_lock(&host->lock);
+
+ if (host->batch_msg == NULL) {
+ host->batch_msg = msg;
+ } else {
+ len = msg->n_events + host->batch_msg->n_events;
+ events = realloc(host->batch_msg->events,
+ (len * sizeof(*host->batch_msg->events)));
+ if (events == NULL) {
+ pthread_mutex_unlock(&host->lock);
+ ERROR ("write_riemann plugin: out of memory");
+ riemann_msg_protobuf_free (msg);
+ return -1;
+ }
+ host->batch_msg->events = events;
+
+ for (i = host->batch_msg->n_events; i < len; i++)
+ host->batch_msg->events[i] = msg->events[i - host->batch_msg->n_events];
+
+ host->batch_msg->n_events = len;
+ sfree (msg->events);
+ msg->n_events = 0;
+ sfree (msg);
+ }
+
+ len = msg__get_packed_size(host->batch_msg);
+ ret = 0;
+ if (len >= host->batch_max) {
+ ret = riemann_batch_flush_nolock(0, host);
+ }
+
+ pthread_mutex_unlock(&host->lock);
+ return ret;
+} /* }}} Msg *riemann_batch_add_value_list */
+
static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{ */
{
int status;
if (!host->notifications)
return 0;
+ /*
+ * Never batch for notifications, send them ASAP
+ */
msg = riemann_notification_to_protobuf (host, n);
if (msg == NULL)
return (-1);
const value_list_t *vl,
user_data_t *ud)
{
- int status;
+ int status = 0;
int statuses[vl->values_len];
struct riemann_host *host = ud->data;
Msg *msg;
if (host->check_thresholds)
write_riemann_threshold_check(ds, vl, statuses);
- msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
- if (msg == NULL)
- return (-1);
- status = riemann_send (host, msg);
- if (status != 0)
- ERROR ("write_riemann plugin: riemann_send failed with status %i",
- status);
+ if (host->use_tcp == 1 && host->batch_mode) {
- riemann_msg_protobuf_free (msg);
+ riemann_batch_add_value_list (host, ds, vl, statuses);
+
+
+ } else {
+
+ msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
+ if (msg == NULL)
+ return (-1);
+
+ status = riemann_send (host, msg);
+ if (status != 0)
+ ERROR ("write_riemann plugin: riemann_send failed with status %i",
+ status);
+
+ riemann_msg_protobuf_free (msg);
+ }
return status;
} /* }}} int riemann_write */
host->store_rates = 1;
host->always_append_ds = 0;
host->use_tcp = 0;
+ host->batch_mode = 0;
+ host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
+ host->batch_init = cdtime();
host->ttl_factor = RIEMANN_TTL_FACTOR;
status = cf_util_get_string (ci, &host->name);
status = cf_util_get_boolean(child, &host->check_thresholds);
if (status != 0)
break;
+ } else if (strcasecmp ("Batch", child->key) == 0) {
+ status = cf_util_get_boolean(child, &host->batch_mode);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
+ status = cf_util_get_int(child, &host->batch_max);
+ if (status != 0)
+ break;
} else if (strcasecmp ("Port", child->key) == 0) {
status = cf_util_get_service (child, &host->service);
if (status != 0) {
pthread_mutex_lock (&host->lock);
status = plugin_register_write (callback_name, riemann_write, &ud);
+
+ if (host->use_tcp == 1 && host->batch_mode) {
+ ud.free_func = NULL;
+ plugin_register_flush(callback_name, riemann_batch_flush, &ud);
+ }
if (status != 0)
WARNING ("write_riemann plugin: plugin_register_write (\"%s\") "
"failed with status %i.",
ssnprintf(ret, ret_len, "%s%s.%s.%s",
prefix, vl->plugin, vl->plugin_instance, vl->type);
} else {
- ssnprintf(ret, ret_len, "%s%s.%s.%s",
- prefix, vl->plugin, vl->plugin_instance, vl->type_instance);
+ ssnprintf(ret, ret_len, "%s%s.%s.%s.%s",
+ prefix, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance);
}
sfree(temp);