+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.
+ * collectd: The capability checking has been rewritten to be more
+ portable. Thanks to Florian Forster. #2009
+ * collectd.conf(5): Various typos have been fixed. Thanks to Marc
+ Fournier.
+ * collectd-tg: Incorrect usage of "nanosleep()" has been fixed which
+ caused the tool to sleep (almost) indefinitely. Thanks to Florian
+ Forster.
+ * Build system: Detection of the Java environment has been made
+ deterministic to allow for reproducible builds. Thanks to Marc
+ Fournier. #1523
+ * Build system: Detection of the Lua headers has been improved. Thanks
+ to Ruben Kerkhof.
+ * APC UPS plugin: Unavailable metrics are now skipped instead of
+ reported as 0 (zero). Thanks to Florian Forster. #2025
+ * Modbus plugin: Build issues on FreeBSD have been fixed. Thanks to
+ Florian Forster.
+ * OpenVPN plugin: Gracefully handle empty configurations. Thanks to
+ Pavel Rochnyack. #1932
+ * PowerDNS plugin: The "recursor command" has been fixed so PowerDNS can
+ correctly parse all requested fields. Thanks to Ruben Kerkhof.
+ * Write Graphite and AMQP plugins: A bug that could lead to a missing
+ null-termination has been fixed. Thanks to Markus Linnala.
+ * Write HTTP plugin: A logic error when checking the correctness of the
+ data set has been fixed. Thanks to Pavel Rochnyack. #1996
+ * Write Kafka plugin: The "Key Random" config option has been fixed.
+ Thanks to Florian Forster. #1977
+ * Write Kafka plugin: Support for librdkafka 0.9.0 has been added.
+ Thanks to Florian Forster.
+ * Write Riemann plugin: Build issues on Solaris have been fixed. Thanks
+ to Florian Forster.
+ * ZFS ARC plugin: A duplicate metric has been removed. Thanks to Ruben
+ Kerkhof. #1963
+
2016-10-07, Version 5.6.1
* Build system: Unnecessary linking of the Write Graphite plugin with
libyajl has been removed. Thanks to Marc Fournier.
noinst_LTLIBRARIES += libcmds.la
libcmds_la_SOURCES = utils_cmds.c utils_cmds.h \
- utils_cmd_flush.c utils_cmd_flush.h \
- utils_cmd_getval.c utils_cmd_getval.h \
- utils_cmd_listval.c utils_cmd_listval.h \
- utils_cmd_putval.c utils_cmd_putval.h \
- utils_parse_option.c
-libcmds_la_LIBADD = daemon/libcommon.la daemon/libmetadata.la \
- daemon/libplugin_mock.la -lm
+ utils_cmd_flush.c utils_cmd_flush.h \
+ utils_cmd_getthreshold.c utils_cmd_getthreshold.h \
+ utils_cmd_getval.c utils_cmd_getval.h \
+ utils_cmd_listval.c utils_cmd_listval.h \
+ utils_cmd_putnotif.c utils_cmd_putnotif.h \
+ utils_cmd_putval.c utils_cmd_putval.h \
+ utils_parse_option.c utils_parse_option.h
+libcmds_la_LIBADD = daemon/libcommon.la daemon/libmetadata.la -lm
check_PROGRAMS += test_utils_cmds
TESTS += test_utils_cmds
test_utils_cmds_SOURCES = utils_cmds_test.c testing.h
test_utils_cmds_LDADD = libcmds.la \
- daemon/libplugin_mock.la daemon/libmetadata.la
+ daemon/libplugin_mock.la
noinst_LTLIBRARIES += liblookup.la
liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
if BUILD_PLUGIN_AMQP
pkglib_LTLIBRARIES += amqp.la
-amqp_la_SOURCES = amqp.c \
- utils_cmds.c utils_cmds.h \
- utils_cmd_putval.c utils_cmd_putval.h \
- utils_parse_option.c utils_parse_option.h
+amqp_la_SOURCES = amqp.c
amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
-amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) libformat_graphite.la libformat_json.la
+amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) \
+ libcmds.la libformat_graphite.la libformat_json.la
endif
if BUILD_PLUGIN_APACHE
if BUILD_PLUGIN_EXEC
pkglib_LTLIBRARIES += exec.la
-exec_la_SOURCES = exec.c \
- utils_cmds.c utils_cmds.h \
- utils_cmd_putnotif.c utils_cmd_putnotif.h \
- utils_cmd_putval.c utils_cmd_putval.h \
- utils_parse_option.h utils_parse_option.c
-exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+exec_la_SOURCES = exec.c
+exec_la_LDFLAGS = $(PLUGIN_LDFLAGS) libcmds.la
endif
if BUILD_PLUGIN_ETHSTAT
if BUILD_PLUGIN_UNIXSOCK
pkglib_LTLIBRARIES += unixsock.la
-unixsock_la_SOURCES = unixsock.c \
- utils_cmds.c utils_cmds.h \
- utils_cmd_flush.h utils_cmd_flush.c \
- utils_cmd_getval.h utils_cmd_getval.c \
- utils_cmd_getthreshold.h utils_cmd_getthreshold.c \
- utils_cmd_listval.h utils_cmd_listval.c \
- utils_cmd_putval.h utils_cmd_putval.c \
- utils_cmd_putnotif.h utils_cmd_putnotif.c \
- utils_parse_option.h utils_parse_option.c
-unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+unixsock_la_SOURCES = unixsock.c
+unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS) libcmds.la
endif
if BUILD_PLUGIN_UPTIME
if BUILD_PLUGIN_WRITE_KAFKA
pkglib_LTLIBRARIES += write_kafka.la
write_kafka_la_SOURCES = write_kafka.c \
- utils_cmds.c utils_cmds.h \
- utils_cmd_putval.c utils_cmd_putval.h \
- utils_crc32.c utils_crc32.h
+ utils_crc32.c utils_crc32.h
write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
-write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) libformat_graphite.la libformat_json.la
+write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) \
+ libcmds.la libformat_graphite.la libformat_json.la
endif
if BUILD_PLUGIN_WRITE_LOG
=item B<ReportStats> B<true>|B<false>
The network plugin cannot only receive and send statistics, it can also create
-statistics about itself. Collected data included the number of received and
+statistics about itself. Collectd data included the number of received and
sent octets and packets, the length of the receive queue and the number of
values handled. When set to B<true>, the I<Network plugin> will make these
statistics available. Defaults to B<false>.
have_seed = 1;
}
-double cdrand_d(void) {
+double cdrand_d() {
double r;
pthread_mutex_lock(&lock);
return (r);
}
+uint32_t cdrand_u() {
+ long r;
+
+ pthread_mutex_lock(&lock);
+ cdrand_seed();
+ r = jrand48(seed);
+ pthread_mutex_unlock(&lock);
+
+ return (uint32_t)r;
+}
+
long cdrand_range(long min, long max) {
long range;
long r;
*
* This function is thread- and reentrant-safe.
*/
-double cdrand_d(void);
+double cdrand_d();
+
+/**
+ * cdrand_u returns a random uint32_t value uniformly distributed in the range
+ * [0-2^32).
+ *
+ * This function is thread- and reentrant-safe.
+ */
+uint32_t cdrand_u();
/**
* Returns a random long between min and max, inclusively.
ps_list_reset();
/* Open the kvm interface, get a descriptor */
- kd = kvm_open(NULL, NULL, NULL, 0, errbuf);
+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) {
ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
return (0);
plugin_dispatch_values(&vl);
}
-static void smart_handle_disk_attribute(SkDisk *d,
- const SkSmartAttributeParsedData *a,
- void *userdata) {
- const char *dev = userdata;
+static void handle_attribute(SkDisk *d, const SkSmartAttributeParsedData *a,
+ void *userdata) {
+ char const *name = userdata;
if (!a->current_value_valid || !a->worst_value_valid)
return;
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE(values);
sstrncpy(vl.plugin, "smart", sizeof(vl.plugin));
- sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance));
+ sstrncpy(vl.plugin_instance, name, sizeof(vl.plugin_instance));
sstrncpy(vl.type, "smart_attribute", sizeof(vl.type));
sstrncpy(vl.type_instance, a->name, sizeof(vl.type_instance));
notification_t notif = {NOTIF_WARNING, cdtime(), "", "", "smart", "",
"smart_attribute", "", NULL};
sstrncpy(notif.host, hostname_g, sizeof(notif.host));
- sstrncpy(notif.plugin_instance, dev, sizeof(notif.plugin_instance));
+ sstrncpy(notif.plugin_instance, name, sizeof(notif.plugin_instance));
sstrncpy(notif.type_instance, a->name, sizeof(notif.type_instance));
ssnprintf(notif.message, sizeof(notif.message),
"attribute %s is below allowed threshold (%d < %d)", a->name,
}
}
-static void smart_handle_disk(const char *dev, const char *serial) {
- SkDisk *d = NULL;
- SkBool awake = FALSE;
+static void smart_read_disk(SkDisk *d, char const *name) {
SkBool available = FALSE;
- const char *shortname;
- const SkSmartParsedData *spd;
- uint64_t poweron, powercycles, badsectors, temperature;
-
- if (use_serial && serial) {
- shortname = serial;
- } else {
- shortname = strrchr(dev, '/');
- if (!shortname)
- return;
- shortname++;
- }
- if (ignorelist_match(ignorelist, shortname) != 0) {
- DEBUG("smart plugin: ignoring %s.", dev);
- return;
- }
-
- DEBUG("smart plugin: checking SMART status of %s.", dev);
-
- if (sk_disk_open(dev, &d) < 0) {
- ERROR("smart plugin: unable to open %s.", dev);
- return;
- }
if (sk_disk_identify_is_available(d, &available) < 0 || !available) {
- DEBUG("smart plugin: disk %s cannot be identified.", dev);
- goto end;
+ DEBUG("smart plugin: disk %s cannot be identified.", name);
+ return;
}
if (sk_disk_smart_is_available(d, &available) < 0 || !available) {
- DEBUG("smart plugin: disk %s has no SMART support.", dev);
- goto end;
+ DEBUG("smart plugin: disk %s has no SMART support.", name);
+ return;
}
if (!ignore_sleep_mode) {
+ SkBool awake = FALSE;
if (sk_disk_check_sleep_mode(d, &awake) < 0 || !awake) {
- DEBUG("smart plugin: disk %s is sleeping.", dev);
- goto end;
+ DEBUG("smart plugin: disk %s is sleeping.", name);
+ return;
}
}
if (sk_disk_smart_read_data(d) < 0) {
- ERROR("smart plugin: unable to get SMART data for disk %s.", dev);
- goto end;
+ ERROR("smart plugin: unable to get SMART data for disk %s.", name);
+ return;
}
- if (sk_disk_smart_parse(d, &spd) < 0) {
- ERROR("smart plugin: unable to parse SMART data for disk %s.", dev);
- goto end;
+
+ if (sk_disk_smart_parse(d, &(SkSmartParsedData const *){NULL}) < 0) {
+ ERROR("smart plugin: unable to parse SMART data for disk %s.", name);
+ return;
}
/* Get some specific values */
- if (sk_disk_smart_get_power_on(d, &poweron) < 0) {
- WARNING("smart plugin: unable to get milliseconds since power on for %s.",
- dev);
- } else
- smart_submit(shortname, "smart_poweron", "", poweron / 1000.);
-
- if (sk_disk_smart_get_power_cycle(d, &powercycles) < 0) {
- WARNING("smart plugin: unable to get number of power cycles for %s.", dev);
- } else
- smart_submit(shortname, "smart_powercycles", "", powercycles);
-
- if (sk_disk_smart_get_bad(d, &badsectors) < 0) {
- WARNING("smart plugin: unable to get number of bad sectors for %s.", dev);
- } else
- smart_submit(shortname, "smart_badsectors", "", badsectors);
-
- if (sk_disk_smart_get_temperature(d, &temperature) < 0) {
- WARNING("smart plugin: unable to get temperature for %s.", dev);
- } else
- smart_submit(shortname, "smart_temperature", "",
- temperature / 1000. - 273.15);
+ uint64_t value;
+ if (sk_disk_smart_get_power_on(d, &value) >= 0)
+ smart_submit(name, "smart_poweron", "", ((gauge_t)value) / 1000.);
+ else
+ DEBUG("smart plugin: unable to get milliseconds since power on for %s.",
+ name);
+
+ if (sk_disk_smart_get_power_cycle(d, &value) >= 0)
+ smart_submit(name, "smart_powercycles", "", (gauge_t)value);
+ else
+ DEBUG("smart plugin: unable to get number of power cycles for %s.", name);
+
+ if (sk_disk_smart_get_bad(d, &value) >= 0)
+ smart_submit(name, "smart_badsectors", "", (gauge_t)value);
+ else
+ DEBUG("smart plugin: unable to get number of bad sectors for %s.", name);
+
+ if (sk_disk_smart_get_temperature(d, &value) >= 0)
+ smart_submit(name, "smart_temperature", "",
+ ((gauge_t)value) / 1000. - 273.15);
+ else
+ DEBUG("smart plugin: unable to get temperature for %s.", name);
/* Grab all attributes */
- if (sk_disk_smart_parse_attributes(d, smart_handle_disk_attribute,
- (char *)shortname) < 0) {
- ERROR("smart plugin: unable to handle SMART attributes for %s.", dev);
+ if (sk_disk_smart_parse_attributes(d, handle_attribute, (void *)name) < 0) {
+ ERROR("smart plugin: unable to handle SMART attributes for %s.", name);
+ }
+}
+
+static void smart_handle_disk(const char *dev, const char *serial) {
+ SkDisk *d = NULL;
+ const char *name;
+
+ if (use_serial && serial) {
+ name = serial;
+ } else {
+ name = strrchr(dev, '/');
+ if (!name)
+ return;
+ name++;
+ }
+ if (ignorelist_match(ignorelist, name) != 0) {
+ DEBUG("smart plugin: ignoring %s.", dev);
+ return;
+ }
+
+ DEBUG("smart plugin: checking SMART status of %s.", dev);
+ if (sk_disk_open(dev, &d) < 0) {
+ ERROR("smart plugin: unable to open %s.", dev);
+ return;
}
-end:
+ smart_read_disk(d, name);
sk_disk_free(d);
}
#include "common.h"
#include "plugin.h"
-#if defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__)
+#define HAVE_KVM_GETFILES 1
+#endif
+
+#if defined(__NetBSD__)
#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
#endif
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
#error "No applicable input method."
#endif
#include <netinet/tcpip.h>
/* #endif HAVE_SYSCTLBYNAME */
-/* This is for OpenBSD and NetBSD. */
+#elif HAVE_KVM_GETFILES
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#define _KERNEL /* for DTYPE_SOCKET */
+#include <sys/file.h>
+#undef _KERNEL
+
+#include <netinet/in.h>
+
+#include <kvm.h>
+/* #endif HAVE_KVM_GETFILES */
+
+/* This is for NetBSD. */
#elif HAVE_LIBKVM_NLIST
#include <arpa/inet.h>
#include <net/route.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
-#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>
#define TCP_STATE_MAX 10
/* #endif HAVE_SYSCTLBYNAME */
+#elif HAVE_KVM_GETFILES
+static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT",
+ "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT",
+ "FIN_WAIT1", "CLOSING", "LAST_ACK",
+ "FIN_WAIT2", "TIME_WAIT"};
+
+#define TCP_STATE_LISTEN 1
+#define TCP_STATE_MIN 0
+#define TCP_STATE_MAX 10
+
+static kvm_t *kvmd;
+/* #endif HAVE_KVM_GETFILES */
+
#elif HAVE_LIBKVM_NLIST
static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT",
"SYN_RECV", "ESTABLISHED", "CLOSE_WAIT",
} /* int conn_read */
/* #endif HAVE_SYSCTLBYNAME */
+#elif HAVE_KVM_GETFILES
+
+static int conn_init(void) {
+ char buf[_POSIX2_LINE_MAX];
+
+ kvmd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf);
+ if (kvmd == NULL) {
+ ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf);
+ return (-1);
+ }
+
+ return (0);
+} /* int conn_init */
+
+static int conn_read(void) {
+ struct kinfo_file *kf;
+ int i, fcnt;
+
+ conn_reset_port_entry();
+
+ kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
+ sizeof(*kf), &fcnt);
+ if (kf == NULL) {
+ ERROR("tcpconns plugin: kvm_getfiles failed.");
+ return (-1);
+ }
+
+ for (i = 0; i < fcnt; i++) {
+ if (kf[i].so_protocol != IPPROTO_TCP)
+ continue;
+ if (kf[i].inp_fport == 0)
+ continue;
+ conn_handle_ports(ntohs(kf[i].inp_lport), ntohs(kf[i].inp_fport),
+ kf[i].t_state);
+ }
+
+ conn_submit_all();
+
+ return (0);
+}
+/* int conn_read */
+/* #endif HAVE_KVM_GETFILES */
+
#elif HAVE_LIBKVM_NLIST
static int kread(u_long addr, void *buf, int size) {
int status;
#include "common.h"
#include "plugin.h"
#include "utils_cmd_flush.h"
-#include "utils_parse_option.h"
cmd_status_t cmd_parse_flush(size_t argc, char **argv, cmd_flush_t *ret_flush,
const cmd_options_t *opts,
#ifndef UTILS_CMD_FLUSH_H
#define UTILS_CMD_FLUSH_H 1
-#include <stdio.h>
-
#include "utils_cmds.h"
+#include <stdio.h>
+
cmd_status_t cmd_parse_flush(size_t argc, char **argv, cmd_flush_t *ret_flush,
const cmd_options_t *opts,
cmd_error_handler_t *err);
#include "collectd.h"
#include "common.h"
-#include "plugin.h"
-
-#include "utils_cmd_putval.h"
#include "utils_cmd_putval.h"
-#include "utils_cmds.h"
-#include "utils_parse_option.h"
/*
* private helper functions
#ifndef UTILS_CMD_PUTVAL_H
#define UTILS_CMD_PUTVAL_H 1
-#include <stdio.h>
-
#include "plugin.h"
#include "utils_cmds.h"
+#include <stdio.h>
+
cmd_status_t cmd_parse_putval(size_t argc, char **argv,
cmd_putval_t *ret_putval,
const cmd_options_t *opts,
#include "utils_cmd_putval.h"
#include "utils_format_graphite.h"
#include "utils_format_json.h"
+#include "utils_random.h"
#include <errno.h>
#include <librdkafka/rdkafka.h>
#define KAFKA_RANDOM_KEY_BUFFER \
(char[KAFKA_RANDOM_KEY_SIZE]) { "" }
static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE]) {
- ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08lX", (unsigned long)mrand48());
+ ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08" PRIX32, cdrand_u());
return buffer;
}
#!/bin/sh
-DEFAULT_VERSION="5.6.1.git"
+DEFAULT_VERSION="5.6.2.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"