+2017-06-06, Version 5.7.2
+ * Build system: The Notify Email plugin is no longer linked with
+ indirect dependencies. Thanks to Marc Fournier.
+ * collectd: A race condition when calculating a metric's rate has been
+ fixed. Thanks to Florian Forster. #1193
+ * AMQP, Exec, UnixSock, Write Kafka plugins: Parsing of the PUTVAL
+ command with multiple values has been fixed. Thanks to Florian
+ Forster. #2274
+ * AMQP plugin: The "ExchangeType" option is now also valid for
+ publishers. Thanks to Florian Forster. #2286
+ * BIND plugin: Fix parsing of the sample time provided by BIND.
+ Previously, the time was assumed to be in the local timezone when in
+ fact it was in UTC. Thanks to Ed Ravin. #1268
+ * BIND plugin: Memory leaks have been fixed. Thanks to Ruben Kerkhof.
+ #2303
+ * cURL-JSON plugin: Handling of arrays has been fixed. Thanks to Florian
+ Forster. #2266
+ * DPDKStat plugin: Error handling during initialization has been
+ improved. Thanks to Ruben Kerkhof.
+ * DPDKStat plugin: Handling of a number of metrics has been improved,
+ for example "rx_q0bytes". Thanks to Przemyslaw Szczerbik. #2167
+ * Intel RDT plugin: Configuration handling has been changed to be more
+ graceful. Thanks to Maryam Tahhan. #2165
+ * Log Logstash plugin: If writing the log entry fails, print it to
+ "STDERR" instead. Thanks to Marc Fournier.
+ * LogFile plugin: If writing to the file fails, print log messages on
+ "STDERR" instead. Thanks to Marc Fournier.
+ * memcachec, Tail plugins: A resource leak in the matching
+ infrastructure has been fixed. Thanks to Krzysztof Matczak. #2192
+ * MQTT plugin: Invalid symbols in topic names are now replaced and a
+ resource leak has been fixed. Thanks to Denys Fedoryshchenko. #2123
+ * Network plugin: A potential endless-loop has been fixed. This can be
+ triggered remotely by sending a signed network packet to a server
+ which is not set up to check signatures. Thanks to Marcin Kozlowski
+ and Pavel Rochnyack. #2174, #2233, CVE-2017-7401
+ * Perl plugin: A potential double-free has been fixed. Thanks to Florian
+ Forster. #2278
+ * Processes plugin: A compilation error on AIX has been fixed. Thanks to
+ Pavel Rochnyack. #2210
+ * SMART plugin: A check for the "CAP_SYS_RAWIO" capability has been
+ added. Thanks to Marc Fournier.
+ * Write Graphite plugin: Error handling in the case that calculating a
+ metric's rate fails has been improved. Previously, the raw counter
+ values were sent to Graphite. Thanks to Iain Buclaw. #2209
+ * Write Prometheus plugin: An incorrect use of "realloc(3)" has been
+ fixed. Thanks to Florian Forster. #2275
+
+2017-01-23, Version 5.7.1
+ * collectd: Handling of boolean configuration options has been unified.
+ Thanks to Sebastian Harl. #2083, #2098
+ * collectd: Reporting of internal statistics has been fixed. Thanks to
+ Florian Forster. #2108
+ * collectd, various plugins: Bugs and issues reported by scan-build and
+ coverity-scan have been fixed. Thanks to Ruben Kerkhof and Florian
+ Forster.
+ * Build system: Parallel build have been fixed. Thanks to Ruben Kerkhof.
+ #2110
+ * DPDKStat plugin: Portability issues and a double-close bug have been
+ fixed. Thanks to Ruben Kerkhof and Marc Fournier.
+ * Intel RDT plugin: A check for the libpqos library version has been
+ added. Thanks to Serhiy Pshyk.
+ * NetApp plugin: Compilation problems have been corrected. Thanks to
+ Florian Forster. #2120
+ * Write Prometheus plugin: A memory leak has been fixed. Thanks to Ruben
+ Kerkhof.
+
2016-12-12, Version 5.7.0
* Documentation: The Turbostat plugin section has been improved. Thanks
to Florian Forster
embedded HTTP server, in a format compatible with Prometheus'
collectd_exporter. Thanks to Florian Forster. #1967
+2017-10-06, Version 5.6.3
+ * collectd: support for boolean string config values has been
+ reintroduced. Thanks to Sebastian Harl. #2083, #2098
+ * collectd: The capability checking has been changed to use
+ "cap_get_proc()". Thanks to Marc Fournier. #2151
+ * Documentation: A section documenting ignore lists has been added to
+ collectd.conf(5). Thanks to Florian Forster.
+ * AMQP plugin: The "ExchangeType" option is now also valid for
+ publishers. Thanks to Florian Forster. #2286
+ * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx, Write HTTP
+ plugins: Handling of URLs that redirect elsewhere has been fixed.
+ Thanks to Pavel Rochnyack. #2328
+ * BIND plugin: Fix parsing of the sample time provided by BIND.
+ Previously, the time was assumed to be in the local time zone when in
+ fact it was in UTC. Thanks to Ed Ravin. #1268
+ * BIND plugin: Memory leaks have been fixed. Thanks to Ruben Kerkhof.
+ #2303
+ * Chrony plugin: Build flags have been fixed. Thanks to Thomas Jost and
+ Marc Fournier. #2133
+ * cURL-JSON plugin: The timeout value has been changed to default to the
+ collection interval. This fixes a regression. Thanks to Marc Fournier.
+ * cURL-JSON plugin: Handling of arrays has been fixed. Thanks to Florian
+ Forster. #2266
+ * DBI plugin: Memory leaks at shutdown have been fixes. Thanks to Pavel
+ Rochnyack and Florian Forster.
+ * E-Mail, Exec, UnixSock plugins: Group ID lookup on systems with many
+ groups has been fixed. Thanks to Ruben Kerkhof and Florian Forster.
+ #2208
+ * IPC plugin: A compilation error on AIX has been fixed. Thanks to Pavel
+ Rochnyack. #2305
+ * LogFile plugin: If writing to the file fails, print log messages on
+ "STDERR" instead. Thanks to Marc Fournier.
+ * Log Logstash plugin: If writing the log entry fails, print it to
+ "STDERR" instead. Thanks to Marc Fournier.
+ * memcachec, Tail plugins: A resource leak in the matching
+ infrastructure has been fixed. Thanks to Krzysztof Matczak. #2192
+ * MQTT plugin: Invalid symbols in topic names are now replaced and a
+ resource leak has been fixed. Thanks to Denys Fedoryshchenko. #2123
+ * Network plugin: A potential endless-loop has been fixed. This can be
+ triggered remotely by sending a signed network packet to a server
+ which is not set up to check signatures. Thanks to Marcin Kozlowski
+ and Pavel Rochnyack. #2174, #2233, CVE-2017-7401
+ * Network plugin: A use-after-free has been fixed. Thanks to Pavel
+ Rochnyack. #2375
+ * Notify Email plugin: The plugin is no longer explicitly linked against
+ libssl and libcrypto, relies on libesmtp being linked correctly.
+ Thanks to Marc Fournier. Debian#852924
+ * NTPd plugin: Calculation of loop offset and error has been fixed.
+ Thanks to Neil Wilson. #2188
+ * OpenLDAP plugin: An incorrect use of the ldap library, leading to a
+ crash, has been fixed. Thanks to Marc Fournier. #2331
+ * Perl plugin: A potential double-free has been fixed. Thanks to Florian
+ Forster. #2278
+ * Perl plugin: Print an error when an incorrect configuration is
+ encountered. Thanks to Pavel Rochnyack. #927
+ * RRDtool plugin: Incorrect handling of the flushes timeout option has
+ been fixed. Handling of the "RandomTimeout" has been fixed. Thanks to
+ Pavel Rochnyack. #2363
+ * SMART plugin: Some warning messages have been removed and the code has
+ been cleaned up. Thanks to Florian Forster. #2062
+ * SMART plugin: A check for the "CAP_SYS_RAWIO" capability has been
+ added. Thanks to Marc Fournier.
+ * SNMP plugin: A double free has been fixed. Thanks to Pavel Rochnyack.
+ #2291
+ * Write Graphite plugin: Error handling in the case that calculating a
+ metric's rate fails has been improved. Previously, the raw counter
+ values were sent to Graphite. Thanks to Iain Buclaw. #2209
+ * Write Kafka plugin: A 32 bit random number is now used when formatting
+ a random key. Thanks to Florian Forster. #2074
+
+
2016-11-30, Version 5.6.2
* collectd: A compile error on AIX has been fixed: "MSG_DONTWAIT" is not
available on AIX. Thanks to Chao Yang.
- write_mongodb
Sends data to MongoDB, a NoSQL database.
+ - write_prometheus
+ Publish values using an embedded HTTP server, in a format compatible
+ with Prometheus' collectd_exporter.
+
- write_redis
Sends the values to a Redis key-value database server.
Used by the `memcachec' plugin to connect to a memcache daemon.
<http://tangent.org/552/libmemcached.html>
+ * libmicrohttpd (optional)
+ Used by the write_prometheus plugin to run an http daemon.
+ <http://www.gnu.org/software/libmicrohttpd/>
+
* libmnl (optional)
Used by the `netlink' plugin.
<http://www.netfilter.org/projects/libmnl/>
# For the turbostat plugin
-have_asm_msrindex_h="no"
-AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"])
-
-if test "x$have_asm_msrindex_h" = "xyes"
-then
- AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY],
- [c_cv_have_usable_asm_msrindex_h],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include<asm/msr-index.h>
-]]],
-[[[
-int y = MSR_PKG_C10_RESIDENCY;
-return(y);
-]]]
- )],
- [c_cv_have_usable_asm_msrindex_h="yes"],
- [c_cv_have_usable_asm_msrindex_h="no"],
- )
- )
-fi
-
-have_cpuid_h="no"
-AC_CHECK_HEADERS(cpuid.h, [have_cpuid_h="yes"])
+AC_CHECK_HEADERS([cpuid.h],
+ [have_cpuid_h="yes"],
+ [have_cpuid_h="no (cpuid.h not found)"]
+)
have_capability="yes"
AC_CHECK_HEADERS(sys/capability.h,
[have_capability="yes"],
[have_capability="no (<sys/capability.h> not found)"])
if test "x$have_capability" = "xyes"; then
-AC_CHECK_LIB(cap, cap_get_bound,
+AC_CHECK_LIB(cap, cap_get_proc,
+ [have_capability="yes"],
+ [have_capability="no (cap_get_proc() not found)"])
+fi
+if test "x$have_capability" = "xyes"; then
+AC_CHECK_DECL([CAP_IS_SUPPORTED],
[have_capability="yes"],
- [have_capability="no (cap_get_bound() not found)"])
+ [have_capability="no (CAP_IS_SUPPORTED not found)"],
+ [[#include <sys/capability.h>]])
fi
if test "x$have_capability" = "xyes"; then
- AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_bound() (-lcap).])
+ AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_proc() (-lcap).])
fi
AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes")
fi
# }}} Check for strptime
+# Check for timegm {{{
+
+# These checks need -Werror because implicit function declarations are only a
+# warning ...
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+
+AC_CACHE_CHECK([for timegm],
+ [c_cv_have_timegm],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+[[[
+#if STRPTIME_NEEDS_STANDARDS
+# ifndef _ISOC99_SOURCE
+# define _ISOC99_SOURCE 1
+# endif
+# ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+# endif
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500
+# endif
+#endif
+#include <time.h>
+]]],
+[[[
+ time_t t = timegm(&(struct tm){0});
+ if (t == ((time_t) -1)) {
+ return 1;
+ }
+]]]
+ )],
+ [c_cv_have_timegm="yes"],
+ [c_cv_have_timegm="no"]
+ )
+)
+
+if test "x$c_cv_have_timegm" != "xyes"
+then
+ AC_CACHE_CHECK([for timegm with _BSD_SOURCE],
+ [c_cv_have_timegm_bsd],
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+[[[
+#if STRPTIME_NEEDS_STANDARDS
+# ifndef _ISOC99_SOURCE
+# define _ISOC99_SOURCE 1
+# endif
+# ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+# endif
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 500
+# endif
+#endif
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE 1
+#endif
+#include <time.h>
+]]],
+[[[
+ time_t t = timegm(&(struct tm){0});
+ if (t == ((time_t) -1)) {
+ return 1;
+ }
+]]]
+ )],
+ [c_cv_have_timegm_bsd="yes"
+ c_cv_have_timegm="yes"],
+ [c_cv_have_timegm_bsd="no"]
+ )
+ )
+fi
+
+if test "x$c_cv_have_timegm" = "xyes"
+then
+ AC_DEFINE(HAVE_TIMEGM, 1, [Define if the timegm(3) function is available.])
+ if test "x$c_cv_have_timegm_bsd" = "xyes"
+ then
+ AC_DEFINE(TIMEGM_NEEDS_BSD, 1, [Set to true if timegm is only exported in BSD mode.])
+ fi
+fi
+
+CFLAGS="$SAVE_CFLAGS"
+# }}} Check for timegm
+
AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
if test "x$have_swapctl" = "xyes"; then
AC_CACHE_CHECK([whether swapctl takes two arguments],
# --with-libdpdk {{{
AC_ARG_VAR([LIBDPDK_CPPFLAGS], [Preprocessor flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_CFLAGS], [Compiler flags for libdpdk])
AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_LIBS], [Libraries to link for libdpdk])
-AC_ARG_WITH([libdpdk], [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])])
+AC_ARG_WITH([libdpdk],
+ [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])],
+ [with_libdpdk="$withval"],
+ [with_libdpdk="yes"]
+)
-if test "x$with_libdpdk" != "xno"
-then
- if test "x$LIBDPDK_CPPFLAGS" = "x"
- then
- LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
- fi
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
- AC_CHECK_HEADERS([rte_config.h],
- [with_libdpdk="yes"],
- [with_libdpdk="no (rte_config.h not found)"]
- )
- CPPFLAGS="$SAVE_CPPFLAGS"
+if test "x$with_libdpdk" != "xno"; then
+ PKG_CHECK_MODULES([DPDK], [libdpdk], [],
+ [AC_MSG_NOTICE([no DPDK pkg-config, using defaults])])
+ if test "x$LIBDPDK_CPPFLAGS" = "x"; then
+ LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
+ fi
+ if test "x$LIBDPDK_CFLAGS" = "x"; then
+ LIBDPDK_CFLAGS="$DPDK_CFLAGS"
+ LIBDPDK_CPPFLAGS="$LIBDPDK_CPPFLAGS $DPDK_CFLAGS"
+ fi
+ if test "x$LIBDPDK_LIBS" = "x"; then
+ if test "x$DPDK_LIBS" != "x"; then
+ LIBDPDK_LIBS="$DPDK_LIBS"
+ else
+ LIBDPDK_LIBS="-ldpdk"
+ fi
+ fi
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$LIBDPDK_CFLAGS $CFLAGS"
+ AC_CHECK_HEADERS([rte_config.h],
+ [
+ with_libdpdk="yes"
+ AC_PREPROC_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+ #include <rte_version.h>
+ #if RTE_VERSION < RTE_VERSION_NUM(16,7,0,0)
+ #error "required DPDK >= 16.07"
+ #endif
+ ]]
+ )
+ ],
+ [dpdk_keepalive="yes"],
+ [dpdk_keepalive="no (DPDK version < 16.07)"]
+ )
+ ],
+ [with_libdpdk="no (rte_config.h not found)"]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ CFLAGS="$SAVE_CFLAGS"
fi
-if test "x$with_libdpdk" = "xyes"
-then
- SAVE_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
- AC_CHECK_LIB([dpdk], [rte_eal_init],
- [with_libdpdk="yes"],
- [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
- )
- LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_libdpdk" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
+ AC_CHECK_LIB([dpdk], [rte_eal_init],
+ [with_libdpdk="yes"],
+ [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
+ )
+ LDFLAGS="$SAVE_LDFLAGS"
fi
# }}}
fi
if test "x$with_libpqos" = "xyes"
then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
+ AC_RUN_IFELSE([AC_LANG_PROGRAM(
+ [[#include <pqos.h>]],
+ [[return !(PQOS_VERSION >= 106)]])],
+ [with_libpqos="yes"], [with_libpqos="no (pqos library version 1.06 or higher is required)"])
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libpqos" = "xyes"
+then
BUILD_WITH_LIBPQOS_CPPFLAGS="$with_libpqos_cppflags"
BUILD_WITH_LIBPQOS_LDFLAGS="$with_libpqos_ldflags"
BUILD_WITH_LIBPQOS_LIBS="-lpqos"
then
plugin_ipvs="yes"
fi
- if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes"
- then
+ if test "x$have_cpuid_h" = "xyes"; then
plugin_turbostat="yes"
fi
%define with_write_log 0%{!?_without_write_log:1}
%define with_write_prometheus 0%{!?_without_write_prometheus:1}
%define with_write_redis 0%{!?_without_write_redis:1}
+%define with_write_riemann 0%{!?_without_write_riemann:1}
%define with_write_sensu 0%{!?_without_write_sensu:1}
%define with_write_tsdb 0%{!?_without_write_tsdb:1}
%define with_xmms 0%{!?_without_xmms:0%{?_has_xmms}}
%define with_write_kafka 0%{!?_without_write_kafka:0}
# plugin write_mongodb disabled, requires libmongoc
%define with_write_mongodb 0%{!?_without_write_mongodb:0}
-# plugin write_riemann disabled, requires a new enough riemann_c_client
-%define with_write_riemann 0%{!?_without_write_riemann:0}
# plugin xencpu disabled, requires xen-devel from non-default repo
%define with_xencpu 0%{!?_without_xencpu:0}
# plugin zone disabled, requires Solaris
%define with_turbostat 0
%define with_write_prometheus 0
%define with_write_redis 0
+%define with_write_riemann 0
%endif
# Plugins not buildable on RHEL < 7
%define with_redis 0
%define with_rrdcached 0
%define with_write_redis 0
+%define with_write_riemann 0
%define with_xmms 0
%endif
Summary: Statistics collection and monitoring daemon
Name: collectd
-Version: 5.7.0
-Release: 2%{?dist}
+Version: 5.7.1
+Release: 3%{?dist}
URL: https://collectd.org
Source: https://collectd.org/files/%{name}-%{version}.tar.bz2
License: GPLv2
Vendor: collectd development team <collectd@verplant.org>
%if 0%{?fedora} || 0%{?rhel} >= 7
+BuildRequires: xfsprogs-devel
%{?systemd_requires}
BuildRequires: systemd
%else
Summary: Java plugin for collectd
Group: System Environment/Daemons
Requires: %{name}%{?_isa} = %{version}-%{release}
-BuildRequires: java-devel, jpackage-utils
-Requires: java, jpackage-utils
+BuildRequires: java-devel >= 1.6, jpackage-utils >= 1.6
+Requires: java >= 1.6, jpackage-utils >= 1.6
%description java
This plugin for collectd allows plugins to be written in Java and executed
in an embedded JVM.
Summary: riemann plugin for collectd
Group: System Environment/Daemons
Requires: %{name}%{?_isa} = %{version}-%{release}
-BuildRequires: protobuf-c-devel
+BuildRequires: riemann-c-client-devel >= 1.6
%description write_riemann
The riemann plugin submits values to Riemann, an event stream processor.
%endif
%doc contrib/
%changelog
+* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-2
+- Don't enable XFS support on RHEL6, it is missing for i386
+
+* Wed Feb 22 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-2
+- Enable XFS support in df plugin
+- Fix bogus date in changelog
+
+* Sun Jan 01 2017 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.1-1
+- New upstream version
+
* Tue Nov 29 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-2
- Disable redis plugin on RHEL 6, hiredis has been retired from EPEL6
# exec CAP_SETUID CAP_SETGID
# iptables CAP_NET_ADMIN
# ping CAP_NET_RAW
+# smart CAP_SYS_RAWIO
# turbostat CAP_SYS_RAWIO
#
# Example, if you use the iptables plugin alongside the dns or ping plugin:
# By default, drop all capabilities:
CapabilityBoundingSet=
-NoNewPrivileges=true
-
# 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
pkglib_LTLIBRARIES += chrony.la
chrony_la_SOURCES = chrony.c
chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+chrony_la_LIBADD = -lm
endif
if BUILD_PLUGIN_CONNTRACK
pkglib_LTLIBRARIES += dpdkstat.la
dpdkstat_la_SOURCES = dpdkstat.c
dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
+dpdkstat_la_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS)
dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
-dpdkstat_la_LIBADD = -ldpdk
+dpdkstat_la_LIBADD = $(LIBDPDK_LIBS)
endif
if BUILD_PLUGIN_DRBD
if BUILD_PLUGIN_EXEC
pkglib_LTLIBRARIES += exec.la
exec_la_SOURCES = exec.c
-exec_la_LDFLAGS = $(PLUGIN_LDFLAGS) libcmds.la
+exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+exec_la_LIBADD = libcmds.la
endif
if BUILD_PLUGIN_ETHSTAT
pkglib_LTLIBRARIES += notify_email.la
notify_email_la_SOURCES = notify_email.c
notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-notify_email_la_LIBADD = -lesmtp -lssl -lcrypto
+notify_email_la_LIBADD = -lesmtp
endif
if BUILD_PLUGIN_NOTIFY_NAGIOS
if BUILD_PLUGIN_TURBOSTAT
pkglib_LTLIBRARIES += turbostat.la
-turbostat_la_SOURCES = turbostat.c
+turbostat_la_SOURCES = \
+ turbostat.c \
+ msr-index.h
turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_UNIXSOCK
pkglib_LTLIBRARIES += unixsock.la
unixsock_la_SOURCES = unixsock.c
-unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS) libcmds.la
+unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+unixsock_la_LIBADD = libcmds.la
endif
if BUILD_PLUGIN_UPTIME
READ_FUNC(average, (inst->sum / ((gauge_t)inst->num)));
READ_FUNC(min, inst->min);
READ_FUNC(max, inst->max);
- READ_FUNC(stddev, sqrt((((gauge_t)inst->num) * inst->squares_sum) -
- (inst->sum * inst->sum)) /
- ((gauge_t)inst->num));
+ READ_FUNC(stddev,
+ sqrt((((gauge_t)inst->num) * inst->squares_sum) -
+ (inst->sum * inst->sum)) /
+ ((gauge_t)inst->num));
}
/* Reset internal state. */
static int agg_config_aggregation(oconfig_item_t *ci) /* {{{ */
{
- aggregation_t *agg;
- _Bool is_valid;
- int status;
-
- agg = calloc(1, sizeof(*agg));
+ aggregation_t *agg = calloc(1, sizeof(*agg));
if (agg == NULL) {
ERROR("aggregation plugin: calloc failed.");
return (-1);
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
+ int status = 0;
if (strcasecmp("Host", child->key) == 0)
- cf_util_get_string_buffer(child, agg->ident.host,
- sizeof(agg->ident.host));
+ status = cf_util_get_string_buffer(child, agg->ident.host,
+ sizeof(agg->ident.host));
else if (strcasecmp("Plugin", child->key) == 0)
- cf_util_get_string_buffer(child, agg->ident.plugin,
- sizeof(agg->ident.plugin));
+ status = cf_util_get_string_buffer(child, agg->ident.plugin,
+ sizeof(agg->ident.plugin));
else if (strcasecmp("PluginInstance", child->key) == 0)
- cf_util_get_string_buffer(child, agg->ident.plugin_instance,
- sizeof(agg->ident.plugin_instance));
+ status = cf_util_get_string_buffer(child, agg->ident.plugin_instance,
+ sizeof(agg->ident.plugin_instance));
else if (strcasecmp("Type", child->key) == 0)
- cf_util_get_string_buffer(child, agg->ident.type,
- sizeof(agg->ident.type));
+ status = cf_util_get_string_buffer(child, agg->ident.type,
+ sizeof(agg->ident.type));
else if (strcasecmp("TypeInstance", child->key) == 0)
- cf_util_get_string_buffer(child, agg->ident.type_instance,
- sizeof(agg->ident.type_instance));
+ status = cf_util_get_string_buffer(child, agg->ident.type_instance,
+ sizeof(agg->ident.type_instance));
else if (strcasecmp("SetHost", child->key) == 0)
- cf_util_get_string(child, &agg->set_host);
+ status = cf_util_get_string(child, &agg->set_host);
else if (strcasecmp("SetPlugin", child->key) == 0)
- cf_util_get_string(child, &agg->set_plugin);
+ status = cf_util_get_string(child, &agg->set_plugin);
else if (strcasecmp("SetPluginInstance", child->key) == 0)
- cf_util_get_string(child, &agg->set_plugin_instance);
+ status = cf_util_get_string(child, &agg->set_plugin_instance);
else if (strcasecmp("SetTypeInstance", child->key) == 0)
- cf_util_get_string(child, &agg->set_type_instance);
+ status = cf_util_get_string(child, &agg->set_type_instance);
else if (strcasecmp("GroupBy", child->key) == 0)
- agg_config_handle_group_by(child, agg);
+ status = agg_config_handle_group_by(child, agg);
else if (strcasecmp("CalculateNum", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_num);
+ status = cf_util_get_boolean(child, &agg->calc_num);
else if (strcasecmp("CalculateSum", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_sum);
+ status = cf_util_get_boolean(child, &agg->calc_sum);
else if (strcasecmp("CalculateAverage", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_average);
+ status = cf_util_get_boolean(child, &agg->calc_average);
else if (strcasecmp("CalculateMinimum", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_min);
+ status = cf_util_get_boolean(child, &agg->calc_min);
else if (strcasecmp("CalculateMaximum", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_max);
+ status = cf_util_get_boolean(child, &agg->calc_max);
else if (strcasecmp("CalculateStddev", child->key) == 0)
- cf_util_get_boolean(child, &agg->calc_stddev);
+ status = cf_util_get_boolean(child, &agg->calc_stddev);
else
WARNING("aggregation plugin: The \"%s\" key is not allowed inside "
"<Aggregation /> blocks and will be ignored.",
child->key);
- }
+
+ if (status != 0) {
+ sfree(agg);
+ return status;
+ }
+ } /* for (int i = 0; i < ci->children_num; i++) */
if (agg_is_regex(agg->ident.host))
agg->regex_fields |= LU_GROUP_BY_HOST;
agg->regex_fields |= LU_GROUP_BY_TYPE_INSTANCE;
/* Sanity checking */
- is_valid = 1;
+ _Bool is_valid = 1;
if (strcmp("/.*/", agg->ident.type) == 0) /* {{{ */
{
ERROR("aggregation plugin: It appears you did not specify the required "
is_valid = 0;
} /* }}} */
- if (!is_valid) /* {{{ */
- {
+ if (!is_valid) { /* {{{ */
sfree(agg);
return (-1);
} /* }}} */
- status = lookup_add(lookup, &agg->ident, agg->group_by, agg);
+ int status = lookup_add(lookup, &agg->ident, agg->group_by, agg);
if (status != 0) {
ERROR("aggregation plugin: lookup_add failed with status %i.", status);
sfree(agg);
status = cf_util_get_string(child, &conf->password);
else if (strcasecmp("Exchange", child->key) == 0)
status = cf_util_get_string(child, &conf->exchange);
- else if ((strcasecmp("ExchangeType", child->key) == 0) && !publish)
+ else if (strcasecmp("ExchangeType", child->key) == 0)
status = cf_util_get_string(child, &conf->exchange_type);
else if ((strcasecmp("Queue", child->key) == 0) && !publish)
status = cf_util_get_string(child, &conf->queue);
#endif
}
- curl_easy_setopt(st->curl, CURLOPT_URL, st->url);
curl_easy_setopt(st->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(st->curl, CURLOPT_MAXREDIRS, 50L);
assert(st->curl != NULL);
st->apache_buffer_fill = 0;
+
+ curl_easy_setopt(st->curl, CURLOPT_URL, st->url);
+
if (curl_easy_perform(st->curl) != CURLE_OK) {
ERROR("apache: curl_easy_perform failed: %s", st->apache_curl_error);
return (-1);
#endif
}
- curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
}
ascent_buffer_fill = 0;
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
if (curl_easy_perform(curl) != CURLE_OK) {
ERROR("ascent plugin: curl_easy_perform failed: %s", ascent_curl_error);
return (-1);
ssnprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply,
basename);
- status = (int)read_file_contents(filename, buffer, buffer_size);
+ status = (int)read_file_contents(filename, buffer, buffer_size - 1);
if (status < 0)
return status;
+ buffer[status] = '\0';
+
strstripnewline(buffer);
return 0;
} /* }}} int sysfs_file_to_buffer */
char const *power_supply, char const *basename,
gauge_t *ret_value) {
int status;
- char buffer[32] = "";
+ char buffer[32];
status =
sysfs_file_to_buffer(dir, power_supply, basename, buffer, sizeof(buffer));
#endif
#endif /* STRPTIME_NEEDS_STANDARDS */
+#if TIMEGM_NEEDS_BSD
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE 1
+#endif
+#endif /* TIMEGM_NEEDS_BSD */
+
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include <time.h>
+
/* Some versions of libcurl don't include this themselves and then don't have
* fd_set available. */
#if HAVE_SYS_SELECT_H
return (-1);
}
- *ret_value = mktime(&tm);
+#if HAVE_TIMEGM
+ time_t t = timegm(&tm);
+ if (t == ((time_t)-1)) {
+ char errbuf[1024];
+ ERROR("bind plugin: timegm() failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+ *ret_value = t;
+#else
+ time_t t = mktime(&tm);
+ if (t == ((time_t)-1)) {
+ char errbuf[1024];
+ ERROR("bind plugin: mktime() failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+ /* mktime assumes that tm is local time. Luckily, it also sets timezone to
+ * the offset used for the conversion, and we undo the conversion to convert
+ * back to UTC. */
+ *ret_value = t - timezone;
+#endif
xmlXPathFreeObject(xpathObj);
return (0);
status = bind_xml_read_gauge(doc, counter, &value.gauge);
else
status = bind_xml_read_derive(doc, counter, &value.derive);
- if (status != 0)
+ if (status != 0) {
+ xmlFree(name);
continue;
+ }
status = (*list_callback)(name, value, current_time, user_data);
if (status == 0)
status = bind_xml_read_gauge(doc, child, &value.gauge);
else
status = bind_xml_read_derive(doc, child, &value.derive);
- if (status != 0)
+ if (status != 0) {
+ xmlFree(attr_name);
continue;
+ }
status = (*list_callback)(attr_name, value, current_time, user_data);
if (status == 0)
num_entries++;
+
+ xmlFree(attr_name);
}
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, bind_curl_callback);
curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, bind_curl_error);
- curl_easy_setopt(curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
#ifdef HAVE_CURLOPT_TIMEOUT_MS
}
bind_buffer_fill = 0;
+
+ curl_easy_setopt(curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL);
+
if (curl_easy_perform(curl) != CURLE_OK) {
ERROR("bind plugin: curl_easy_perform failed: %s", bind_curl_error);
return (-1);
=over 4
-=item B<dispatch>([type][, values][, plugin_instance][, type_instance][, plugin][, host][, time][, interval]) -> None. Dispatch a value list.
+=item B<dispatch>([type][, message][, plugin_instance][, type_instance][, plugin][, host][, time][, severity]) -> None. Dispatch a notification.
Dispatch this instance to the collectd process. The object has members for each
of the possible arguments for this method. For a detailed explanation of these
# <Database bar>
# Interval 60
# Service "service_name"
-# Query backend # predefined
+# Query backends # predefined
# Query rt36_tickets
# </Database>
# <Database qux>
=item B<PostCacheChain> I<ChainName>
Configure the name of the "pre-cache chain" and the "post-cache chain". Please
-see L<FILTER CONFIGURATION> below on information on chains and how these
+see L</"FILTER CONFIGURATION"> below on information on chains and how these
setting change the daemon's behavior.
=back
collected or if they are ignored is controlled by the B<IgnoreSelected> option;
see below.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
Invert the selection: If set to true, all cgroups I<except> the ones that
Select partitions based on the devicename.
+See F</"IGNORELISTS"> for details.
+
=item B<MountPoint> I<Directory>
Select partitions based on the mountpoint.
+See F</"IGNORELISTS"> for details.
+
=item B<FSType> I<FSType>
Select partitions based on the filesystem type.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
Invert the selection: If set to true, all partitions B<except> the ones that
Disk "sdd"
Disk "/hda[34]/"
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
Select this interface. By default these interfaces will then be collected. For
a more detailed description see B<IgnoreSelected> below.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
If no configuration if given, the B<interface>-plugin will collect data from
Selects sensors to collect or to ignore, depending on B<IgnoreSelected>.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
If no configuration if given, the B<ipmi> plugin will collect data from all
Select this irq. By default these irqs will then be collected. For a more
detailed description see B<IgnoreSelected> below.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
If no configuration if given, the B<irq>-plugin will collect data from all
the device, i.e. the name of the block device without the leading C</dev/>.
See B<IgnoreSelected> for more details.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
Invert device selection: If set to B<true>, all md devices B<except> those
If no volume was specified at all for either of the three options, that data
will be collected for all available volumes.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelectedIO> B<true>|B<false>
=item B<IgnoreSelectedOps> B<true>|B<false>
Filter "ppp0" "u32-1:0"
</Plugin>
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected>
The behavior is the same as with all other similar plugins: If nothing is
As there can be multiple devices on the bus you can list multiple sensor (use
multiple B<Sensor> elements).
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
If no configuration is given, the B<onewire> plugin will collect data from all
=item B<Interval> I<Seconds>
Sets the interval in which to send ICMP echo packets to the configured hosts.
-This is B<not> the interval in which statistics are queries from the plugin but
-the interval in which the hosts are "pinged". Therefore, the setting here
-should be smaller than or equal to the global B<Interval> setting. Fractional
-times, such as "1.24" are allowed.
+This is B<not> the interval in which metrics are read from the plugin but the
+interval in which the hosts are "pinged". Therefore, the setting here should be
+smaller than or equal to the global B<Interval> setting. Fractional times, such
+as "1.24" are allowed.
Default: B<1.0>
<Database bar>
Interval 300
Service "service_name"
- Query backend # predefined
+ Query backends # predefined
Query rt36_tickets
</Database>
depends on the B<IgnoreSelected>. By default, only matched values are selected.
If no value is configured at all, all values will be selected.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
If set to B<true>, inverts the selection made by B<Value>, i.E<nbsp>e. all
When the C<rrdtool> plugin uses a cache (by setting B<CacheTimeout>, see below)
it writes all values for a certain RRD-file if the oldest value is older than
-(or equal to) the number of seconds specified. If some RRD-file is not updated
+(or equal to) the number of seconds specified by B<CacheTimeout>.
+That check happens on new values arriwal. If some RRD-file is not updated
anymore for some reason (the computer was shut down, the network is broken,
-etc.) some values may still be in the cache. If B<CacheFlush> is set, then the
-entire cache is searched for entries older than B<CacheTimeout> seconds and
-written to disk every I<Seconds> seconds. Since this is kind of expensive and
-does nothing under normal circumstances, this value should not be too small.
-900 seconds might be a good value, though setting this to 7200 seconds doesn't
-normally do much harm either.
+etc.) some values may still be in the cache. If B<CacheFlush> is set, then
+every I<Seconds> seconds the entire cache is searched for entries older than
+B<CacheTimeout> + B<RandomTimeout> seconds. The entries found are written to
+disk. Since scanning the entire cache is kind of expensive and does nothing
+under normal circumstances, this value should not be too small. 900 seconds
+might be a good value, though setting this to 7200 seconds doesn't normally
+do much harm either.
+
+Defaults to 10x B<CacheTimeout>.
+B<CacheFlush> must be larger than or equal to B<CacheTimeout>, otherwise the
+above default is used.
=item B<CacheTimeout> I<Seconds>
I<it8712-isa-0290/voltage-in1>" will cause collectd to gather data for the
voltage sensor I<in1> of the I<it8712> on the isa bus at the address 0290.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
If no configuration if given, the B<sensors>-plugin will collect data from all
Disk "sdd"
Disk "/hda[34]/"
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> B<true>|B<false>
Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
an interval. If set to B<False>, the default, these values aren't calculated /
dispatched.
+Please note what reported timer values less than 0.001 are ignored in all B<Timer*> reports.
+
=back
=head2 Plugin C<swap>
depending on the value of the B<IgnoreSelected> option. This option may be
used multiple times to specify a list of devices.
+See F</"IGNORELISTS"> for details.
+
=item B<IgnoreSelected> I<true>|I<false>
Invert the selection: If set to true, all devices B<except> the ones that
Target "write"
</Chain>
+=head1 IGNORELISTS
+
+B<Ignorelists> are a generic framework to either ignore some metrics or report
+specific metircs only. Plugins usually provide one or more options to specify
+the items (mounts points, devices, ...) and the boolean option
+C<IgnoreSelected>.
+
+=over 4
+
+=item B<Select> I<String>
+
+Selects the item I<String>. This option often has a plugin specific name, e.g.
+B<Sensor> in the C<sensors> plugin. It is also plugin specific what this string
+is compared to. For example, the C<df> plugin's B<MountPoint> compares it to a
+mount point and the C<sensors> plugin's B<Sensor> compares it to a sensor name.
+
+By default, this option is doing a case-sensitive full-string match. The
+following config will match C<foo>, but not C<Foo>:
+
+ Select "foo"
+
+If I<String> starts and ends with C</> (a slash), the string is compiled as a
+I<regular expression>. For example, so match all item starting with C<foo>, use
+could use the following syntax:
+
+ Select "/^foo/"
+
+The regular expression is I<not> anchored, i.e. the following config will match
+C<foobar>, C<barfoo> and C<AfooZ>:
+
+ Select "/foo/"
+
+The B<Select> option may be repeated to select multiple items.
+
+=item B<IgnoreSelected> B<true>|B<false>
+
+If set to B<true>, matching metrics are I<ignored> and all other metrics are
+collected. If set to B<false>, matching metrics are I<collected> and all other
+metrics are ignored.
+
+=back
+
=head1 SEE ALSO
L<collectd(1)>,
curl_easy_setopt(wp->curl, CURLOPT_WRITEDATA, wp);
curl_easy_setopt(wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
curl_easy_setopt(wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf);
- curl_easy_setopt(wp->curl, CURLOPT_URL, wp->url);
curl_easy_setopt(wp->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(wp->curl, CURLOPT_MAXREDIRS, 50L);
start = cdtime();
wp->buffer_fill = 0;
+
+ curl_easy_setopt(wp->curl, CURLOPT_URL, wp->url);
+
status = curl_easy_perform(wp->curl);
if (status != CURLE_OK) {
ERROR("curl plugin: curl_easy_perform failed with status %i: %s", status,
return ds->ds[0].type;
}
-static int cj_cb_map_key(void *ctx, const unsigned char *val, yajl_len_t len);
+/* cj_load_key loads the configuration for "key" from the parent context and
+ * sets either .key or .tree in the current context. */
+static int cj_load_key(cj_t *db, char const *key) {
+ if (db == NULL || key == NULL || db->depth <= 0)
+ return EINVAL;
-static void cj_cb_inc_array_index(void *ctx, _Bool update_key) {
- cj_t *db = (cj_t *)ctx;
+ sstrncpy(db->state[db->depth].name, key, sizeof(db->state[db->depth].name));
+
+ c_avl_tree_t *tree = db->state[db->depth - 1].tree;
+ if (tree == NULL) {
+ return 0;
+ }
+
+ /* the parent has a key, so the tree pointer is invalid. */
+ if (CJ_IS_KEY(db->state[db->depth - 1].key)) {
+ return 0;
+ }
+
+ void *value = NULL;
+ if (c_avl_get(tree, key, (void *)&value) == 0) {
+ if (CJ_IS_KEY((cj_key_t *)value)) {
+ db->state[db->depth].key = value;
+ } else {
+ db->state[db->depth].tree = value;
+ }
+ } else if (c_avl_get(tree, CJ_ANY, (void *)&value) == 0) {
+ if (CJ_IS_KEY((cj_key_t *)value)) {
+ db->state[db->depth].key = value;
+ } else {
+ db->state[db->depth].tree = value;
+ }
+ } else {
+ db->state[db->depth].key = NULL;
+ }
+
+ return 0;
+}
+static void cj_advance_array(cj_t *db) {
if (!db->state[db->depth].in_array)
return;
db->state[db->depth].index++;
- if (update_key) {
- char name[DATA_MAX_NAME_LEN];
-
- ssnprintf(name, sizeof(name), "%d", db->state[db->depth].index - 1);
-
- cj_cb_map_key(ctx, (unsigned char *)name, (yajl_len_t)strlen(name));
- }
+ char name[DATA_MAX_NAME_LEN];
+ ssnprintf(name, sizeof(name), "%d", db->state[db->depth].index);
+ cj_load_key(db, name);
}
/* yajl callbacks */
#define CJ_CB_CONTINUE 1
static int cj_cb_boolean(void *ctx, int boolVal) {
- cj_cb_inc_array_index(ctx, /* update_key = */ 0);
+ cj_advance_array(ctx);
return (CJ_CB_CONTINUE);
}
static int cj_cb_null(void *ctx) {
- cj_cb_inc_array_index(ctx, /* update_key = */ 0);
+ cj_advance_array(ctx);
return (CJ_CB_CONTINUE);
}
cj_t *db = (cj_t *)ctx;
cj_key_t *key = db->state[db->depth].key;
- value_t vt;
- int type;
- int status;
/* Create a null-terminated version of the string. */
memcpy(buffer, number, number_len);
buffer[sizeof(buffer) - 1] = 0;
- if ((key == NULL) || !CJ_IS_KEY(key)) {
- if (key != NULL &&
- !db->state[db->depth].in_array /*can be inhomogeneous*/) {
- NOTICE("curl_json plugin: Found \"%s\", but the configuration expects"
- " a map.",
- buffer);
- return (CJ_CB_CONTINUE);
- }
- cj_cb_inc_array_index(ctx, /* update_key = */ 1);
- key = db->state[db->depth].key;
- if ((key == NULL) || !CJ_IS_KEY(key)) {
- return (CJ_CB_CONTINUE);
- }
- } else {
- cj_cb_inc_array_index(ctx, /* update_key = */ 1);
- }
- type = cj_get_type(key);
- status = parse_value(buffer, &vt, type);
+ if (key == NULL) {
+ /* no config for this element. */
+ cj_advance_array(ctx);
+ return CJ_CB_CONTINUE;
+ } else if (!CJ_IS_KEY(key)) {
+ /* the config expects a map or an array. */
+ NOTICE(
+ "curl_json plugin: Found \"%s\", but the configuration expects a map.",
+ buffer);
+ cj_advance_array(ctx);
+ return CJ_CB_CONTINUE;
+ }
+
+ int type = cj_get_type(key);
+ value_t vt;
+ int status = parse_value(buffer, &vt, type);
if (status != 0) {
NOTICE("curl_json plugin: Unable to parse number: \"%s\"", buffer);
+ cj_advance_array(ctx);
return (CJ_CB_CONTINUE);
}
cj_submit(db, key, &vt);
+ cj_advance_array(ctx);
return (CJ_CB_CONTINUE);
} /* int cj_cb_number */
* NULL. */
static int cj_cb_map_key(void *ctx, unsigned char const *in_name,
yajl_len_t in_name_len) {
- cj_t *db = (cj_t *)ctx;
- c_avl_tree_t *tree;
+ char name[in_name_len + 1];
- tree = db->state[db->depth - 1].tree;
-
- if (tree != NULL) {
- cj_key_t *value = NULL;
- char *name;
- size_t name_len;
-
- /* Create a null-terminated version of the name. */
- name = db->state[db->depth].name;
- name_len =
- COUCH_MIN((size_t)in_name_len, sizeof(db->state[db->depth].name) - 1);
- memcpy(name, in_name, name_len);
- name[name_len] = 0;
-
- if (c_avl_get(tree, name, (void *)&value) == 0) {
- if (CJ_IS_KEY((cj_key_t *)value)) {
- db->state[db->depth].key = value;
- } else {
- db->state[db->depth].tree = (c_avl_tree_t *)value;
- }
- } else if (c_avl_get(tree, CJ_ANY, (void *)&value) == 0)
- if (CJ_IS_KEY((cj_key_t *)value)) {
- db->state[db->depth].key = value;
- } else {
- db->state[db->depth].tree = (c_avl_tree_t *)value;
- }
- else
- db->state[db->depth].key = NULL;
- }
+ memmove(name, in_name, in_name_len);
+ name[sizeof(name) - 1] = 0;
- return (CJ_CB_CONTINUE);
+ if (cj_load_key(ctx, name) != 0)
+ return CJ_CB_ABORT;
+
+ return CJ_CB_CONTINUE;
}
static int cj_cb_string(void *ctx, const unsigned char *val, yajl_len_t len) {
return (cj_cb_number(ctx, (const char *)val, len));
} /* int cj_cb_string */
-static int cj_cb_start(void *ctx) {
- cj_t *db = (cj_t *)ctx;
- if (++db->depth >= YAJL_MAX_DEPTH) {
- ERROR("curl_json plugin: %s depth exceeds max, aborting.",
- db->url ? db->url : db->sock);
- return (CJ_CB_ABORT);
- }
- return (CJ_CB_CONTINUE);
-}
-
static int cj_cb_end(void *ctx) {
cj_t *db = (cj_t *)ctx;
db->state[db->depth].tree = NULL;
- --db->depth;
+ db->depth--;
+ cj_advance_array(ctx);
return (CJ_CB_CONTINUE);
}
static int cj_cb_start_map(void *ctx) {
- cj_cb_inc_array_index(ctx, /* update_key = */ 1);
- return cj_cb_start(ctx);
+ cj_t *db = (cj_t *)ctx;
+
+ if ((db->depth + 1) >= YAJL_MAX_DEPTH) {
+ ERROR("curl_json plugin: %s depth exceeds max, aborting.",
+ db->url ? db->url : db->sock);
+ return (CJ_CB_ABORT);
+ }
+ db->depth++;
+ return (CJ_CB_CONTINUE);
}
static int cj_cb_end_map(void *ctx) { return cj_cb_end(ctx); }
static int cj_cb_start_array(void *ctx) {
cj_t *db = (cj_t *)ctx;
- cj_cb_inc_array_index(ctx, /* update_key = */ 1);
- if (db->depth + 1 < YAJL_MAX_DEPTH) {
- db->state[db->depth + 1].in_array = 1;
- db->state[db->depth + 1].index = 0;
+
+ if ((db->depth + 1) >= YAJL_MAX_DEPTH) {
+ ERROR("curl_json plugin: %s depth exceeds max, aborting.",
+ db->url ? db->url : db->sock);
+ return CJ_CB_ABORT;
}
- return cj_cb_start(ctx);
+ db->depth++;
+ db->state[db->depth].in_array = 1;
+ db->state[db->depth].index = 0;
+
+ cj_load_key(db, "0");
+
+ return CJ_CB_CONTINUE;
}
static int cj_cb_end_array(void *ctx) {
curl_easy_setopt(db->curl, CURLOPT_WRITEDATA, db);
curl_easy_setopt(db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
- curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS, (long)db->timeout);
else if (db->interval > 0)
curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS,
- (long)CDTIME_T_TO_MS(db->timeout));
+ (long)CDTIME_T_TO_MS(db->interval));
else
curl_easy_setopt(db->curl, CURLOPT_TIMEOUT_MS,
(long)CDTIME_T_TO_MS(plugin_get_interval()));
int status;
long rc;
char *url;
- url = db->url;
+
+ curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
status = curl_easy_perform(db->curl);
if (status != CURLE_OK) {
ERROR("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
- status, db->curl_errbuf, url);
+ status, db->curl_errbuf, db->url);
return (-1);
}
if (db->stats != NULL)
long rc;
char *ptr;
char *url;
- url = db->url;
db->buffer_fill = 0;
+
+ curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
+
status = curl_easy_perform(curl);
if (status != CURLE_OK) {
ERROR("curl_xml plugin: curl_easy_perform failed with status %i: %s (%s)",
- status, db->curl_errbuf, url);
+ status, db->curl_errbuf, db->url);
return (-1);
}
if (db->stats != NULL)
curl_easy_setopt(db->curl, CURLOPT_WRITEDATA, db);
curl_easy_setopt(db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
curl_easy_setopt(db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
- curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
curl_easy_setopt(db->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(db->curl, CURLOPT_MAXREDIRS, 50L);
*/
if (cf_read(configfile)) {
fprintf(stderr, "Error: Reading the config file failed!\n"
- "Read the syslog for details.\n");
+ "Read the logs for details.\n");
return (1);
}
ptr = (const char *)buf;
nleft = count;
- if (fd < 0)
- return (-1);
+ if (fd < 0) {
+ errno = EINVAL;
+ return errno;
+ }
/* checking for closed peer connection */
pfd.fd = fd;
if (poll(&pfd, 1, 0) > 0) {
char buffer[32];
if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
- // if recv returns zero (even though poll() said there is data to be
- // read),
- // that means the connection has been closed
- return -1;
+ /* if recv returns zero (even though poll() said there is data to be
+ * read), that means the connection has been closed */
+ return errno ? errno : -1;
}
}
continue;
if (status < 0)
- return (status);
+ return errno ? errno : status;
nleft = nleft - ((size_t)status);
ptr = ptr + ((size_t)status);
#if HAVE_CAPABILITY
int check_capability(int arg) /* {{{ */
{
- cap_value_t cap = (cap_value_t)arg;
+ cap_value_t cap_value = (cap_value_t)arg;
+ cap_t cap;
+ cap_flag_value_t cap_flag_value;
- if (!CAP_IS_SUPPORTED(cap))
+ if (!CAP_IS_SUPPORTED(cap_value))
return (-1);
- int have_cap = cap_get_bound(cap);
- if (have_cap != 1)
+ if (!(cap = cap_get_proc())) {
+ ERROR("check_capability: cap_get_proc failed.");
return (-1);
+ }
- return (0);
+ if (cap_get_flag(cap, cap_value, CAP_EFFECTIVE, &cap_flag_value) < 0) {
+ ERROR("check_capability: cap_get_flag failed.");
+ cap_free(cap);
+ return (-1);
+ }
+ cap_free(cap);
+
+ return (cap_flag_value != CAP_SET);
} /* }}} int check_capability */
#else
int check_capability(__attribute__((unused)) int arg) /* {{{ */
* argument. Returns zero if it does, less than zero if it doesn't or on error.
* See capabilities(7) for the list of possible capabilities.
* */
-int check_capability(int capability);
+int check_capability(int arg);
#endif /* HAVE_SYS_CAPABILITY_H */
#endif /* COMMON_H */
if ((ci == NULL) || (ret_bool == NULL))
return (EINVAL);
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
+ if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN) &&
+ (ci->values[0].type != OCONFIG_TYPE_STRING))) {
ERROR("cf_util_get_boolean: The %s option requires "
"exactly one boolean argument.",
ci->key);
return (-1);
}
- *ret_bool = ci->values[0].value.boolean ? 1 : 0;
+ switch (ci->values[0].type) {
+ case OCONFIG_TYPE_BOOLEAN:
+ *ret_bool = ci->values[0].value.boolean ? 1 : 0;
+ break;
+ case OCONFIG_TYPE_STRING:
+ WARNING("cf_util_get_boolean: Using string value `%s' for boolean option "
+ "`%s' is deprecated and will be removed in future releases. "
+ "Use unquoted true or false instead.",
+ ci->values[0].value.string, ci->key);
+
+ if (IS_TRUE(ci->values[0].value.string))
+ *ret_bool = 1;
+ else if (IS_FALSE(ci->values[0].value.string))
+ *ret_bool = 0;
+ else {
+ ERROR("cf_util_get_boolean: Cannot parse string value `%s' of the `%s' "
+ "option as a boolean value.",
+ ci->values[0].value.string, ci->key);
+ return (-1);
+ }
+ break;
+ }
return (0);
} /* }}} int cf_util_get_boolean */
temp = md_strdup(actual);
if (temp == NULL) {
- pthread_mutex_unlock(&md->lock);
ERROR("meta_data_as_string: md_strdup failed for key `%s'.", key);
return (-ENOMEM);
}
return (plugindir);
}
-static void plugin_update_internal_statistics(void) { /* {{{ */
-
+static int plugin_update_internal_statistics(void) { /* {{{ */
gauge_t copy_write_queue_length = (gauge_t)write_queue_length;
/* Initialize `vl' */
value_list_t vl = VALUE_LIST_INIT;
- sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, "collectd", sizeof(vl.plugin));
+ vl.interval = plugin_get_interval();
/* Write queue */
sstrncpy(vl.plugin_instance, "write_queue", sizeof(vl.plugin_instance));
vl.type_instance[0] = 0;
plugin_dispatch_values(&vl);
- return;
-} /* }}} void plugin_update_internal_statistics */
+ return 0;
+} /* }}} int plugin_update_internal_statistics */
static void destroy_callback(callback_func_t *cf) /* {{{ */
{
/* Init the value cache */
uc_init();
- if (IS_TRUE(global_option_get("CollectInternalStats")))
+ if (IS_TRUE(global_option_get("CollectInternalStats"))) {
record_statistics = 1;
+ plugin_register_read("collectd", plugin_update_internal_statistics);
+ }
chain_name = global_option_get("PreCacheChain");
pre_cache_chain = fc_chain_get_by_name(chain_name);
/* TODO: Rename this function. */
void plugin_read_all(void) {
- if (record_statistics) {
- plugin_update_internal_statistics();
- }
uc_check_timeout();
return;
} /* int uc_init */
int uc_check_timeout(void) {
- cdtime_t now = cdtime();
-
struct {
char *key;
cdtime_t time;
size_t expired_num = 0;
pthread_mutex_lock(&cache_lock);
+ cdtime_t now = cdtime();
/* Build a list of entries to be flushed */
c_avl_iterator_t *iter = c_avl_get_iterator(cache_tree);
/* remove missing values from getval */
if (ce->state == STATE_MISSING) {
+ DEBUG("utils_cache: uc_get_rate_by_name: requested metric \"%s\" is in "
+ "state \"missing\".",
+ name);
status = -1;
} else {
ret_num = ce->values_num;
/* This is important - the caller has no other way of knowing how many
* values are returned. */
- if (ret_num != (size_t)ds->ds_num) {
+ if (ret_num != ds->ds_num) {
ERROR("utils_cache: uc_get_rate: ds[%s] has %zu values, "
"but uc_get_rate_by_name returned %zu.",
ds->type, ds->ds_num, ret_num);
return;
sfree(db->name);
+ sfree(db->select_db);
sfree(db->driver);
+ sfree(db->host);
for (size_t i = 0; i < db->driver_options_num; i++) {
sfree(db->driver_options[i].key);
if (db->q_prep_areas)
for (size_t i = 0; i < db->queries_num; ++i)
udb_query_delete_preparation_area(db->q_prep_areas[i]);
- free(db->q_prep_areas);
+ sfree(db->q_prep_areas);
+ /* N.B.: db->queries references objects "owned" by the global queries
+ * variable. Free the array here, but not the content. */
+ sfree(db->queries);
sfree(db);
} /* }}} void cdbi_database_free */
static void dpdk_config_init_default(void) {
g_configuration->interval = plugin_get_interval();
if (g_configuration->interval == cf_get_default_interval())
- WARNING("dpdkstat: No time interval was configured, default value %lu ms "
- "is set",
+ WARNING("dpdkstat: No time interval was configured, default value %" PRIu64
+ " ms is set",
CDTIME_T_TO_MS(g_configuration->interval));
/* Default is all ports enabled */
g_configuration->enabled_port_mask = ~0;
if (err) {
ERROR("dpdkstat semaphore init failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- goto fail_close;
+ goto fail;
}
err = sem_init(&g_configuration->sema_stats_in_shm, 1, 0);
if (err) {
ERROR("dpdkstat semaphore init failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- goto fail_close;
+ goto fail;
}
g_configuration->xstats = NULL;
if (pid > 0) {
close(g_configuration->helper_pipes[1]);
g_configuration->helper_pid = pid;
- DEBUG("dpdkstat: helper pid %lu", (long)g_configuration->helper_pid);
+ DEBUG("dpdkstat: helper pid %li", (long)g_configuration->helper_pid);
/* Kick helper once its alive to have it start processing */
sem_post(&g_configuration->sema_helper_get_stats);
} else if (pid == 0) {
if ((type_end != NULL) &&
(strncmp(counter_name, "rx_", strlen("rx_")) == 0)) {
- if (strncmp(type_end, "_errors", strlen("_errors")) == 0) {
+ if (strstr(type_end, "bytes") != NULL) {
+ sstrncpy(vl.type, "if_rx_octets", sizeof(vl.type));
+ } else if (strstr(type_end, "error") != NULL) {
sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
- } else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0) {
+ } else if (strstr(type_end, "dropped") != NULL) {
sstrncpy(vl.type, "if_rx_dropped", sizeof(vl.type));
- } else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0) {
- sstrncpy(vl.type, "if_rx_octets", sizeof(vl.type));
- } else if (strncmp(type_end, "_packets", strlen("_packets")) == 0) {
+ } else if (strstr(type_end, "packets") != NULL) {
sstrncpy(vl.type, "if_rx_packets", sizeof(vl.type));
- } else if (strncmp(type_end, "_placement", strlen("_placement")) == 0) {
+ } else if (strstr(type_end, "_placement") != NULL) {
sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
- } else if (strncmp(type_end, "_buff", strlen("_buff")) == 0) {
+ } else if (strstr(type_end, "_buff") != NULL) {
sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
} else {
/* Does not fit obvious type: use a more generic one */
} else if ((type_end != NULL) &&
(strncmp(counter_name, "tx_", strlen("tx_"))) == 0) {
- if (strncmp(type_end, "_errors", strlen("_errors")) == 0) {
+ if (strstr(type_end, "bytes") != NULL) {
+ sstrncpy(vl.type, "if_tx_octets", sizeof(vl.type));
+ } else if (strstr(type_end, "error") != NULL) {
sstrncpy(vl.type, "if_tx_errors", sizeof(vl.type));
- } else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0) {
+ } else if (strstr(type_end, "dropped") != NULL) {
sstrncpy(vl.type, "if_tx_dropped", sizeof(vl.type));
- } else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0) {
- sstrncpy(vl.type, "if_tx_octets", sizeof(vl.type));
- } else if (strncmp(type_end, "_packets", strlen("_packets")) == 0) {
+ } else if (strstr(type_end, "packets") != NULL) {
sstrncpy(vl.type, "if_tx_packets", sizeof(vl.type));
} else {
/* Does not fit obvious type: use a more generic one */
} else if ((type_end != NULL) &&
(strncmp(counter_name, "flow_", strlen("flow_"))) == 0) {
- if (strncmp(type_end, "_filters", strlen("_filters")) == 0) {
+ if (strstr(type_end, "_filters") != NULL) {
sstrncpy(vl.type, "operations", sizeof(vl.type));
- } else if (strncmp(type_end, "_errors", strlen("_errors")) == 0) {
+ } else if (strstr(type_end, "error") != NULL)
sstrncpy(vl.type, "errors", sizeof(vl.type));
- } else if (strncmp(type_end, "_filters", strlen("_filters")) == 0) {
- sstrncpy(vl.type, "filter_result", sizeof(vl.type));
- }
+
} else if ((type_end != NULL) &&
(strncmp(counter_name, "mac_", strlen("mac_"))) == 0) {
- if (strncmp(type_end, "_errors", strlen("_errors")) == 0) {
+ if (strstr(type_end, "error") != NULL) {
sstrncpy(vl.type, "errors", sizeof(vl.type));
}
} else {
}
if ('e' == line[0]) { /* e:<type>:<bytes> */
- char *ptr = NULL;
- char *type = strtok_r(line + 2, ":", &ptr);
- char *tmp = strtok_r(NULL, ":", &ptr);
- int bytes = 0;
-
- if (NULL == tmp) {
+ char *type = line + 2;
+ char *bytes_str = strchr(type, ':');
+ if (bytes_str == NULL) {
log_err("collect: syntax error in line '%s'", line);
continue;
}
- bytes = atoi(tmp);
+ *bytes_str = 0;
+ bytes_str++;
pthread_mutex_lock(&count_mutex);
type_list_incr(&list_count, type, /* increment = */ 1);
pthread_mutex_unlock(&count_mutex);
+ int bytes = atoi(bytes_str);
if (bytes > 0) {
pthread_mutex_lock(&size_mutex);
type_list_incr(&list_size, type, /* increment = */ bytes);
}
struct sockaddr_un addr = {
- .sun_family = AF_UNIX
+ .sun_family = AF_UNIX,
};
sstrncpy(addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1));
{
struct group sg;
struct group *grp;
- char grbuf[2048];
int status;
+ long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (grbuf_size <= 0)
+ grbuf_size = sysconf(_SC_PAGESIZE);
+ if (grbuf_size <= 0)
+ grbuf_size = 4096;
+ char grbuf[grbuf_size];
+
grp = NULL;
status = getgrnam_r(group, &sg, grbuf, sizeof(grbuf), &grp);
if (status != 0) {
char errbuf[1024];
log_warn("getgrnam_r (%s) failed: %s", group,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ sstrerror(status, errbuf, sizeof(errbuf)));
} else if (grp == NULL) {
log_warn("No such group: `%s'", group);
} else {
struct passwd *sp_ptr;
struct passwd sp;
- char nambuf[2048];
if (pl->pid != 0)
return (-1);
+ long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (nambuf_size <= 0)
+ nambuf_size = sysconf(_SC_PAGESIZE);
+ if (nambuf_size <= 0)
+ nambuf_size = 4096;
+ char nambuf[nambuf_size];
+
if ((create_pipe(fd_pipe_in) == -1) || (create_pipe(fd_pipe_out) == -1) ||
(create_pipe(fd_pipe_err) == -1))
goto failed;
status = getpwnam_r(pl->user, &sp, nambuf, sizeof(nambuf), &sp_ptr);
if (status != 0) {
ERROR("exec plugin: Failed to get user information for user ``%s'': %s",
- pl->user, sstrerror(errno, errbuf, sizeof(errbuf)));
+ pl->user, sstrerror(status, errbuf, sizeof(errbuf)));
goto failed;
}
struct group *gr_ptr = NULL;
struct group gr;
- status = getgrnam_r(pl->group, &gr, nambuf, sizeof(nambuf), &gr_ptr);
+ long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (grbuf_size <= 0)
+ grbuf_size = sysconf(_SC_PAGESIZE);
+ if (grbuf_size <= 0)
+ grbuf_size = 4096;
+ char grbuf[grbuf_size];
+
+ status = getgrnam_r(pl->group, &gr, grbuf, sizeof(grbuf), &gr_ptr);
if (0 != status) {
ERROR("exec plugin: Failed to get group information "
"for group ``%s'': %s",
- pl->group, sstrerror(errno, errbuf, sizeof(errbuf)));
+ pl->group, sstrerror(status, errbuf, sizeof(errbuf)));
goto failed;
}
if (NULL == gr_ptr) {
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read");
+ int status =
+ plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read");
+ if (status != 0) {
+ ERROR("exec plugin: plugin_thread_create failed.");
+ }
pthread_attr_destroy(&attr);
} /* for (pl) */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- plugin_thread_create(&t, &attr, exec_notification_one, (void *)pln,
- "exec notify");
+ int status = plugin_thread_create(&t, &attr, exec_notification_one,
+ (void *)pln, "exec notify");
+ if (status != 0) {
+ ERROR("exec plugin: plugin_thread_create failed.");
+ }
pthread_attr_destroy(&attr);
} /* for (pl) */
* Marc Fournier <marc.fournier at camptocamp.com>
**/
+#include "collectd.h"
#include "common.h"
#include "plugin.h"
#include "utils_time.h"
-#include "collectd.h"
#define CGPS_TRUE 1
#define CGPS_FALSE 0
int ret = !cgps_thread_shutdown;
- pthread_mutex_lock(&cgps_thread_lock);
+ pthread_mutex_unlock(&cgps_thread_lock);
return ret;
}
free(res);
// Clean mutex:
- pthread_mutex_unlock(&cgps_thread_lock);
pthread_mutex_destroy(&cgps_thread_lock);
pthread_mutex_unlock(&cgps_data_lock);
pthread_mutex_destroy(&cgps_data_lock);
#define RDT_MAX_SOCKET_CORES 64
#define RDT_MAX_CORES (RDT_MAX_SOCKET_CORES * RDT_MAX_SOCKETS)
+typedef enum {
+ UNKNOWN = 0,
+ CONFIGURATION_ERROR,
+} rdt_config_status;
+
struct rdt_core_group_s {
char *desc;
size_t num_cores;
static rdt_ctx_t *g_rdt = NULL;
+static rdt_config_status g_state = UNKNOWN;
+
static int isdup(const uint64_t *nums, size_t size, uint64_t val) {
for (size_t i = 0; i < size; i++)
if (nums[i] == val)
}
static int rdt_config(oconfig_item_t *ci) {
- int ret = 0;
-
- ret = rdt_preinit();
- if (ret != 0)
- return ret;
+ if (rdt_preinit() != 0) {
+ g_state = CONFIGURATION_ERROR;
+ /* if we return -1 at this point collectd
+ reports a failure in configuration and
+ aborts
+ */
+ return (0);
+ }
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
if (strcasecmp("Cores", child->key) == 0) {
-
- ret = rdt_config_cgroups(child);
- if (ret != 0)
- return ret;
+ if (rdt_config_cgroups(child) != 0) {
+ g_state = CONFIGURATION_ERROR;
+ /* if we return -1 at this point collectd
+ reports a failure in configuration and
+ aborts
+ */
+ return (0);
+ }
#if COLLECT_DEBUG
rdt_dump_cgroups();
#endif /* COLLECT_DEBUG */
-
} else {
ERROR(RDT_PLUGIN ": Unknown configuration parameter \"%s\".", child->key);
}
static int rdt_init(void) {
int ret;
+ if(g_state == CONFIGURATION_ERROR)
+ return (-1);
+
ret = rdt_preinit();
if (ret != 0)
return ret;
ipcinfo_shm_t *pshm;
unsigned int shm_segments = 0;
size64_t shm_bytes = 0;
- int n;
+ int i, n;
ipcinfo_shm = (ipcinfo_shm_t *)ipc_get_info(
0, GET_IPCINFO_SHM_ALL, IPCINFO_SHM_VERSION, sizeof(ipcinfo_shm_t), &n);
if (ipcinfo_shm == NULL)
return -1;
- for (int i = 0, pshm = ipcinfo_shm; i < n; i++, pshm++) {
+ for (i = 0, pshm = ipcinfo_shm; i < n; i++, pshm++) {
shm_segments++;
shm_bytes += pshm->shm_segsz;
}
#include "aux_types.h"
static char *unquote (const char *orig);
-static int yyerror (const char *s);
+static void yyerror(const char *s);
/* Lexer variables */
extern int yylineno;
argument_list argument
{
$$ = $1;
+ oconfig_value_t *tmp = realloc($$.argument,
+ ($$.argument_num+1) * sizeof(*$$.argument));
+ if (tmp == NULL) {
+ yyerror("realloc failed");
+ YYERROR;
+ }
+ $$.argument = tmp;
+ $$.argument[$$.argument_num] = $2;
$$.argument_num++;
- $$.argument = realloc ($$.argument, $$.argument_num * sizeof (oconfig_value_t));
- $$.argument[$$.argument_num-1] = $2;
}
| argument
{
- $$.argument = malloc (sizeof (oconfig_value_t));
+ $$.argument = calloc(1, sizeof(*$$.argument));
+ if ($$.argument == NULL) {
+ yyerror("calloc failed");
+ YYERROR;
+ }
$$.argument[0] = $1;
$$.argument_num = 1;
}
option:
identifier argument_list EOL
{
- memset (&$$, '\0', sizeof ($$));
+ memset(&$$, 0, sizeof($$));
$$.key = $1;
$$.values = $2.argument;
$$.values_num = $2.argument_num;
block_begin:
OPENBRAC identifier CLOSEBRAC EOL
{
- memset (&$$, '\0', sizeof ($$));
+ memset(&$$, 0, sizeof($$));
$$.key = $2;
}
|
OPENBRAC identifier argument_list CLOSEBRAC EOL
{
- memset (&$$, '\0', sizeof ($$));
+ memset(&$$, 0, sizeof($$));
$$.key = $2;
$$.values = $3.argument;
$$.values_num = $3.argument_num;
block:
block_begin statement_list block_end
{
- if (strcmp ($1.key, $3) != 0)
+ if (strcmp($1.key, $3) != 0)
{
- printf ("block_begin = %s; block_end = %s;\n", $1.key, $3);
- yyerror ("Block not closed..\n");
- exit (1);
+ printf("block_begin = %s; block_end = %s;\n", $1.key, $3);
+ yyerror("block not closed");
+ YYERROR;
}
free ($3); $3 = NULL;
$$ = $1;
}
| block_begin block_end
{
- if (strcmp ($1.key, $2) != 0)
+ if (strcmp($1.key, $2) != 0)
{
- printf ("block_begin = %s; block_end = %s;\n", $1.key, $2);
- yyerror ("Block not closed..\n");
- exit (1);
+ printf("block_begin = %s; block_end = %s;\n", $1.key, $2);
+ yyerror("block not closed");
+ YYERROR;
}
free ($2); $2 = NULL;
$$ = $1;
$$ = $1;
if (($2.values_num > 0) || ($2.children_num > 0))
{
+ oconfig_item_t *tmp = realloc($$.statement,
+ ($$.statement_num+1) * sizeof(*tmp));
+ if (tmp == NULL) {
+ yyerror("realloc failed");
+ YYERROR;
+ }
+ $$.statement = tmp;
+ $$.statement[$$.statement_num] = $2;
$$.statement_num++;
- $$.statement = realloc ($$.statement, $$.statement_num * sizeof (oconfig_item_t));
- $$.statement[$$.statement_num-1] = $2;
}
}
| statement
{
if (($1.values_num > 0) || ($1.children_num > 0))
{
- $$.statement = malloc (sizeof (oconfig_item_t));
+ $$.statement = calloc(1, sizeof(*$$.statement));
+ if ($$.statement == NULL) {
+ yyerror("calloc failed");
+ YYERROR;
+ }
$$.statement[0] = $1;
$$.statement_num = 1;
}
entire_file:
statement_list
{
- ci_root = calloc (1, sizeof (*ci_root));
+ ci_root = calloc(1, sizeof(*ci_root));
+ if (ci_root == NULL) {
+ yyerror("calloc failed");
+ YYERROR;
+ }
ci_root->children = $1.statement;
ci_root->children_num = $1.statement_num;
}
| /* epsilon */
{
- ci_root = calloc (1, sizeof (*ci_root));
- ci_root->children = NULL;
- ci_root->children_num = 0;
+ ci_root = calloc(1, sizeof(*ci_root));
+ if (ci_root == NULL) {
+ yyerror("calloc failed");
+ YYERROR;
+ }
}
;
%%
-static int yyerror (const char *s)
+static void yyerror(const char *s)
{
const char *text;
- if (*yytext == '\n')
+ if (yytext == NULL)
+ text = "<empty>";
+ else if (*yytext == '\n')
text = "<newline>";
else
text = yytext;
- fprintf (stderr, "Parse error in file `%s', line %i near `%s': %s\n",
+ fprintf(stderr, "Parse error in file `%s', line %i near `%s': %s\n",
c_file, yylineno, text, s);
- return (-1);
} /* int yyerror */
static char *unquote (const char *orig)
len -= 2;
memmove (ret, ret + 1, len);
- ret[len] = '\0';
+ ret[len] = 0;
for (int i = 0; i < len; i++)
{
#define HAVE_YAJL_V2 1
#endif
-#define DEFAULT_LOGFILE LOCALSTATEDIR "/log/" PACKAGE_NAME ".json.log"
-
#if COLLECT_DEBUG
static int log_level = LOG_DEBUG;
#else
pthread_mutex_lock(&file_lock);
if (log_file == NULL) {
- fh = fopen(DEFAULT_LOGFILE, "a");
- do_close = 1;
+ fh = stderr;
} else if (strcasecmp(log_file, "stdout") == 0) {
fh = stdout;
do_close = 0;
if (fh == NULL) {
char errbuf[1024];
- fprintf(stderr, "log_logstash plugin: fopen (%s) failed: %s\n",
- (log_file == NULL) ? DEFAULT_LOGFILE : log_file,
+ fprintf(stderr, "log_logstash plugin: fopen (%s) failed: %s\n", log_file,
sstrerror(errno, errbuf, sizeof(errbuf)));
} else {
fprintf(fh, "%s\n", buf);
#include "common.h"
#include "plugin.h"
-#define DEFAULT_LOGFILE LOCALSTATEDIR "/log/collectd.log"
-
#if COLLECT_DEBUG
static int log_level = LOG_DEBUG;
#else
pthread_mutex_lock(&file_lock);
if (log_file == NULL) {
- fh = fopen(DEFAULT_LOGFILE, "a");
- do_close = 1;
+ fh = stderr;
} else if (strcasecmp(log_file, "stderr") == 0)
fh = stderr;
else if (strcasecmp(log_file, "stdout") == 0)
if (fh == NULL) {
char errbuf[1024];
- fprintf(stderr, "logfile plugin: fopen (%s) failed: %s\n",
- (log_file == NULL) ? DEFAULT_LOGFILE : log_file,
+ fprintf(stderr, "logfile plugin: fopen (%s) failed: %s\n", log_file,
sstrerror(errno, errbuf, sizeof(errbuf)));
} else {
if (print_timestamp)
* CPU time consumed by the memcached process
*/
if (FIELD_IS("rusage_user")) {
- rusage_user = atoll(fields[2]);
+ /* Convert to useconds */
+ rusage_user = atof(fields[2]) * 1000000;
} else if (FIELD_IS("rusage_system")) {
- rusage_syst = atoll(fields[2]);
+ rusage_syst = atof(fields[2]) * 1000000;
}
/*
* measure; we will try to reconnect the next time we have to publish a
* message */
conf->connected = 0;
+ mosquitto_disconnect(conf->mosq);
pthread_mutex_unlock(&conf->lock);
return (-1);
value_list_t const *vl, mqtt_client_conf_t *conf) {
char name[MQTT_MAX_TOPIC_SIZE];
int status;
+ char *c;
if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0))
return (FORMAT_VL(buf, buf_len, vl));
if ((status < 0) || (((size_t)status) >= buf_len))
return (ENOMEM);
+ while((c = strchr(buf, '#')) || (c = strchr(buf, '+'))) {
+ *c = '_';
+ }
+
return (0);
} /* int format_topic */
--- /dev/null
+/*
+ * Partial header file imported from the linux kernel
+ * (arch/x86/include/asm/msr-index.h)
+ * as it is not provided by the kernel sources anymore
+ *
+ * Only the minimal blocks of macro have been included
+ * ----
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * ----
+ */
+
+#ifndef _ASM_X86_MSR_INDEX_H
+#define _ASM_X86_MSR_INDEX_H
+
+/*
+ * CPU model specific register (MSR) numbers.
+ *
+ * Do not add new entries to this file unless the definitions are shared
+ * between multiple compilation units.
+ */
+
+/* Intel MSRs. Some also available on other CPUs */
+
+/* C-state Residency Counters */
+#define MSR_PKG_C3_RESIDENCY 0x000003f8
+#define MSR_PKG_C6_RESIDENCY 0x000003f9
+#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
+#define MSR_PKG_C7_RESIDENCY 0x000003fa
+#define MSR_CORE_C3_RESIDENCY 0x000003fc
+#define MSR_CORE_C6_RESIDENCY 0x000003fd
+#define MSR_CORE_C7_RESIDENCY 0x000003fe
+#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
+#define MSR_PKG_C2_RESIDENCY 0x0000060d
+#define MSR_PKG_C8_RESIDENCY 0x00000630
+#define MSR_PKG_C9_RESIDENCY 0x00000631
+#define MSR_PKG_C10_RESIDENCY 0x00000632
+
+/* Run Time Average Power Limiting (RAPL) Interface */
+
+#define MSR_RAPL_POWER_UNIT 0x00000606
+
+#define MSR_PKG_POWER_LIMIT 0x00000610
+#define MSR_PKG_ENERGY_STATUS 0x00000611
+#define MSR_PKG_PERF_STATUS 0x00000613
+#define MSR_PKG_POWER_INFO 0x00000614
+
+#define MSR_DRAM_POWER_LIMIT 0x00000618
+#define MSR_DRAM_ENERGY_STATUS 0x00000619
+#define MSR_DRAM_PERF_STATUS 0x0000061b
+#define MSR_DRAM_POWER_INFO 0x0000061c
+
+#define MSR_PP0_POWER_LIMIT 0x00000638
+#define MSR_PP0_ENERGY_STATUS 0x00000639
+#define MSR_PP0_POLICY 0x0000063a
+#define MSR_PP0_PERF_STATUS 0x0000063b
+
+#define MSR_PP1_POWER_LIMIT 0x00000640
+#define MSR_PP1_ENERGY_STATUS 0x00000641
+#define MSR_PP1_POLICY 0x00000642
+
+/* Intel defined MSRs. */
+#define MSR_IA32_TSC 0x00000010
+#define MSR_SMI_COUNT 0x00000034
+
+#define MSR_IA32_MPERF 0x000000e7
+#define MSR_IA32_APERF 0x000000e8
+
+#define MSR_IA32_THERM_STATUS 0x0000019c
+
+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
+
+#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
+
+#endif /* _ASM_X86_MSR_INDEX_H */
const char *type, const char *type_inst, double d,
cdtime_t timestamp, cdtime_t interval) {
return (submit_values(host, plugin_inst, type, type_inst,
- &(value_t){.gauge = counter}, 1, timestamp, interval));
+ &(value_t){.gauge = d}, 1, timestamp, interval));
} /* }}} int submit_uint64 */
/* Calculate hit ratio from old and new counters and submit the resulting
static int cna_handle_snapvault_data(const char *hostname, /* {{{ */
cfg_snapvault_t *cfg_snapvault,
na_elem_t *data, cdtime_t interval) {
- na_elem_iter_t status_iter;
-
- status = na_elem_child(data, "status-list");
- if (!status) {
+ na_elem_t *status_list = na_elem_child(data, "status-list");
+ if (status_list == NULL) {
ERROR("netapp plugin: SnapVault status record missing status-list");
return (0);
}
- status_iter = na_child_iterator(status);
+ na_elem_iter_t status_iter = na_child_iterator(status_list);
for (na_elem_t *status = na_iterator_next(&status_iter); status != NULL;
status = na_iterator_next(&status_iter)) {
const char *dest_sys, *dest_path, *src_sys, *src_path;
continue;
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats64)) < 0) {
+ char errbuf[1024];
ERROR("netlink plugin: link_filter_cb: IFLA_STATS64 mnl_attr_validate2 "
- "failed.");
+ "failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
return MNL_CB_ERROR;
}
stats.stats64 = mnl_attr_get_payload(attr);
continue;
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats32)) < 0) {
+ char errbuf[1024];
ERROR("netlink plugin: link_filter_cb: IFLA_STATS mnl_attr_validate2 "
- "failed.");
+ "failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
return MNL_CB_ERROR;
}
stats.stats32 = mnl_attr_get_payload(attr);
if (mnl_attr_get_type(attr) == TCA_STATS_BASIC) {
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(**bs)) < 0) {
+ char errbuf[1024];
ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 "
- "failed.");
+ "failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
return MNL_CB_ERROR;
}
*bs = mnl_attr_get_payload(attr);
continue;
if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*ts)) < 0) {
+ char errbuf[1024];
ERROR("netlink plugin: qos_filter_cb: TCA_STATS mnl_attr_validate2 "
- "failed.");
+ "failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
return MNL_CB_ERROR;
}
ts = mnl_attr_get_payload(attr);
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret < 0) {
- ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed.");
+ char errbuf[1024];
+ ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
return (-1);
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
}
if (ret < 0) {
- ERROR("netlink plugin: ir_read:mnl_socket_recvfrom failed.");
+ char errbuf[1024];
+ ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
continue;
}
-
} /* for (type_index) */
} /* for (if_index) */
buffer_len = *ret_buffer_len;
buffer_offset = 0;
- if (se->data.server.userdb == NULL) {
- c_complain(
- LOG_NOTICE, &complain_no_users,
- "network plugin: Received signed network packet but can't verify it "
- "because no user DB has been configured. Will accept it.");
- return (0);
- }
-
/* Check if the buffer has enough data for this structure. */
if (buffer_len <= PART_SIGNATURE_SHA256_SIZE)
return (-ENOMEM);
return (-1);
}
+ if (se->data.server.userdb == NULL) {
+ c_complain(
+ LOG_NOTICE, &complain_no_users,
+ "network plugin: Received signed network packet but can't verify it "
+ "because no user DB has been configured. Will accept it.");
+
+ *ret_buffer = buffer + pss_head_length;
+ *ret_buffer_len -= pss_head_length;
+
+ return (0);
+ }
+
/* Copy the hash. */
BUFFER_READ(pss.hash, sizeof(pss.hash));
part_size - buffer_offset,
/* in = */ NULL, /* in len = */ 0);
if (err != 0) {
- sfree(pea.username);
ERROR("network plugin: gcry_cipher_decrypt returned: %s. Username: %s",
gcry_strerror(err), pea.username);
+ sfree(pea.username);
return (-1);
}
parse_packet(se, buffer + buffer_offset, payload_len, flags | PP_ENCRYPTED,
pea.username);
- /* XXX: Free pea.username?!? */
-
/* Update return values */
*ret_buffer = buffer + part_size;
*ret_buffer_len = buffer_len - part_size;
#endif
}
- if (url != NULL) {
- curl_easy_setopt(curl, CURLOPT_URL, url);
- }
-
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
return (-1);
nginx_buffer_len = 0;
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
if (curl_easy_perform(curl) != CURLE_OK) {
WARNING("nginx plugin: curl_easy_perform failed: %s", nginx_curl_error);
return (-1);
}
/* kerninfo -> estimated error */
- offset_loop = scale_loop * ((gauge_t)ntohl(ik->offset));
+ offset_loop = (gauge_t)((int32_t)ntohl(ik->offset) * scale_loop);
freq_loop = ntpd_read_fp(ik->freq);
- offset_error = scale_error * ((gauge_t)ntohl(ik->esterror));
+ offset_error = (gauge_t)((int32_t)ntohl(ik->esterror) * scale_error);
DEBUG("info_kernel:\n"
" pll offset = %.8g\n"
if (rc != LDAP_SUCCESS) {
ERROR("openldap plugin: ldap_initialize failed: %s", ldap_err2string(rc));
st->state = 0;
- ldap_unbind_ext_s(ld, NULL, NULL);
+ if (ld != NULL)
+ ldap_unbind_ext_s(ld, NULL, NULL);
return (-1);
}
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);
+ if (st->ld != NULL)
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
return (-1);
}
}
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);
+ if (st->ld != NULL)
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
return (-1);
} else {
DEBUG("openldap plugin: Successfully connected to %s", st->url);
ERROR("openldap plugin: Failed to execute search: %s", ldap_err2string(rc));
ldap_msgfree(result);
st->state = 0;
- ldap_unbind_ext_s(st->ld, NULL, NULL);
+ if (st->ld != NULL)
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
return (-1);
}
* meta => [ { name => <name>, value => <value> }, ... ]
* }
*/
-static int av2notification_meta(pTHX_ AV *array, notification_meta_t **meta) {
- notification_meta_t **m = meta;
+static int av2notification_meta(pTHX_ AV *array,
+ notification_meta_t **ret_meta) {
+ notification_meta_t *tail = NULL;
int len = av_len(array);
for (int i = 0; i <= len; ++i) {
SV **tmp = av_fetch(array, i, 0);
- HV *hash;
- if (NULL == tmp)
+ if (tmp == NULL)
return -1;
if (!(SvROK(*tmp) && (SVt_PVHV == SvTYPE(SvRV(*tmp))))) {
continue;
}
- hash = (HV *)SvRV(*tmp);
+ HV *hash = (HV *)SvRV(*tmp);
- *m = smalloc(sizeof(**m));
+ notification_meta_t *m = calloc(1, sizeof(*m));
+ if (m == NULL)
+ return ENOMEM;
- if (NULL == (tmp = hv_fetch(hash, "name", 4, 0))) {
+ SV **name = hv_fetch(hash, "name", strlen("name"), 0);
+ if (name == NULL) {
log_warn("av2notification_meta: Skipping invalid "
"meta information.");
- free(*m);
+ sfree(m);
continue;
}
- sstrncpy((*m)->name, SvPV_nolen(*tmp), sizeof((*m)->name));
+ sstrncpy(m->name, SvPV_nolen(*name), sizeof(m->name));
- if (NULL == (tmp = hv_fetch(hash, "value", 5, 0))) {
+ SV **value = hv_fetch(hash, "value", strlen("value"), 0);
+ if (value == NULL) {
log_warn("av2notification_meta: Skipping invalid "
"meta information.");
- free(*m);
+ sfree(m);
continue;
}
- if (SvNOK(*tmp)) {
- (*m)->nm_value.nm_double = SvNVX(*tmp);
- (*m)->type = NM_TYPE_DOUBLE;
- } else if (SvUOK(*tmp)) {
- (*m)->nm_value.nm_unsigned_int = SvUVX(*tmp);
- (*m)->type = NM_TYPE_UNSIGNED_INT;
- } else if (SvIOK(*tmp)) {
- (*m)->nm_value.nm_signed_int = SvIVX(*tmp);
- (*m)->type = NM_TYPE_SIGNED_INT;
+ if (SvNOK(*value)) {
+ m->nm_value.nm_double = SvNVX(*value);
+ m->type = NM_TYPE_DOUBLE;
+ } else if (SvUOK(*value)) {
+ m->nm_value.nm_unsigned_int = SvUVX(*value);
+ m->type = NM_TYPE_UNSIGNED_INT;
+ } else if (SvIOK(*value)) {
+ m->nm_value.nm_signed_int = SvIVX(*value);
+ m->type = NM_TYPE_SIGNED_INT;
} else {
- (*m)->nm_value.nm_string = sstrdup(SvPV_nolen(*tmp));
- (*m)->type = NM_TYPE_STRING;
+ m->nm_value.nm_string = sstrdup(SvPV_nolen(*value));
+ m->type = NM_TYPE_STRING;
}
- (*m)->next = NULL;
- m = &((*m)->next);
+ m->next = NULL;
+ if (tail == NULL)
+ *ret_meta = m;
+ else
+ tail->next = m;
+ tail = m;
}
+
return 0;
} /* static int av2notification_meta (AV *, notification_meta_t *) */
static int notification_meta2av(pTHX_ notification_meta_t *meta, AV *array) {
int meta_num = 0;
-
- while (meta) {
+ for (notification_meta_t *m = meta; m != NULL; m = m->next) {
++meta_num;
- meta = meta->next;
}
av_extend(array, meta_num);
return 0;
} /* static int g_interval_set (pTHX_ SV *, MAGIC *) */
-static MGVTBL g_pv_vtbl = {g_pv_get, g_pv_set, NULL, NULL, NULL, NULL, NULL
+static MGVTBL g_pv_vtbl = {g_pv_get,
+ g_pv_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
#if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
,
NULL
#endif
};
-static MGVTBL g_interval_vtbl = {g_interval_get, g_interval_set, NULL, NULL,
- NULL, NULL, NULL
+static MGVTBL g_interval_vtbl = {g_interval_get,
+ g_interval_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
#if HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL
,
NULL
char *plugin;
HV *config;
+ if (NULL == perl_threads) {
+ log_err("A `Plugin' block was encountered but no plugin was loaded yet. "
+ "Put the appropriate `LoadPlugin' option in front of it.");
+ return -1;
+ }
+
dSP;
if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
static double ping_timeout = 0.9;
static int ping_max_missed = -1;
+static pthread_mutex_t ping_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t ping_cond = PTHREAD_COND_INITIALIZER;
static int ping_thread_loop = 0;
static int ping_thread_error = 0;
static pthread_t ping_thread_id;
-static pthread_mutex_t ping_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t ping_cond = PTHREAD_COND_INITIALIZER;
static const char *config_keys[] = {"Host", "SourceAddress",
#ifdef HAVE_OPING_1_3
static void *ping_thread(void *arg) /* {{{ */
{
- pingobj_t *pingobj = NULL;
-
struct timeval tv_begin;
struct timeval tv_end;
struct timespec ts_wait;
c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
- pthread_mutex_lock(&ping_lock);
-
- pingobj = ping_construct();
+ pingobj_t *pingobj = ping_construct();
if (pingobj == NULL) {
ERROR("ping plugin: ping_construct failed.");
+ pthread_mutex_lock(&ping_lock);
ping_thread_error = 1;
pthread_mutex_unlock(&ping_lock);
return ((void *)-1);
if (count == 0) {
ERROR("ping plugin: No host could be added to ping object. Giving up.");
+ pthread_mutex_lock(&ping_lock);
ping_thread_error = 1;
pthread_mutex_unlock(&ping_lock);
return ((void *)-1);
ts_int.tv_nsec = (long)(temp_nsec * 1000000000L);
}
+ pthread_mutex_lock(&ping_lock);
while (ping_thread_loop > 0) {
- int status;
_Bool send_successful = 0;
if (gettimeofday(&tv_begin, NULL) < 0) {
pthread_mutex_unlock(&ping_lock);
- status = ping_send(pingobj);
+ int status = ping_send(pingobj);
if (status < 0) {
c_complain(LOG_ERR, &complaint, "ping plugin: ping_send failed: %s",
ping_get_error(pingobj));
</Query>
<Query queries>
- Statement "SELECT sum(n_tup_ins) AS ins, \
- sum(n_tup_upd) AS upd, \
- sum(n_tup_del) AS del \
+ Statement "SELECT coalesce(sum(n_tup_ins), 0) AS ins, \
+ coalesce(sum(n_tup_upd), 0) AS upd, \
+ coalesce(sum(n_tup_del), 0) AS del \
FROM pg_stat_user_tables;"
<Result>
</Query>
<Query queries>
- Statement "SELECT sum(n_tup_ins) AS ins, \
- sum(n_tup_upd) AS upd, \
- sum(n_tup_del) AS del, \
- sum(n_tup_hot_upd) AS hot_upd \
+ Statement "SELECT coalesce(sum(n_tup_ins), 0) AS ins, \
+ coalesce(sum(n_tup_upd), 0) AS upd, \
+ coalesce(sum(n_tup_del), 0) AS del, \
+ coalesce(sum(n_tup_hot_upd), 0) AS hot_upd \
FROM pg_stat_user_tables;"
<Result>
</Query>
<Query table_states>
- Statement "SELECT sum(n_live_tup) AS live, sum(n_dead_tup) AS dead \
+ Statement "SELECT coalesce(sum(n_live_tup), 0) AS live, \
+ coalesce(sum(n_dead_tup), 0) AS dead \
FROM pg_stat_user_tables;"
<Result>
plugin_dispatch_values(&vl);
} /* }}} static void submit */
-static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
- char **ret_buffer, size_t *ret_buffer_size) {
+static int powerdns_get_data_dgram(list_item_t *item, char **ret_buffer) {
+ /* {{{ */
int sd;
int status;
buffer[buffer_size - 1] = 0;
*ret_buffer = buffer;
- *ret_buffer_size = buffer_size;
-
return (0);
} /* }}} int powerdns_get_data_dgram */
-static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
- char **ret_buffer,
- size_t *ret_buffer_size) {
+static int powerdns_get_data_stream(list_item_t *item, char **ret_buffer) {
+ /* {{{ */
int sd;
int status;
if (status < 0) {
SOCK_ERROR("recv", item->sockaddr.sun_path);
break;
- } else if (status == 0)
+ } else if (status == 0) {
break;
+ }
buffer_new = realloc(buffer, buffer_size + status + 1);
if (buffer_new == NULL) {
FUNC_ERROR("realloc");
- status = -1;
+ status = ENOMEM;
break;
}
buffer = buffer_new;
} /* while (42) */
close(sd);
- if (status < 0) {
+ if (status != 0) {
sfree(buffer);
- } else {
- assert(status == 0);
- *ret_buffer = buffer;
- *ret_buffer_size = buffer_size;
+ return status;
}
- return (status);
+ *ret_buffer = buffer;
+ return 0;
} /* }}} int powerdns_get_data_stream */
-static int powerdns_get_data(list_item_t *item, char **ret_buffer,
- size_t *ret_buffer_size) {
+static int powerdns_get_data(list_item_t *item, char **ret_buffer) {
if (item->socktype == SOCK_DGRAM)
- return (powerdns_get_data_dgram(item, ret_buffer, ret_buffer_size));
+ return (powerdns_get_data_dgram(item, ret_buffer));
else if (item->socktype == SOCK_STREAM)
- return (powerdns_get_data_stream(item, ret_buffer, ret_buffer_size));
+ return (powerdns_get_data_stream(item, ret_buffer));
else {
ERROR("powerdns plugin: Unknown socket type: %i", (int)item->socktype);
return (-1);
static int powerdns_read_server(list_item_t *item) /* {{{ */
{
- char *buffer = NULL;
- size_t buffer_size = 0;
- int status;
-
- char *dummy;
- char *saveptr;
-
- char *key;
- char *value;
-
- const char *const *fields;
- int fields_num;
-
if (item->command == NULL)
item->command = strdup(SERVER_COMMAND);
if (item->command == NULL) {
return (-1);
}
- status = powerdns_get_data(item, &buffer, &buffer_size);
- if (status != 0)
- return (-1);
+ char *buffer = NULL;
+ int status = powerdns_get_data(item, &buffer);
+ if (status != 0) {
+ ERROR("powerdns plugin: powerdns_get_data failed.");
+ return (status);
+ }
+ if (buffer == NULL) {
+ return EINVAL;
+ }
+ const char *const *fields = default_server_fields;
+ int fields_num = default_server_fields_num;
if (item->fields_num != 0) {
fields = (const char *const *)item->fields;
fields_num = item->fields_num;
- } else {
- fields = default_server_fields;
- fields_num = default_server_fields_num;
}
assert(fields != NULL);
/* corrupt-packets=0,deferred-cache-inserts=0,deferred-cache-lookup=0,latency=0,packetcache-hit=0,packetcache-miss=0,packetcache-size=0,qsize-q=0,query-cache-hit=0,query-cache-miss=0,recursing-answers=0,recursing-questions=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,udp4-answers=0,udp4-queries=0,udp6-answers=0,udp6-queries=0,
*/
- dummy = buffer;
- saveptr = NULL;
+ char *dummy = buffer;
+ char *saveptr = NULL;
+ char *key;
while ((key = strtok_r(dummy, ",", &saveptr)) != NULL) {
dummy = NULL;
- value = strchr(key, '=');
+ char *value = strchr(key, '=');
if (value == NULL)
break;
static int powerdns_read_recursor(list_item_t *item) /* {{{ */
{
char *buffer = NULL;
- size_t buffer_size = 0;
int status;
char *dummy;
}
assert(item->command != NULL);
- status = powerdns_get_data(item, &buffer, &buffer_size);
+ status = powerdns_get_data(item, &buffer);
if (status != 0) {
ERROR("powerdns plugin: powerdns_get_data failed.");
return (-1);
pse.cpu_user_counter = procentry[i].pi_ru.ru_utime.tv_sec * 1000000 +
procentry[i].pi_ru.ru_utime.tv_usec / 1000;
- pse.cpu_system = 0;
/* tv_usec is nanosec ??? */
pse.cpu_system_counter = procentry[i].pi_ru.ru_stime.tv_sec * 1000000 +
procentry[i].pi_ru.ru_stime.tv_usec / 1000;
* ALWAYS lock `cache_lock' first! */
static cdtime_t cache_timeout = 0;
static cdtime_t cache_flush_timeout = 0;
-static cdtime_t random_timeout = TIME_T_TO_CDTIME_T_STATIC(1);
+static cdtime_t random_timeout = 0;
static cdtime_t cache_flush_last;
static c_avl_tree_t *cache = NULL;
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
CDTIME_T_TO_DOUBLE(timeout));
now = cdtime();
- timeout = TIME_T_TO_CDTIME_T(timeout);
/* Build a list of entries to be flushed */
iter = c_avl_get_iterator(cache);
} /* int rrd_cache_flush_identifier */
static int64_t rrd_get_random_variation(void) {
- long min;
- long max;
-
if (random_timeout == 0)
return (0);
- /* Assure that "cache_timeout + random_variation" is never negative. */
- if (random_timeout > cache_timeout) {
- INFO("rrdtool plugin: Adjusting \"RandomTimeout\" to %.3f seconds.",
- CDTIME_T_TO_DOUBLE(cache_timeout));
- random_timeout = cache_timeout;
- }
-
- max = (long)(random_timeout / 2);
- min = max - ((long)random_timeout);
-
- return ((int64_t)cdrand_range(min, max));
+ return (int64_t)cdrand_range(-random_timeout, random_timeout);
} /* int64_t rrd_get_random_variation */
static int rrd_cache_insert(const char *filename, const char *value,
return (-1);
}
- c_avl_get(cache, filename, (void *)&rc);
-
- if (rc == NULL) {
+ int status = c_avl_get(cache, filename, (void *)&rc);
+ if ((status != 0) || (rc == NULL)) {
rc = malloc(sizeof(*rc));
if (rc == NULL) {
pthread_mutex_unlock(&cache_lock);
if ((cache_timeout > 0) &&
((cdtime() - cache_flush_last) > cache_flush_timeout))
- rrd_cache_flush(cache_flush_timeout);
+ rrd_cache_flush(cache_timeout + random_timeout);
pthread_mutex_unlock(&cache_lock);
}
cache_timeout = DOUBLE_TO_CDTIME_T(tmp);
} else if (strcasecmp("CacheFlush", key) == 0) {
- int tmp = atoi(value);
+ double tmp = atof(value);
if (tmp < 0) {
fprintf(stderr, "rrdtool: `CacheFlush' must "
"be greater than 0.\n");
"be greater than 0.\n");
return (1);
}
- cache_flush_timeout = tmp;
+ cache_flush_timeout = DOUBLE_TO_CDTIME_T(tmp);
} else if (strcasecmp("DataDir", key) == 0) {
char *tmp;
size_t len;
cache_flush_last = cdtime();
if (cache_timeout == 0) {
+ random_timeout = 0;
cache_flush_timeout = 0;
- } else if (cache_flush_timeout < cache_timeout)
+ } else if (cache_flush_timeout < cache_timeout) {
+ INFO("rrdtool plugin: \"CacheFlush %.3f\" is less than \"CacheTimeout "
+ "%.3f\". Adjusting \"CacheFlush\" to %.3f seconds.",
+ CDTIME_T_TO_DOUBLE(cache_flush_timeout),
+ CDTIME_T_TO_DOUBLE(cache_timeout),
+ CDTIME_T_TO_DOUBLE(cache_timeout * 10));
cache_flush_timeout = 10 * cache_timeout;
+ }
+
+ /* Assure that "cache_timeout + random_variation" is never negative. */
+ if (random_timeout > cache_timeout) {
+ INFO("rrdtool plugin: Adjusting \"RandomTimeout\" to %.3f seconds.",
+ CDTIME_T_TO_DOUBLE(cache_timeout));
+ random_timeout = cache_timeout;
+ }
pthread_mutex_unlock(&cache_lock);
#include <atasmart.h>
#include <libudev.h>
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif
+
static const char *config_keys[] = {"Disk", "IgnoreSelected", "IgnoreSleepMode",
"UseSerial"};
return (0);
} /* int smart_read */
+static int smart_init(void) {
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_RAWIO)
+ if (check_capability(CAP_SYS_RAWIO) != 0) {
+ if (getuid() == 0)
+ WARNING("smart plugin: Running collectd as root, but the "
+ "CAP_SYS_RAWIO capability is missing. The plugin's read "
+ "function will probably fail. Is your init system dropping "
+ "capabilities?");
+ else
+ WARNING("smart plugin: collectd doesn't have the CAP_SYS_RAWIO "
+ "capability. If you don't want to run collectd as root, try "
+ "running \"setcap cap_sys_rawio=ep\" on the collectd binary.");
+ }
+#endif
+ return (0);
+} /* int smart_init */
+
void module_register(void) {
plugin_register_config("smart", smart_config, config_keys, config_keys_num);
+ plugin_register_init("smart", smart_init);
plugin_register_read("smart", smart_read);
} /* void module_register */
if (oid_list_todo_num == 0) {
/* The request is still empty - so we are finished */
DEBUG("snmp plugin: all variables have left their subtree");
+ snmp_free_pdu(req);
status = 0;
break;
}
res = NULL;
status = snmp_sess_synch_response(host->sess_handle, req, &res);
+
+ /* snmp_sess_synch_response always frees our req PDU */
+ req = NULL;
+
if ((status != STAT_SUCCESS) || (res == NULL)) {
char *errstr = NULL;
snmp_free_pdu(res);
res = NULL;
- /* snmp_synch_response already freed our PDU */
- req = NULL;
sfree(errstr);
csnmp_host_close_session(host);
for (vb = res->variables, i = 0; (vb != NULL);
vb = vb->next_variable, i++) {
/* Calculate value index from todo list */
- while ((i < oid_list_len) && !oid_list_todo[i])
+ while ((i < oid_list_len) && !oid_list_todo[i]) {
i++;
+ }
+ if (i >= oid_list_len) {
+ break;
+ }
/* An instance is configured and the res variable we process is the
* instance value (last index) */
snmp_free_pdu(res);
res = NULL;
- if (req != NULL)
- snmp_free_pdu(req);
- req = NULL;
-
if (status == 0)
csnmp_dispatch_table(host, data, instance_list_head, value_list_head);
} /* tbl_result_setup */
static void tbl_result_clear(tbl_result_t *res) {
+ if (res == NULL) {
+ return;
+ }
+
sfree(res->type);
sfree(res->instance_prefix);
} /* tbl_setup */
static void tbl_clear(tbl_t *tbl) {
+ if (tbl == NULL) {
+ return;
+ }
+
sfree(tbl->file);
sfree(tbl->sep);
sfree(tbl->instance);
+ /* (tbl->results == NULL) -> (tbl->results_num == 0) */
+ assert((tbl->results != NULL) || (tbl->results_num == 0));
for (size_t i = 0; i < tbl->results_num; ++i)
tbl_result_clear(tbl->results + i);
sfree(tbl->results);
} /* tbl_config_append_array_s */
static int tbl_config_result(tbl_t *tbl, oconfig_item_t *ci) {
- tbl_result_t *res;
-
- int status = 0;
-
if (0 != ci->values_num) {
log_err("<Result> does not expect any arguments.");
return 1;
}
- res = realloc(tbl->results, (tbl->results_num + 1) * sizeof(*tbl->results));
+ tbl_result_t *res =
+ realloc(tbl->results, (tbl->results_num + 1) * sizeof(*tbl->results));
if (res == NULL) {
char errbuf[1024];
log_err("realloc failed: %s.", sstrerror(errno, errbuf, sizeof(errbuf)));
}
tbl->results = res;
- ++tbl->results_num;
- res = tbl->results + tbl->results_num - 1;
+ res = tbl->results + tbl->results_num;
tbl_result_setup(res);
for (int i = 0; i < ci->children_num; ++i) {
c->key);
}
+ int status = 0;
if (NULL == res->type) {
- log_err("No \"Type\" option specified for <Result> "
- "in table \"%s\".",
+ log_err("No \"Type\" option specified for <Result> in table \"%s\".",
tbl->file);
status = 1;
}
if (NULL == res->values) {
- log_err("No \"ValuesFrom\" option specified for <Result> "
- "in table \"%s\".",
+ log_err("No \"ValuesFrom\" option specified for <Result> in table \"%s\".",
tbl->file);
status = 1;
}
if (0 != status) {
tbl_result_clear(res);
- --tbl->results_num;
return status;
}
+
+ tbl->results_num++;
return 0;
} /* tbl_config_result */
static int tbl_config_table(oconfig_item_t *ci) {
- tbl_t *tbl;
-
- int status = 0;
-
if ((1 != ci->values_num) || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
log_err("<Table> expects a single string argument.");
return 1;
}
- tbl = realloc(tables, (tables_num + 1) * sizeof(*tables));
+ tbl_t *tbl = realloc(tables, (tables_num + 1) * sizeof(*tables));
if (NULL == tbl) {
char errbuf[1024];
log_err("realloc failed: %s.", sstrerror(errno, errbuf, sizeof(errbuf)));
}
tables = tbl;
- ++tables_num;
- tbl = tables + tables_num - 1;
+ tbl = tables + tables_num;
tbl_setup(tbl, ci->values[0].value.string);
for (size_t i = 0; i < ((size_t)ci->children_num); ++i) {
c->key, tbl->file);
}
+ int status = 0;
if (NULL == tbl->sep) {
log_err("Table \"%s\" does not specify any separator.", tbl->file);
status = 1;
}
if (NULL == tbl->results) {
+ assert(tbl->results_num == 0);
log_err("Table \"%s\" does not specify any (valid) results.", tbl->file);
status = 1;
}
if (0 != status) {
tbl_clear(tbl);
- --tables_num;
return status;
}
if (res->values[j] > tbl->max_colnum)
tbl->max_colnum = res->values[j];
}
+
+ tables_num++;
return 0;
} /* tbl_config_table */
REPLACE_FIELD("%{type_instance}", vl->type_instance);
if (vl->meta != NULL) {
- char **meta_toc;
- int meta_entries = meta_data_toc(vl->meta, &meta_toc);
- for (int i = 0; i < meta_entries; i++) {
+ char **meta_toc = NULL;
+ int status = meta_data_toc(vl->meta, &meta_toc);
+ if (status <= 0)
+ return;
+ size_t meta_entries = (size_t)status;
+
+ for (size_t i = 0; i < meta_entries; i++) {
char meta_name[DATA_MAX_NAME_LEN];
char *value_str;
const char *key = meta_toc[i];
if (data->meta != NULL) {
char temp[DATA_MAX_NAME_LEN * 2];
- int meta_entries;
char **meta_toc;
if ((new_meta = meta_data_create()) == NULL) {
return (-ENOMEM);
}
- meta_entries = meta_data_toc(data->meta, &meta_toc);
- for (int i = 0; i < meta_entries; i++) {
+ int status = meta_data_toc(data->meta, &meta_toc);
+ if (status < 0) {
+ ERROR("Target `set': meta_data_toc failed with status %d.", status);
+ meta_data_destroy(new_meta);
+ return status;
+ }
+ size_t meta_entries = (size_t)status;
+
+ for (size_t i = 0; i < meta_entries; i++) {
const char *key = meta_toc[i];
char *string;
int status;
if (status) {
ERROR("Target `set': Unable to get replacement metadata value `%s'.",
key);
- strarray_free(meta_toc, (size_t)meta_entries);
+ strarray_free(meta_toc, meta_entries);
+ meta_data_destroy(new_meta);
return (status);
}
status = meta_data_add_string(new_meta, key, temp);
if (status) {
ERROR("Target `set': Unable to set metadata value `%s'.", key);
- strarray_free(meta_toc, (size_t)meta_entries);
+ strarray_free(meta_toc, meta_entries);
+ meta_data_destroy(new_meta);
return (status);
}
}
- strarray_free(meta_toc, (size_t)meta_entries);
+ strarray_free(meta_toc, meta_entries);
}
#define SUBST_FIELD(f) \
for (in_ptr = (struct xinpgen *)(((char *)in_orig) + in_orig->xig_len);
in_ptr->xig_len > sizeof(struct xinpgen);
in_ptr = (struct xinpgen *)(((char *)in_ptr) + in_ptr->xig_len)) {
+#if __FreeBSD_version >= 1200026
+ struct xtcpcb *tp = (struct xtcpcb *)in_ptr;
+ struct xinpcb *inp = &tp->xt_inp;
+ struct xsocket *so = &inp->xi_socket;
+#else
struct tcpcb *tp = &((struct xtcpcb *)in_ptr)->xt_tp;
struct inpcb *inp = &((struct xtcpcb *)in_ptr)->xt_inp;
struct xsocket *so = &((struct xtcpcb *)in_ptr)->xt_socket;
+#endif
/* Ignore non-TCP sockets */
if (so->xso_protocol != IPPROTO_TCP)
#include "plugin.h"
#include "utils_time.h"
-#include <asm/msr-index.h>
+#include "msr-index.h"
#include <cpuid.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
1.0 / 1000000 * t->aperf / interval_float);
if ((!aperf_mperf_unstable) || (!(t->aperf > t->tsc || t->mperf > t->tsc)))
- turbostat_submit(name, "frequency", "busy", 1.0 * t->tsc / 1000000 *
- t->aperf / t->mperf /
- interval_float);
+ turbostat_submit(name, "frequency", "busy",
+ 1.0 * t->tsc / 1000000 * t->aperf / t->mperf /
+ interval_float);
/* Sanity check (should stay stable) */
turbostat_submit(name, "gauge", "TSC",
const char *grpname;
struct group *g;
struct group sg;
- char grbuf[2048];
+
+ long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (grbuf_size <= 0)
+ grbuf_size = sysconf(_SC_PAGESIZE);
+ if (grbuf_size <= 0)
+ grbuf_size = 4096;
+ char grbuf[grbuf_size];
grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME;
g = NULL;
if (status != 0) {
char errbuf[1024];
WARNING("unixsock plugin: getgrnam_r (%s) failed: %s", grpname,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ sstrerror(status, errbuf, sizeof(errbuf)));
break;
}
if (g == NULL) {
print_to_socket(fh, "%zu Threshold found\n", i);
if (threshold.host[0] != 0)
- print_to_socket(fh, "Host: %s\n", threshold.host) if (
- threshold.plugin[0] !=
- 0) print_to_socket(fh, "Plugin: %s\n",
- threshold.plugin) if (threshold.plugin_instance[0] !=
- 0)
- print_to_socket(fh, "Plugin Instance: %s\n",
- threshold.plugin_instance) if (threshold.type[0] != 0)
- print_to_socket(fh, "Type: %s\n", threshold.type) if (
- threshold.type_instance[0] !=
- 0) print_to_socket(fh, "Type Instance: %s\n",
- threshold
- .type_instance) if (threshold.data_source
- [0] != 0)
- print_to_socket(
- fh, "Data Source: %s\n",
- threshold.data_source) if (!isnan(threshold.warning_min))
- print_to_socket(
- fh, "Warning Min: %g\n",
- threshold
- .warning_min) if (!isnan(threshold.warning_max))
- print_to_socket(
- fh, "Warning Max: %g\n",
- threshold
- .warning_max) if (!isnan(threshold.failure_min))
- print_to_socket(
- fh, "Failure Min: %g\n",
- threshold
- .failure_min) if (!isnan(threshold
- .failure_max))
- print_to_socket(
- fh, "Failure Max: %g\n",
- threshold.failure_max) if (threshold
- .hysteresis >
- 0.0)
- print_to_socket(
- fh, "Hysteresis: %g\n",
- threshold.hysteresis) if (threshold
- .hits > 1)
- print_to_socket(fh, "Hits: %i\n",
- threshold.hits)
-
- return (0);
+ print_to_socket(fh, "Host: %s\n", threshold.host);
+ if (threshold.plugin[0] != 0)
+ print_to_socket(fh, "Plugin: %s\n", threshold.plugin);
+ if (threshold.plugin_instance[0] != 0)
+ print_to_socket(fh, "Plugin Instance: %s\n", threshold.plugin_instance);
+ if (threshold.type[0] != 0)
+ print_to_socket(fh, "Type: %s\n", threshold.type);
+ if (threshold.type_instance[0] != 0)
+ print_to_socket(fh, "Type Instance: %s\n", threshold.type_instance);
+ if (threshold.data_source[0] != 0)
+ print_to_socket(fh, "Data Source: %s\n", threshold.data_source);
+ if (!isnan(threshold.warning_min))
+ print_to_socket(fh, "Warning Min: %g\n", threshold.warning_min);
+ if (!isnan(threshold.warning_max))
+ print_to_socket(fh, "Warning Max: %g\n", threshold.warning_max);
+ if (!isnan(threshold.failure_min))
+ print_to_socket(fh, "Failure Min: %g\n", threshold.failure_min);
+ if (!isnan(threshold.failure_max))
+ print_to_socket(fh, "Failure Max: %g\n", threshold.failure_max);
+ if (threshold.hysteresis > 0.0)
+ print_to_socket(fh, "Hysteresis: %g\n", threshold.hysteresis);
+ if (threshold.hits > 1)
+ print_to_socket(fh, "Hits: %i\n", threshold.hits);
+
+ return (0);
} /* int handle_getthreshold */
/* vim: set sw=2 sts=2 ts=8 et : */
type = NULL;
type_instance = NULL;
- vl.values_len = ds->ds_num;
- vl.values = malloc(vl.values_len * sizeof(*vl.values));
- if (vl.values == NULL) {
- cmd_error(CMD_ERROR, err, "malloc failed.");
- sfree(identifier_copy);
- return (CMD_ERROR);
- }
-
ret_putval->raw_identifier = identifier_copy;
if (ret_putval->raw_identifier == NULL) {
cmd_error(CMD_ERROR, err, "malloc failed.");
/* else: cmd_parse_option did not find an option; treat this as a
* value list. */
+ vl.values_len = ds->ds_num;
+ vl.values = calloc(vl.values_len, sizeof(*vl.values));
+ if (vl.values == NULL) {
+ cmd_error(CMD_ERROR, err, "malloc failed.");
+ result = CMD_ERROR;
+ break;
+ }
+
status = parse_values(argv[i], &vl, ds);
if (status != 0) {
cmd_error(CMD_PARSE_ERROR, err, "Parsing the values string failed.");
result = CMD_PARSE_ERROR;
+ vl.values_len = 0;
+ sfree(vl.values);
break;
}
- tmp = (value_list_t *)realloc(ret_putval->vl, (ret_putval->vl_num + 1) *
- sizeof(*ret_putval->vl));
+ tmp = realloc(ret_putval->vl,
+ (ret_putval->vl_num + 1) * sizeof(*ret_putval->vl));
if (tmp == NULL) {
cmd_error(CMD_ERROR, err, "realloc failed.");
cmd_destroy_putval(ret_putval);
result = CMD_ERROR;
+ vl.values_len = 0;
+ sfree(vl.values);
break;
}
ret_putval->vl = tmp;
ret_putval->vl_num++;
memcpy(&ret_putval->vl[ret_putval->vl_num - 1], &vl, sizeof(vl));
+
+ /* pointer is now owned by ret_putval->vl[] */
+ vl.values_len = 0;
+ vl.values = NULL;
} /* while (*buffer != 0) */
/* Done parsing the options. */
- if (result != CMD_OK) {
- if (ret_putval->vl_num == 0)
- sfree(vl.values);
+ if (result != CMD_OK)
cmd_destroy_putval(ret_putval);
- }
return (result);
} /* cmd_status_t cmd_parse_putval */
sfree(putval->raw_identifier);
for (size_t i = 0; i < putval->vl_num; ++i) {
- if (i == 0) /* values is shared between all entries */
- sfree(putval->vl[i].values);
+ sfree(putval->vl[i].values);
meta_data_destroy(putval->vl[i].meta);
putval->vl[i].meta = NULL;
}
int buffer_pos = 0;
gauge_t *rates = NULL;
- if (flags & GRAPHITE_STORE_RATES)
+ if (flags & GRAPHITE_STORE_RATES) {
rates = uc_get_rate(ds, vl);
+ if (rates == NULL) {
+ ERROR("format_graphite: error with uc_get_rate");
+ return -1;
+ }
+ }
for (size_t i = 0; i < ds->ds_num; i++) {
char const *ds_name = NULL;
} \
} while (0)
+#define CHECK_SUCCESS(cmd) \
+ do { \
+ yajl_gen_status s = (cmd); \
+ if (s != yajl_gen_status_ok) { \
+ return (int)s; \
+ } \
+ } while (0)
+
static int format_json_meta(yajl_gen g, notification_meta_t *meta) /* {{{ */
{
if (meta == NULL)
default:
ERROR("format_json_meta: unknown meta data type %d (name \"%s\")",
meta->type, meta->name);
- yajl_gen_null(g);
+ CHECK_SUCCESS(yajl_gen_null(g));
}
return format_json_meta(g, meta->next);
static int format_alert(yajl_gen g, notification_t const *n) /* {{{ */
{
- yajl_gen_array_open(g);
- yajl_gen_map_open(g); /* BEGIN alert */
+ CHECK_SUCCESS(yajl_gen_array_open(g)); /* BEGIN array */
+ CHECK_SUCCESS(yajl_gen_map_open(g)); /* BEGIN alert */
/*
* labels
*/
JSON_ADD(g, "labels");
- yajl_gen_map_open(g); /* BEGIN labels */
+ CHECK_SUCCESS(yajl_gen_map_open(g)); /* BEGIN labels */
JSON_ADD(g, "alertname");
if (strncmp(n->plugin, n->type, strlen(n->plugin)) == 0)
}
JSON_ADD(g, "severity");
- JSON_ADD(g, (n->severity == NOTIF_FAILURE)
- ? "FAILURE"
- : (n->severity == NOTIF_WARNING)
- ? "WARNING"
- : (n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN");
+ JSON_ADD(g,
+ (n->severity == NOTIF_FAILURE)
+ ? "FAILURE"
+ : (n->severity == NOTIF_WARNING)
+ ? "WARNING"
+ : (n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN");
JSON_ADD(g, "service");
JSON_ADD(g, "collectd");
- yajl_gen_map_close(g); /* END labels */
+ CHECK_SUCCESS(yajl_gen_map_close(g)); /* END labels */
/*
* annotations
*/
JSON_ADD(g, "annotations");
- yajl_gen_map_open(g); /* BEGIN annotations */
+ CHECK_SUCCESS(yajl_gen_map_open(g)); /* BEGIN annotations */
JSON_ADD(g, "summary");
JSON_ADD(g, n->message);
- if (format_json_meta(g, n->meta) != 0)
+ if (format_json_meta(g, n->meta) != 0) {
return -1;
+ }
- yajl_gen_map_close(g); /* END annotations */
+ CHECK_SUCCESS(yajl_gen_map_close(g)); /* END annotations */
JSON_ADD(g, "startsAt");
- format_time(g, n->time);
+ if (format_time(g, n->time) != 0) {
+ return -1;
+ }
- yajl_gen_map_close(g); /* END alert */
- yajl_gen_array_close(g);
+ CHECK_SUCCESS(yajl_gen_map_close(g)); /* END alert */
+ CHECK_SUCCESS(yajl_gen_array_close(g)); /* END array */
return 0;
} /* }}} format_alert */
}
/* copy to output buffer */
- yajl_gen_get_buf(g, &out, &unused_out_len);
+ if (yajl_gen_get_buf(g, &out, &unused_out_len) != yajl_gen_status_ok) {
+ yajl_gen_clear(g);
+ yajl_gen_free(g);
+ return -1;
+ }
sstrncpy(buffer, (void *)out, buffer_size);
yajl_gen_clear(g);
#include <regex.h>
#define UTILS_MATCH_FLAGS_EXCLUDE_REGEX 0x02
+#define UTILS_MATCH_FLAGS_REGEX 0x04
struct cu_match_s {
regex_t regex;
sfree(obj);
return (NULL);
}
+ obj->flags |= UTILS_MATCH_FLAGS_REGEX;
if (excluderegex && strcmp(excluderegex, "") != 0) {
status = regcomp(&obj->excluderegex, excluderegex, REG_EXTENDED);
if (obj == NULL)
return;
+ if (obj->flags & UTILS_MATCH_FLAGS_REGEX)
+ regfree(&obj->regex);
+ if (obj->flags & UTILS_MATCH_FLAGS_EXCLUDE_REGEX)
+ regfree(&obj->excluderegex);
if ((obj->user_data != NULL) && (obj->free != NULL))
(*obj->free)(obj->user_data);
sfree(cb->prefix);
sfree(cb->postfix);
+ pthread_mutex_unlock(&cb->send_lock);
pthread_mutex_destroy(&cb->send_lock);
sfree(cb);
{
int status = 0;
+ curl_easy_setopt(cb->curl, CURLOPT_URL, cb->location);
curl_easy_setopt(cb->curl, CURLOPT_POSTFIELDS, data);
status = curl_easy_perform(cb->curl);
curl_easy_setopt(cb->curl, CURLOPT_HTTPHEADER, cb->headers);
curl_easy_setopt(cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf);
- curl_easy_setopt(cb->curl, CURLOPT_URL, cb->location);
curl_easy_setopt(cb->curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(cb->curl, CURLOPT_MAXREDIRS, 50L);
}
#endif
+static rd_kafka_resp_err_t kafka_error() {
+#if RD_KAFKA_VERSION >= 0x000b00ff
+ return rd_kafka_last_error();
+#else
+ return rd_kafka_errno2err(errno);
+#endif
+}
+
static uint32_t kafka_hash(const char *keydata, size_t keylen) {
uint32_t hash = 5381;
for (; keylen > 0; keylen--)
if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
topic_conf)) == NULL) {
ERROR("write_kafka plugin: cannot create topic : %s\n",
- rd_kafka_err2str(rd_kafka_errno2err(errno)));
+ rd_kafka_err2str(kafka_error()));
return errno;
}
#include <microhttpd.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
#ifndef PROMETHEUS_DEFAULT_STALENESS_DELTA
#define PROMETHEUS_DEFAULT_STALENESS_DELTA TIME_T_TO_CDTIME_T_STATIC(300)
#endif
((fam->n_metric - 1) - i) * sizeof(fam->metric[i]));
fam->n_metric--;
+ if (fam->n_metric == 0) {
+ sfree(fam->metric);
+ return 0;
+ }
+
Io__Prometheus__Client__Metric **tmp =
realloc(fam->metric, fam->n_metric * sizeof(*fam->metric));
- if ((tmp != NULL) || (fam->n_metric == 0))
+ if (tmp != NULL)
fam->metric = tmp;
return 0;
return fam;
}
- if (!allocate)
+ if (!allocate) {
+ sfree(name);
return NULL;
+ }
fam = metric_family_create(name, ds, vl, ds_index);
if (fam == NULL) {
}
/* }}} */
+static void prom_logger(__attribute__((unused)) void *arg, char const *fmt,
+ va_list ap) {
+ /* {{{ */
+ char errbuf[1024];
+ vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
+
+ ERROR("write_prometheus plugin: %s", errbuf);
+} /* }}} prom_logger */
+
+#if MHD_VERSION >= 0x00090000
+static int prom_open_socket(int addrfamily) {
+ /* {{{ */
+ char service[NI_MAXSERV];
+ snprintf(service, sizeof(service), "%hu", httpd_port);
+
+ struct addrinfo *res;
+ int status = getaddrinfo(NULL, service,
+ &(struct addrinfo){
+ .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
+ .ai_family = addrfamily,
+ .ai_socktype = SOCK_STREAM,
+ },
+ &res);
+ if (status != 0) {
+ return -1;
+ }
+
+ int fd = -1;
+ for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) {
+ fd = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, 0);
+ if (fd == -1)
+ continue;
+
+ if (bind(fd, ai->ai_addr, ai->ai_addrlen) != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
+ if (listen(fd, /* backlog = */ 16) != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
+ break;
+ }
+
+ freeaddrinfo(res);
+
+ return fd;
+} /* }}} int prom_open_socket */
+
+static struct MHD_Daemon *prom_start_daemon() {
+ /* {{{ */
+ int fd = prom_open_socket(PF_INET6);
+ if (fd == -1)
+ fd = prom_open_socket(PF_INET);
+ if (fd == -1) {
+ ERROR("write_prometheus plugin: Opening a listening socket failed.");
+ return NULL;
+ }
+
+ struct MHD_Daemon *d = MHD_start_daemon(
+ MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, httpd_port,
+ /* MHD_AcceptPolicyCallback = */ NULL,
+ /* MHD_AcceptPolicyCallback arg = */ NULL, http_handler, NULL,
+ MHD_OPTION_LISTEN_SOCKET, fd, MHD_OPTION_EXTERNAL_LOGGER, prom_logger,
+ NULL, MHD_OPTION_END);
+ if (d == NULL) {
+ ERROR("write_prometheus plugin: MHD_start_daemon() failed.");
+ close(fd);
+ return NULL;
+ }
+
+ return d;
+} /* }}} struct MHD_Daemon *prom_start_daemon */
+#else /* if MHD_VERSION < 0x00090000 */
+static struct MHD_Daemon *prom_start_daemon() {
+ /* {{{ */
+ struct MHD_Daemon *d = MHD_start_daemon(
+ MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, httpd_port,
+ /* MHD_AcceptPolicyCallback = */ NULL,
+ /* MHD_AcceptPolicyCallback arg = */ NULL, http_handler, NULL,
+ MHD_OPTION_EXTERNAL_LOGGER, prom_logger, NULL, MHD_OPTION_END);
+ if (d == NULL) {
+ ERROR("write_prometheus plugin: MHD_start_daemon() failed.");
+ return NULL;
+ }
+
+ return d;
+} /* }}} struct MHD_Daemon *prom_start_daemon */
+#endif
+
/*
* collectd callbacks
*/
}
if (httpd == NULL) {
- unsigned int flags = MHD_USE_THREAD_PER_CONNECTION;
-#if MHD_VERSION >= 0x00093300
- flags |= MHD_USE_DUAL_STACK;
-#endif
-
- httpd = MHD_start_daemon(flags, httpd_port,
- /* MHD_AcceptPolicyCallback = */ NULL,
- /* MHD_AcceptPolicyCallback arg = */ NULL,
- http_handler, NULL, MHD_OPTION_END);
+ httpd = prom_start_daemon();
if (httpd == NULL) {
ERROR("write_prometheus plugin: MHD_start_daemon() failed.");
return -1;
wrr_disconnect(host);
+ pthread_mutex_lock(&host->lock);
pthread_mutex_destroy(&host->lock);
sfree(host);
} /* }}} void wrr_free */
#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_cache.h"
+
#include <arpa/inet.h>
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
#include <stddef.h>
-#include "common.h"
-#include "plugin.h"
-#include "utils_cache.h"
#include <stdlib.h>
#define SENSU_HOST "localhost"
sfree(host->separator);
free_str_list(&(host->metric_handlers));
free_str_list(&(host->notification_handlers));
+
+ pthread_mutex_unlock(&host->lock);
pthread_mutex_destroy(&host->lock);
+
sfree(host);
} /* }}} void sensu_free */
sfree(cb->service);
sfree(cb->host_tags);
+ pthread_mutex_unlock(&cb->send_lock);
pthread_mutex_destroy(&cb->send_lock);
sfree(cb);
#!/bin/sh
-DEFAULT_VERSION="5.7.0.git"
+DEFAULT_VERSION="5.7.2.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"