From: Ruben Kerkhof Date: Sat, 28 Nov 2015 12:33:02 +0000 (+0100) Subject: Merge pull request #1199 from rubenk/remove-gcrypt-exec-prefix-check X-Git-Tag: collectd-5.6.0~569 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=042c592bcddeea04cf81230ba9c97a09c5d3595c;hp=7fe3dd55996faef47d0697a9f043470b18493447;p=collectd.git Merge pull request #1199 from rubenk/remove-gcrypt-exec-prefix-check Remove gcrypt exec prefix check --- diff --git a/.travis.yml b/.travis.yml index 09adb4d9..435669bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,55 @@ -sudo: false +sudo: required +dist: trusty compiler: - gcc - clang -addons: - apt: - packages: - - iptables-dev - - libcap-dev - - libdbi-dev - - libhiredis-dev - - libnfnetlink-dev - - libnotify-dev - - libpcap-dev - - libperl-dev - - libprotobuf-c0-dev - - librrd-dev - - libsnmp-dev - - libudev-dev - - libvarnishapi-dev - - libyajl-dev - - linux-libc-dev - - protobuf-c-compiler language: c +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq --no-install-recommends + libatasmart-dev + libcap-dev + libcurl4-gnutls-dev + libdbi0-dev + libesmtp-dev + libganglia1-dev + libgcrypt11-dev + libglib2.0-dev + libhiredis-dev + libi2c-dev + libldap2-dev + libltdl-dev + liblvm2-dev + libmemcached-dev + libmnl-dev + libmodbus-dev + libmosquitto0-dev + libmysqlclient-dev + libnotify-dev + libopenipmi-dev + liboping-dev + libow-dev + libpcap-dev + libperl-dev + libpq-dev + libprotobuf-c0-dev + librabbitmq-dev + librdkafka-dev + librrd-dev + libsensors4-dev + libsigrok-dev + libsnmp-dev + libstatgrab-dev + libtokyocabinet-dev + libtokyotyrant-dev + libudev-dev + libupsclient-dev + libvarnish-dev + libvirt-dev + libxml2-dev + libyajl-dev + linux-libc-dev + perl + protobuf-c-compiler + python-dev script: sh build.sh && ./configure && make distcheck diff --git a/Makefile.am b/Makefile.am index 35f24cb1..b79ea1ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,12 @@ ACLOCAL_AMFLAGS = -I libltdl/m4 -SUBDIRS = libltdl src bindings . +SUBDIRS = + +if BUILD_INCLUDED_LTDL +SUBDIRS += libltdl +endif + +SUBDIRS += src bindings . AM_CPPFLAGS = $(LTDLINCL) diff --git a/bindings/perl/lib/Collectd/Unixsock.pm b/bindings/perl/lib/Collectd/Unixsock.pm index 5c6a5f9d..d927d13e 100644 --- a/bindings/perl/lib/Collectd/Unixsock.pm +++ b/bindings/perl/lib/Collectd/Unixsock.pm @@ -137,13 +137,13 @@ sub _parse_identifier sub _escape_argument { - local $_ = shift; + my $arg = shift; - return $_ if /^\w+$/; + return $arg if $arg =~ /^\w+$/; - s#\\#\\\\#g; - s#"#\\"#g; - return "\"$_\""; + $arg =~ s#\\#\\\\#g; + $arg =~ s#"#\\"#g; + return "\"$arg\""; } # Send a command on a socket, including any required argument escaping. @@ -262,10 +262,11 @@ sub getthreshold # {{{ $self->_socket_chat($msg, sub { local $_ = shift; my $ret = shift; - /^\s*([^:]+):\s*(.*)/ and do { - $1 =~ s/\s*$//; - $ret->{$1} = $2; - }; + my ( $key, $val ); + ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do { + $key =~ s/\s*$//; + $ret->{$key} = $val; + }; }, $ret ); return $ret; diff --git a/bindings/perl/t/01_methods.t b/bindings/perl/t/01_methods.t index 2f7818b1..4e94f8e8 100644 --- a/bindings/perl/t/01_methods.t +++ b/bindings/perl/t/01_methods.t @@ -16,7 +16,7 @@ sub test_query { my ($nresults, $resultdata) = @$results; my $r = $s->getval(%{Collectd::Unixsock::_parse_identifier($attr)}); is(ref $r, 'HASH', "Got a result for $attr"); - is(scalar keys $r, $nresults, "$nresults result result for $attr"); + is(scalar keys %$r, $nresults, "$nresults result result for $attr"); is_deeply($r, $resultdata, "Data or $attr matches"); } diff --git a/configure.ac b/configure.ac index e3732fae..e9728d58 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,18 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)]) +AC_INIT([collectd], + [m4_esyscmd(./version-gen.sh)], + [https://github.com/collectd/collectd/issues], + [collectd], + [https://collectd.org]) AC_CONFIG_SRCDIR(src/) AC_CONFIG_HEADERS(src/config.h) AC_CONFIG_AUX_DIR([libltdl/config]) +dnl older automake's default of ARFLAGS=cru is noisy on newer binutils; +dnl we don't really need the 'u' even in older toolchains. Then there is +dnl older libtool, which spelled it AR_FLAGS +m4_divert_text([DEFAULTS], [: "${ARFLAGS=cr} ${AR_FLAGS=cr}"]) + m4_ifdef([LT_PACKAGE_VERSION], # libtool >= 2.2 [ @@ -24,6 +33,8 @@ m4_ifdef([LT_PACKAGE_VERSION], ] ) +AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"]) + AM_INIT_AUTOMAKE([tar-pax dist-bzip2 foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_LANG(C) @@ -50,12 +61,23 @@ AC_PROG_YACC PKG_PROG_PKG_CONFIG AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no]) -AC_CHECK_HEADERS([google/protobuf-c/protobuf-c.h], - [have_protobuf_c_h="yes"], - [have_protobuf_c_h="no"]) -if test "x$have_protoc_c" = "xyes" && test "x$have_protobuf_c_h" != "xyes" +if test "x$have_protoc_c" = "xno" +then + have_protoc_c="no (protoc-c compiler not found)" +fi + +if test "x$have_protoc_c" = "xyes" then - have_protoc_c="no (unable to find )" + AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h], + [have_protoc_c="yes"; break], + [have_protoc_c="no ( not found)"]) +fi +if test "x$have_protoc_c" = "xyes" +then + AC_CHECK_LIB([protobuf-c], [protobuf_c_version], + [have_protoc_c="yes"], + [have_protoc_c="no (libprotobuf-c not found)"]) + fi AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes") @@ -632,6 +654,9 @@ AC_CHECK_HEADERS(net/pfvar.h, #if HAVE_NET_IF_H # include #endif +#if HAVE_NETINET_IN_H +# include +#endif ]) # For the multimeter plugin @@ -1244,6 +1269,8 @@ have_getvfsstat="no" AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"]) have_listmntent="no" AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"]) +have_getmntent_r="no" +AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"]) have_getmntent="no" AC_CHECK_FUNCS(getmntent, [have_getmntent="c"]) @@ -1915,30 +1942,33 @@ AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Pat GANGLIA_LDFLAGS="-L$withval/lib" with_libganglia="yes" else - with_libganglia_config="ganglia-config" with_libganglia="$withval" fi; fi; fi ], [ - with_libganglia_config="ganglia-config" with_libganglia="yes" ]) -if test "x$with_libganglia" = "xyes" && test "x$with_libganglia_config" != "x" +if test "x$with_libganglia" = "xyes" then - if test "x$GANGLIA_CPPFLAGS" = "x" + if test "x$with_libganglia_config" != "x" then - GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null` - fi + if test "x$GANGLIA_CPPFLAGS" = "x" + then + GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null` + fi - if test "x$GANGLIA_LDFLAGS" = "x" - then - GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null` - fi + if test "x$GANGLIA_LDFLAGS" = "x" + then + GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null` + fi - if test "x$GANGLIA_LIBS" = "x" - then - GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null` + if test "x$GANGLIA_LIBS" = "x" + then + GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null` + fi + else + GANGLIA_LIBS="-lganglia" fi fi @@ -2721,7 +2751,7 @@ AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to ]) if test "x$with_libmysql" = "xyes" then - with_mysql_cflags=`$with_mysql_config --cflags 2>/dev/null` + with_mysql_cflags=`$with_mysql_config --include 2>/dev/null` mysql_config_status=$? if test $mysql_config_status -ne 0 @@ -2757,15 +2787,17 @@ then then with_libmysql="no ($with_mysql_config failed)" else - AC_CHECK_LIB(mysqlclient, mysql_init, - [with_libmysql="yes"], - [with_libmysql="no (symbol 'mysql_init' not found)"], - [$with_mysql_libs]) - - AC_CHECK_LIB(mysqlclient, mysql_get_server_version, + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_mysql_cflags" + SAVE_LIBS="$LIBS" + LIBS="$with_mysql_libs" + AC_SEARCH_LIBS([mysql_get_server_version], + [], [with_libmysql="yes"], [with_libmysql="no (symbol 'mysql_get_server_version' not found)"], - [$with_mysql_libs]) + []) + CPPFLAGS="$SAVE_CPPFLAGS" + LIBS="$SAVE_LIBS" fi fi if test "x$with_libmysql" = "xyes" @@ -3285,11 +3317,6 @@ then fi if test "x$with_libpcap" = "xyes" then - AC_CHECK_HEADERS(pcap-bpf.h,, - [with_libpcap="no (pcap-bpf.h not found)"]) -fi -if test "x$with_libpcap" = "xyes" -then AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP], [c_cv_libpcap_have_pcap_error_iface_not_up], AC_COMPILE_IFELSE([AC_LANG_PROGRAM( @@ -3742,8 +3769,8 @@ fi # }}} --with-python # --with-librabbitmq {{{ -with_librabbitmq_cppflags="-I/usr/local/include" -with_librabbitmq_ldflags="-L/usr/local/lib" +with_librabbitmq_cppflags="" +with_librabbitmq_ldflags="" AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])], [ if test "x$withval" != "xno" && test "x$withval" != "xyes" @@ -5234,6 +5261,7 @@ collectd features:]) AC_COLLECTD([debug], [enable], [feature], [debugging]) AC_COLLECTD([daemon], [disable], [feature], [daemon mode]) AC_COLLECTD([getifaddrs],[enable], [feature], [getifaddrs under Linux]) +AC_COLLECTD([werror], [disable], [feature], [building with -Werror]) dependency_warning="no" dependency_error="no" @@ -5255,6 +5283,7 @@ plugin_disk="no" plugin_drbd="no" plugin_entropy="no" plugin_ethstat="no" +plugin_fhcount="no" plugin_fscache="no" plugin_interface="no" plugin_ipmi="no" @@ -5298,6 +5327,7 @@ then plugin_disk="yes" plugin_drbd="yes" plugin_entropy="yes" + plugin_fhcount="yes" plugin_fscache="yes" plugin_interface="yes" plugin_ipc="yes" @@ -5353,6 +5383,7 @@ fi if test "x$ac_system" = "xFreeBSD" then + plugin_disk="yes" plugin_zfs_arc="yes" fi @@ -5494,6 +5525,11 @@ then plugin_df="yes" fi +if test "x$c_cv_have_getmntent_r" = "xyes" +then + plugin_df="yes" +fi + # Df plugin: Check if we have either `statfs' or `statvfs' second. if test "x$plugin_df" = "xyes" then @@ -5642,7 +5678,7 @@ AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver]) AC_PLUGIN([exec], [yes], [Execution of external programs]) -AC_PLUGIN([fhcount], [yes], [File handles statistics]) +AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statistics]) AC_PLUGIN([filecount], [yes], [Count files in directories]) AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics]) AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin]) @@ -5900,6 +5936,13 @@ AC_SUBST(LCC_VERSION_STRING) AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h) +AM_CFLAGS="-Wall" +if test "x$enable_werror" != "xno" +then + AM_CFLAGS="$AM_CFLAGS -Werror" +fi +AC_SUBST([AM_CFLAGS]) + AC_CONFIG_FILES([Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile]) AC_OUTPUT @@ -5930,6 +5973,17 @@ fi cat <' -if COMPILER_IS_GCC -AM_CFLAGS = -Wall -Werror -endif - AM_CPPFLAGS = -I$(srcdir)/daemon AM_CPPFLAGS += -DPREFIX='"${prefix}"' AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' @@ -41,6 +37,9 @@ check_PROGRAMS += test_utils_vl_lookup TESTS += test_utils_vl_lookup test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h test_utils_vl_lookup_LDADD = liblookup.la daemon/libcommon.la daemon/libplugin_mock.la +if BUILD_WITH_LIBKSTAT +test_utils_vl_lookup_LDADD += -lkstat +endif noinst_LTLIBRARIES += libmount.la libmount_la_SOURCES = utils_mount.c utils_mount.h @@ -48,7 +47,9 @@ check_PROGRAMS += test_utils_mount TESTS += test_utils_mount test_utils_mount_SOURCES = utils_mount_test.c testing.h test_utils_mount_LDADD = libmount.la daemon/libcommon.la daemon/libplugin_mock.la - +if BUILD_WITH_LIBKSTAT +test_utils_mount_LDADD += -lkstat +endif sbin_PROGRAMS = collectdmon bin_PROGRAMS = collectd-nagios collectdctl collectd-tg @@ -210,8 +211,7 @@ endif if BUILD_PLUGIN_CGROUPS pkglib_LTLIBRARIES += cgroups.la -cgroups_la_SOURCES = cgroups.c \ - utils_ignorelist.c utils_ignorelist.h +cgroups_la_SOURCES = cgroups.c cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS) cgroups_la_LIBADD = libmount.la endif @@ -310,16 +310,14 @@ endif if BUILD_PLUGIN_DF pkglib_LTLIBRARIES += df.la -df_la_SOURCES = df.c \ - utils_ignorelist.c utils_ignorelist.h +df_la_SOURCES = df.c df_la_LDFLAGS = $(PLUGIN_LDFLAGS) df_la_LIBADD = libmount.la endif if BUILD_PLUGIN_DISK pkglib_LTLIBRARIES += disk.la -disk_la_SOURCES = disk.c \ - utils_ignorelist.c utils_ignorelist.h +disk_la_SOURCES = disk.c disk_la_CFLAGS = $(AM_CFLAGS) disk_la_LDFLAGS = $(PLUGIN_LDFLAGS) disk_la_LIBADD = @@ -339,6 +337,9 @@ endif if BUILD_WITH_LIBUDEV disk_la_LIBADD += -ludev endif +if BUILD_FREEBSD +disk_la_LIBADD += -ldevstat -lgeom +endif if BUILD_WITH_PERFSTAT disk_la_LIBADD += -lperfstat endif @@ -419,8 +420,7 @@ endif if BUILD_PLUGIN_INTERFACE pkglib_LTLIBRARIES += interface.la -interface_la_SOURCES = interface.c \ - utils_ignorelist.c utils_ignorelist.h +interface_la_SOURCES = interface.c interface_la_CFLAGS = $(AM_CFLAGS) interface_la_LDFLAGS = $(PLUGIN_LDFLAGS) interface_la_LIBADD = @@ -457,8 +457,7 @@ endif if BUILD_PLUGIN_IPMI pkglib_LTLIBRARIES += ipmi.la -ipmi_la_SOURCES = ipmi.c \ - utils_ignorelist.c utils_ignorelist.h +ipmi_la_SOURCES = ipmi.c ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS) ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS) ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS) @@ -477,8 +476,7 @@ endif if BUILD_PLUGIN_IRQ pkglib_LTLIBRARIES += irq.la -irq_la_SOURCES = irq.c \ - utils_ignorelist.c utils_ignorelist.h +irq_la_SOURCES = irq.c irq_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif @@ -537,8 +535,7 @@ endif if BUILD_PLUGIN_MADWIFI pkglib_LTLIBRARIES += madwifi.la -madwifi_la_SOURCES = madwifi.c madwifi.h \ - utils_ignorelist.c utils_ignorelist.h +madwifi_la_SOURCES = madwifi.c madwifi.h madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif @@ -584,8 +581,7 @@ endif if BUILD_PLUGIN_MD pkglib_LTLIBRARIES += md.la -md_la_SOURCES = md.c \ - utils_ignorelist.c utils_ignorelist.h +md_la_SOURCES = md.c md_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif @@ -630,8 +626,7 @@ endif if BUILD_PLUGIN_MIC pkglib_LTLIBRARIES += mic.la -mic_la_SOURCES = mic.c \ - utils_ignorelist.c utils_ignorelist.h +mic_la_SOURCES = mic.c mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH) mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS) mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD) @@ -673,8 +668,7 @@ endif if BUILD_PLUGIN_NETAPP pkglib_LTLIBRARIES += netapp.la -netapp_la_SOURCES = netapp.c \ - utils_ignorelist.c utils_ignorelist.h +netapp_la_SOURCES = netapp.c netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS) netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS) netapp_la_LIBADD = $(LIBNETAPP_LIBS) @@ -780,8 +774,7 @@ endif if BUILD_PLUGIN_ONEWIRE pkglib_LTLIBRARIES += onewire.la -onewire_la_SOURCES = onewire.c \ - utils_ignorelist.c utils_ignorelist.h +onewire_la_SOURCES = onewire.c onewire_la_CFLAGS = $(AM_CFLAGS) onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS) @@ -894,8 +887,7 @@ endif if BUILD_PLUGIN_PROTOCOLS pkglib_LTLIBRARIES += protocols.la -protocols_la_SOURCES = protocols.c \ - utils_ignorelist.c utils_ignorelist.h +protocols_la_SOURCES = protocols.c protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif @@ -933,8 +925,7 @@ endif if BUILD_PLUGIN_SENSORS pkglib_LTLIBRARIES += sensors.la -sensors_la_SOURCES = sensors.c \ - utils_ignorelist.c utils_ignorelist.h +sensors_la_SOURCES = sensors.c sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS) sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS) sensors_la_LIBADD = -lsensors @@ -957,8 +948,7 @@ endif if BUILD_PLUGIN_SMART if BUILD_WITH_LIBUDEV pkglib_LTLIBRARIES += smart.la -smart_la_SOURCES = smart.c \ - utils_ignorelist.c utils_ignorelist.h +smart_la_SOURCES = smart.c smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS) smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS) smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev @@ -1097,8 +1087,7 @@ endif if BUILD_PLUGIN_THERMAL pkglib_LTLIBRARIES += thermal.la -thermal_la_SOURCES = thermal.c \ - utils_ignorelist.c utils_ignorelist.h +thermal_la_SOURCES = thermal.c thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif @@ -1183,8 +1172,7 @@ endif if BUILD_PLUGIN_VIRT pkglib_LTLIBRARIES += virt.la -virt_la_SOURCES = virt.c \ - utils_ignorelist.c utils_ignorelist.h +virt_la_SOURCES = virt.c virt_la_CFLAGS = $(AM_CFLAGS) \ $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) @@ -1378,25 +1366,30 @@ EXTRA_DIST += collectd.conf.pod \ echo "$@ has some POD errors!"; false; \ fi +AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@) +am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@) +am__v_PROTOC_C_0 = @echo " PROTOC-C " $@; +am__v_PROTOC_C_1 = + # Protocol buffer for the "pinba" plugin. EXTRA_DIST += pinba.proto -if HAVE_PROTOC_C +if BUILD_PLUGIN_PINBA CLEANFILES += pinba.pb-c.c pinba.pb-c.h BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h pinba.pb-c.c pinba.pb-c.h: pinba.proto - protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto + $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto endif # Protocol buffer for the "write_riemann" plugin. EXTRA_DIST += riemann.proto -if HAVE_PROTOC_C +if BUILD_PLUGIN_WRITE_RIEMANN CLEANFILES += riemann.pb-c.c riemann.pb-c.h BUILT_SOURCES += riemann.pb-c.c riemann.pb-c.h riemann.pb-c.c riemann.pb-c.h: riemann.proto - protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto + $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto endif install-exec-hook: diff --git a/src/apache.c b/src/apache.c index e384d800..b306032b 100644 --- a/src/apache.c +++ b/src/apache.c @@ -383,8 +383,7 @@ static int init_host (apache_t *st) /* {{{ */ if (st->timeout >= 0) curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) st->timeout); else - curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); @@ -520,12 +519,9 @@ static void submit_scoreboard (char *buf, apache_t *st) static int apache_read_host (user_data_t *user_data) /* {{{ */ { - int i; - char *ptr; char *saveptr; - char *lines[16]; - int lines_num = 0; + char *line; char *fields[4]; int fields_num; @@ -565,29 +561,17 @@ static int apache_read_host (user_data_t *user_data) /* {{{ */ ptr = st->apache_buffer; saveptr = NULL; - while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL) + while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) { ptr = NULL; - lines_num++; - - if (lines_num >= 16) - break; - } - - for (i = 0; i < lines_num; i++) - { - fields_num = strsplit (lines[i], fields, 4); + fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields)); if (fields_num == 3) { - if ((strcmp (fields[0], "Total") == 0) - && (strcmp (fields[1], "Accesses:") == 0)) - submit_derive ("apache_requests", "", - atoll (fields[2]), st); - else if ((strcmp (fields[0], "Total") == 0) - && (strcmp (fields[1], "kBytes:") == 0)) - submit_derive ("apache_bytes", "", - 1024LL * atoll (fields[2]), st); + if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0)) + submit_derive ("apache_requests", "", atoll (fields[2]), st); + else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0)) + submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st); } else if (fields_num == 2) { diff --git a/src/apcups.c b/src/apcups.c index dc533f1e..29d58c3a 100644 --- a/src/apcups.c +++ b/src/apcups.c @@ -32,9 +32,6 @@ #if HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NETDB_H # include #endif @@ -128,7 +125,7 @@ static int net_open (char const *node, char const *service) if (status != 0) { char errbuf[1024]; - INFO ("getaddrinfo failed: %s", + INFO ("apcups plugin: getaddrinfo failed: %s", (status == EAI_SYSTEM) ? sstrerror (errno, errbuf, sizeof (errbuf)) : gai_strerror (status)); @@ -147,7 +144,7 @@ static int net_open (char const *node, char const *service) if (sd < 0) { - DEBUG ("Unable to open a socket"); + DEBUG ("apcups plugin: Unable to open a socket"); freeaddrinfo (ai_return); return (-1); } @@ -159,13 +156,13 @@ static int net_open (char const *node, char const *service) if (status != 0) /* `connect(2)' failed */ { char errbuf[1024]; - INFO ("connect failed: %s", + INFO ("apcups plugin: connect failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); close (sd); return (-1); } - DEBUG ("Done opening a socket %i", sd); + DEBUG ("apcups plugin: Done opening a socket %i", sd); return (sd); } /* int net_open */ @@ -458,7 +455,7 @@ static int apcups_read (void) */ if (status != 0) { - DEBUG ("apc_query_server (%s, %s) = %i", + DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i", (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node, (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service, status); diff --git a/src/ascent.c b/src/ascent.c index 11175af5..2ba3c772 100644 --- a/src/ascent.c +++ b/src/ascent.c @@ -594,8 +594,7 @@ static int ascent_init (void) /* {{{ */ if (timeout != NULL) curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, atol(timeout)); else - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); diff --git a/src/bind.c b/src/bind.c index 32b0f16e..06b4ace0 100644 --- a/src/bind.c +++ b/src/bind.c @@ -1759,7 +1759,7 @@ static int bind_init (void) /* {{{ */ curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); #ifdef HAVE_CURLOPT_TIMEOUT_MS curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (timeout >= 0) ? - (long) timeout : CDTIME_T_TO_MS(plugin_get_interval())); + (long) timeout : (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif diff --git a/src/ceph.c b/src/ceph.c index d928a7ba..419ca6e5 100644 --- a/src/ceph.c +++ b/src/ceph.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/src/collectd-exec.pod b/src/collectd-exec.pod index 10f9f618..0e4cd53a 100644 --- a/src/collectd-exec.pod +++ b/src/collectd-exec.pod @@ -17,7 +17,7 @@ collectd-exec - Documentation of collectd's C =head1 DESCRIPTION -The C forks of an executable either to receive values or to +The C forks off an executable either to receive values or to dispatch notifications to the outside world. The syntax of the configuration is explained in L but summarized in the above synopsis. @@ -42,7 +42,7 @@ time and continuously write values to C. See L below for a description of the output format expected from these programs. -B If the executable only writes one value and then exits I will be +B If the executable only writes one value and then exits it will be executed every I seconds. If I is short (the default is 10 seconds) this may result in serious system load. diff --git a/src/collectd-tg.c b/src/collectd-tg.c index 80473e0e..9bd65bca 100644 --- a/src/collectd-tg.c +++ b/src/collectd-tg.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "utils_heap.h" @@ -100,6 +101,7 @@ static void signal_handler (int signal) /* {{{ */ loop = 0; } /* }}} void signal_handler */ +#if HAVE_CLOCK_GETTIME static double dtime (void) /* {{{ */ { struct timespec ts = { 0 }; @@ -109,6 +111,18 @@ static double dtime (void) /* {{{ */ return ((double) ts.tv_sec) + (((double) ts.tv_nsec) / 1e9); } /* }}} double dtime */ +#else +/* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */ +static double dtime (void) /* {{{ */ +{ + struct timeval tv = { 0 }; + + if (gettimeofday (&tv, /* timezone = */ NULL) != 0) + perror ("gettimeofday"); + + return ((double) tv.tv_sec) + (((double) tv.tv_usec) / 1e6); +} /* }}} double dtime */ +#endif static int compare_time (const void *v0, const void *v1) /* {{{ */ { diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 1f4ccf81..30d536a1 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -291,7 +291,7 @@ # # ValuesPercentage false -# ReportDegraded +# ReportDegraded false # # @@ -683,6 +683,11 @@ # Prefix "collectd" # StoreRates true # Retain false +# CACert "/etc/ssl/ca.crt" +# CertificateFile "/etc/ssl/client.crt" +# CertificateKeyFile "/etc/ssl/client.pem" +# TLSProtocol "tlsv1.2" +# CipherSuite "ciphers" # # # Host "localhost" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index bd39295e..78a130cf 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -1827,6 +1827,7 @@ than those of other plugins. It usually looks something like this: Driver "mysql" + Interval 120 DriverOption "host" "localhost" DriverOption "username" "collectd" DriverOption "password" "aZo6daiw" @@ -2006,6 +2007,11 @@ the daemon. Other than that, that name is not used. =over 4 +=item B I + +Sets the interval (in seconds) in which the values will be collected from this +database. By default the global B setting will be used. + =item B I Specifies the driver to use to connect to the database. In many cases those @@ -2288,7 +2294,7 @@ expected from them. This is documented in great detail in L. =head2 Plugin C The C plugin provides statistics about used, unused and total number of -file handles. +file handles on Linux. The I provides the following configuration options: @@ -3341,6 +3347,38 @@ Configures the topic(s) to subscribe to. You can use the single level C<+> and multi level C<#> wildcards. Defaults to B, i.e. all topics beneath the B branch. +=item B I + +Path to the PEM-encoded CA certificate file. Setting this option enables TLS +communication with the MQTT broker, and as such, B should be the TLS-enabled +port of the MQTT broker. +A valid TLS configuration requires B, B and B. + +=item B I + +Path to the PEM-encoded certificate file to use as client certificate when +connecting to the MQTT broker. +A valid TLS configuration requires B, B and B. + +=item B I + +Path to the unencrypted PEM-encoded key file corresponding to B. +A valid TLS configuration requires B, B and B. + +=item B I + +If configured, this specifies the string protocol version (e.g. C, +C) to use for the TLS connection to the broker. If not set a default +version is used which depends on the version of OpenSSL the Mosquitto library +was linked against. + +=item B I + +A string describing the ciphers available for use. See L and the +C utility for more information. If unset, the default ciphers +will be used. + + =back =head2 Plugin C @@ -7133,14 +7171,18 @@ setting B. B
means use the interface's mac address. This is useful since the interface path might change between reboots of a guest or across migrations. -=item B B +=item B B When the virt plugin logs data, it sets the plugin_instance of the collected -data according to this setting. The default is to use the guest name as provided -by the hypervisor, which is equal to setting B. +data according to this setting. The default is to not set the plugin_instance. +B means use the guest's name as provided by the hypervisor. B means use the guest's UUID. +You can also specify combinations of the B and B fields. +For example B means to concatenate the guest name and UUID +(with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). + =back =head2 Plugin C @@ -7482,6 +7524,10 @@ complete. When this limit is reached, the POST operation will be aborted, and all the data in the current send buffer will probably be lost. Defaults to 0, which means the connection never times out. +=item B B|B + +Enables printing of HTTP error code to log. Turned off by default. + The C plugin regularly submits the collected values to the HTTP server. How frequently this happens depends on how much data you are collecting and the size of B. The optimal value to set B to is @@ -7610,6 +7656,8 @@ Synopsis: Timeout 1000 Prefix "collectd/" Database 1 + MaxSetSize -1 + StoreRates true @@ -7618,7 +7666,7 @@ the timestamp as the score. Retrieving a date range can then be done using the C I command. Additionally, all the identifiers of these I are kept in a I called C (or C<${prefix}/values> if the B option was specified) and can be retrieved -using the C I command. You can specify the database to use +using the C I command. You can specify the database to use with the B parameter (default is C<0>). See L and L for details. @@ -7663,7 +7711,18 @@ is recommended but not required to include a trailing slash in I. =item B I -This index selects the redis database to use for writing operations. Defaults to C<0>. +This index selects the redis database to use for writing operations. Defaults +to C<0>. + +=item B I + +The B option limits the number of items that the I can +hold. Negative values for I sets no limit, which is the default behavior. + +=item B B|B + +If set to B (the default), convert counter values to rates. If set to +B counter values are stored as is, i.e. as an increasing integer number. =back @@ -7744,7 +7803,7 @@ C. =item B B|B -If set the B, append the name of the I (DS) to the +If set to B, append the name of the I (DS) to the "service", i.e. the field that, together with the "host" field, uniquely identifies a metric in I. If set to B (the default), this is only done when there is more than one DS. diff --git a/src/curl.c b/src/curl.c index ac4cc512..16ae3aba 100644 --- a/src/curl.c +++ b/src/curl.c @@ -418,8 +418,7 @@ static int cc_page_init_curl (web_page_t *wp) /* {{{ */ if (wp->timeout >= 0) curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) wp->timeout); else - curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); diff --git a/src/curl_json.c b/src/curl_json.c index 5aceae4e..510d9b62 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -28,7 +28,6 @@ #include "utils_avltree.h" #include "utils_complain.h" -#include #include #include @@ -655,11 +654,9 @@ static int cj_init_curl (cj_t *db) /* {{{ */ if (db->timeout >= 0) curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); else if (db->interval > 0) - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(db->timeout)); + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(db->timeout)); else - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); diff --git a/src/curl_xml.c b/src/curl_xml.c index 8a466bae..5a1f2bab 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -897,8 +897,7 @@ static int cx_init_curl (cx_t *db) /* {{{ */ if (db->timeout >= 0) curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); else - curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 1634713b..3d50029b 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -1,7 +1,3 @@ -if COMPILER_IS_GCC -AM_CFLAGS = -Wall -Werror -endif - AM_CPPFLAGS = -I$(top_srcdir)/src AM_CPPFLAGS += -DPREFIX='"${prefix}"' AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' @@ -62,6 +58,7 @@ collectd_SOURCES = collectd.c collectd.h \ plugin.c plugin.h \ utils_cache.c utils_cache.h \ utils_complain.c utils_complain.h \ + utils_ignorelist.c utils_ignorelist.h \ utils_llist.c utils_llist.h \ utils_random.c utils_random.h \ utils_tail_match.c utils_tail_match.h \ @@ -93,8 +90,8 @@ else collectd_LDADD += -loconfig endif -check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_subst -TESTS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_subst +check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst +TESTS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst test_common_SOURCES = common_test.c ../testing.h test_common_LDADD = libcommon.la libplugin_mock.la @@ -108,6 +105,8 @@ test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS) test_utils_heap_SOURCES = utils_heap_test.c ../testing.h test_utils_heap_LDADD = libheap.la $(COMMON_LIBS) +test_utils_time_SOURCES = utils_time_test.c ../testing.h + test_utils_subst_SOURCES = utils_subst_test.c ../testing.h \ utils_subst.c utils_subst.h test_utils_subst_LDADD = libcommon.la libplugin_mock.la diff --git a/src/daemon/collectd.c b/src/daemon/collectd.c index a40e6046..fc529331 100644 --- a/src/daemon/collectd.c +++ b/src/daemon/collectd.c @@ -32,7 +32,6 @@ #include "configfile.h" #include -#include #include #include @@ -460,7 +459,11 @@ int notify_systemd (void) unsetenv ("NOTIFY_SOCKET"); +#if defined(SOCK_CLOEXEC) + fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0); +#else fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0); +#endif if (fd < 0) { char errbuf[1024]; ERROR ("creating UNIX socket failed: %s", @@ -478,7 +481,6 @@ int notify_systemd (void) } else { -#if KERNEL_LINUX /* Linux abstract namespace socket: specify address as "\0foo", i.e. * start with a null byte. Since null bytes have no special meaning in * that case, we have to set su_size correctly to cover only the bytes @@ -488,11 +490,6 @@ int notify_systemd (void) su_size = sizeof (sa_family_t) + strlen (notifysocket); if (su_size > sizeof (su)) su_size = sizeof (su); -#else - ERROR ("Systemd socket uses Linux abstract namespace notation (\"%s\"), " - "but I don't appear to be running on Linux.", notifysocket); - return 0; -#endif } if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0) @@ -504,6 +501,7 @@ int notify_systemd (void) return 0; } + unsetenv ("NOTIFY_SOCKET"); close(fd); return 1; } diff --git a/src/daemon/collectd.h b/src/daemon/collectd.h index 80b753c8..66b48568 100644 --- a/src/daemon/collectd.h +++ b/src/daemon/collectd.h @@ -95,6 +95,9 @@ # include # endif #endif +#if HAVE_SYS_SOCKET_H +# include +#endif #if HAVE_ASSERT_H # include diff --git a/src/daemon/common.c b/src/daemon/common.c index abe9a6e8..dfaa61aa 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -46,9 +46,10 @@ /* for getaddrinfo */ #include -#include #include +#include + #if HAVE_NETINET_IN_H # include #endif @@ -270,9 +271,23 @@ ssize_t swrite (int fd, const void *buf, size_t count) const char *ptr; size_t nleft; ssize_t status; + struct pollfd pfd; ptr = (const char *) buf; nleft = count; + + /* checking for closed peer connection */ + pfd.fd = fd; + pfd.events = POLLIN | POLLHUP; + pfd.revents = 0; + 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; + } + } while (nleft > 0) { diff --git a/src/daemon/common_test.c b/src/daemon/common_test.c index 0ee4e7e0..399f8b53 100644 --- a/src/daemon/common_test.c +++ b/src/daemon/common_test.c @@ -27,6 +27,10 @@ #include "testing.h" #include "common.h" +#if HAVE_LIBKSTAT +kstat_ctl_t *kc; +#endif /* HAVE_LIBKSTAT */ + DEF_TEST(sstrncpy) { char buffer[16] = ""; @@ -38,18 +42,18 @@ DEF_TEST(sstrncpy) ret = sstrncpy (ptr, "foobar", 8); OK(ret == ptr); - STREQ ("foobar", ptr); + EXPECT_EQ_STR ("foobar", ptr); OK(buffer[3] == buffer[12]); ret = sstrncpy (ptr, "abc", 8); OK(ret == ptr); - STREQ ("abc", ptr); + EXPECT_EQ_STR ("abc", ptr); OK(buffer[3] == buffer[12]); ret = sstrncpy (ptr, "collectd", 8); OK(ret == ptr); OK(ptr[7] == 0); - STREQ ("collect", ptr); + EXPECT_EQ_STR ("collect", ptr); OK(buffer[3] == buffer[12]); return (0); @@ -66,12 +70,12 @@ DEF_TEST(ssnprintf) status = ssnprintf (ptr, 8, "%i", 1337); OK(status == 4); - STREQ ("1337", ptr); + EXPECT_EQ_STR ("1337", ptr); status = ssnprintf (ptr, 8, "%s", "collectd"); OK(status == 8); OK(ptr[7] == 0); - STREQ ("collect", ptr); + EXPECT_EQ_STR ("collect", ptr); OK(buffer[3] == buffer[12]); return (0); @@ -83,7 +87,7 @@ DEF_TEST(sstrdup) ptr = sstrdup ("collectd"); OK(ptr != NULL); - STREQ ("collectd", ptr); + EXPECT_EQ_STR ("collectd", ptr); sfree(ptr); OK(ptr == NULL); @@ -103,40 +107,40 @@ DEF_TEST(strsplit) strncpy (buffer, "foo bar", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); + EXPECT_EQ_STR ("foo", fields[0]); + EXPECT_EQ_STR ("bar", fields[1]); strncpy (buffer, "foo \t bar", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); + EXPECT_EQ_STR ("foo", fields[0]); + EXPECT_EQ_STR ("bar", fields[1]); strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 5); - STREQ ("one", fields[0]); - STREQ ("two", fields[1]); - STREQ ("three", fields[2]); - STREQ ("four", fields[3]); - STREQ ("five", fields[4]); + EXPECT_EQ_STR ("one", fields[0]); + EXPECT_EQ_STR ("two", fields[1]); + EXPECT_EQ_STR ("three", fields[2]); + EXPECT_EQ_STR ("four", fields[3]); + EXPECT_EQ_STR ("five", fields[4]); strncpy (buffer, "\twith trailing\n", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 2); - STREQ ("with", fields[0]); - STREQ ("trailing", fields[1]); + EXPECT_EQ_STR ("with", fields[0]); + EXPECT_EQ_STR ("trailing", fields[1]); strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 8); - STREQ ("7", fields[6]); - STREQ ("8", fields[7]); + EXPECT_EQ_STR ("7", fields[6]); + EXPECT_EQ_STR ("8", fields[7]); strncpy (buffer, "single", sizeof (buffer)); status = strsplit (buffer, fields, 8); OK(status == 1); - STREQ ("single", fields[0]); + EXPECT_EQ_STR ("single", fields[0]); strncpy (buffer, "", sizeof (buffer)); status = strsplit (buffer, fields, 8); @@ -158,26 +162,26 @@ DEF_TEST(strjoin) status = strjoin (buffer, sizeof (buffer), fields, 2, "!"); OK(status == 7); - STREQ ("foo!bar", buffer); + EXPECT_EQ_STR ("foo!bar", buffer); status = strjoin (buffer, sizeof (buffer), fields, 1, "!"); OK(status == 3); - STREQ ("foo", buffer); + EXPECT_EQ_STR ("foo", buffer); status = strjoin (buffer, sizeof (buffer), fields, 0, "!"); OK(status < 0); status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht"); OK(status == 10); - STREQ ("foorchtbar", buffer); + EXPECT_EQ_STR ("foorchtbar", buffer); status = strjoin (buffer, sizeof (buffer), fields, 4, ""); OK(status == 12); - STREQ ("foobarbazqux", buffer); + EXPECT_EQ_STR ("foobarbazqux", buffer); status = strjoin (buffer, sizeof (buffer), fields, 4, "!"); OK(status == 15); - STREQ ("foo!bar!baz!qux", buffer); + EXPECT_EQ_STR ("foo!bar!baz!qux", buffer); fields[0] = "0123"; fields[1] = "4567"; @@ -207,7 +211,7 @@ DEF_TEST(escape_slashes) strncpy (buffer, cases[i].str, sizeof (buffer)); OK(escape_slashes (buffer, sizeof (buffer)) == 0); - STREQ(cases[i].want, buffer); + EXPECT_EQ_STR(cases[i].want, buffer); } return 0; @@ -234,7 +238,7 @@ DEF_TEST(escape_string) strncpy (buffer, cases[i].str, sizeof (buffer)); OK(escape_string (buffer, sizeof (buffer)) == 0); - STREQ(cases[i].want, buffer); + EXPECT_EQ_STR(cases[i].want, buffer); } return 0; @@ -248,23 +252,23 @@ DEF_TEST(strunescape) strncpy (buffer, "foo\\tbar", sizeof (buffer)); status = strunescape (buffer, sizeof (buffer)); OK(status == 0); - STREQ ("foo\tbar", buffer); + EXPECT_EQ_STR ("foo\tbar", buffer); strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); status = strunescape (buffer, sizeof (buffer)); OK(status == 0); - STREQ ("\tfoo\r\n", buffer); + EXPECT_EQ_STR ("\tfoo\r\n", buffer); strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); status = strunescape (buffer, sizeof (buffer)); OK(status == 0); - STREQ ("With \"quotes\"", buffer); + EXPECT_EQ_STR ("With \"quotes\"", buffer); /* Backslash before null byte */ strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); status = strunescape (buffer, sizeof (buffer)); OK(status != 0); - STREQ ("\tbackslash end", buffer); + EXPECT_EQ_STR ("\tbackslash end", buffer); return (0); /* Backslash at buffer end */ @@ -328,11 +332,11 @@ DEF_TEST(parse_values) }; int status = parse_values (cases[i].buffer, &vl, &ds); - EXPECT_INTEQ (cases[i].status, status); + EXPECT_EQ_INT (cases[i].status, status); if (status != 0) continue; - DBLEQ (cases[i].value, vl.values[0].gauge); + EXPECT_EQ_DOUBLE (cases[i].value, vl.values[0].gauge); } return (0); @@ -370,7 +374,7 @@ DEF_TEST(value_to_rate) } OK(value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state) == 0); - DBLEQ(cases[i].want, got); + EXPECT_EQ_DOUBLE(cases[i].want, got); } return 0; diff --git a/src/daemon/meta_data.c b/src/daemon/meta_data.c index 6ee8446b..4e46ed53 100644 --- a/src/daemon/meta_data.c +++ b/src/daemon/meta_data.c @@ -255,7 +255,6 @@ void meta_data_destroy (meta_data_t *md) /* {{{ */ if (md == NULL) return; - pthread_mutex_destroy(&md->lock); md_entry_free (md->head); pthread_mutex_destroy (&md->lock); free (md); diff --git a/src/daemon/meta_data_test.c b/src/daemon/meta_data_test.c index 6d61107d..b4c0e276 100644 --- a/src/daemon/meta_data_test.c +++ b/src/daemon/meta_data_test.c @@ -71,27 +71,27 @@ DEF_TEST(base) /* retrieve and check all values */ CHECK_ZERO (meta_data_get_string (m, "string", &s)); - STREQ ("foobar", s); + EXPECT_EQ_STR ("foobar", s); sfree (s); CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si)); - EXPECT_INTEQ (-1, (int) si); + EXPECT_EQ_INT (-1, (int) si); CHECK_ZERO (meta_data_get_unsigned_int (m, "unsigned_int", &ui)); - EXPECT_INTEQ (1, (int) ui); + EXPECT_EQ_INT (1, (int) ui); CHECK_ZERO (meta_data_get_double (m, "double", &d)); - DBLEQ (47.11, d); + EXPECT_EQ_DOUBLE (47.11, d); CHECK_ZERO (meta_data_get_boolean (m, "boolean", &b)); OK1 (b, "b evaluates to true"); /* retrieving the wrong type always fails */ - EXPECT_INTEQ (-2, meta_data_get_boolean (m, "string", &b)); - EXPECT_INTEQ (-2, meta_data_get_string (m, "signed_int", &s)); - EXPECT_INTEQ (-2, meta_data_get_string (m, "unsigned_int", &s)); - EXPECT_INTEQ (-2, meta_data_get_string (m, "double", &s)); - EXPECT_INTEQ (-2, meta_data_get_string (m, "boolean", &s)); + EXPECT_EQ_INT (-2, meta_data_get_boolean (m, "string", &b)); + EXPECT_EQ_INT (-2, meta_data_get_string (m, "signed_int", &s)); + EXPECT_EQ_INT (-2, meta_data_get_string (m, "unsigned_int", &s)); + EXPECT_EQ_INT (-2, meta_data_get_string (m, "double", &s)); + EXPECT_EQ_INT (-2, meta_data_get_string (m, "boolean", &s)); /* replace existing keys */ CHECK_ZERO (meta_data_add_signed_int (m, "string", 666)); @@ -99,11 +99,11 @@ DEF_TEST(base) CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", 666)); CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si)); - EXPECT_INTEQ (666, (int) si); + EXPECT_EQ_INT (666, (int) si); /* deleting keys */ CHECK_ZERO (meta_data_delete (m, "signed_int")); - EXPECT_INTEQ (-2, meta_data_delete (m, "doesnt exist")); + EXPECT_EQ_INT (-2, meta_data_delete (m, "doesnt exist")); meta_data_destroy (m); return 0; diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index be3f03fc..831e3fb0 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -1089,6 +1089,7 @@ int plugin_load (char const *plugin_name, uint32_t flags) /* success */ plugin_mark_loaded (plugin_name); ret = 0; + INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name); break; } else @@ -1724,8 +1725,6 @@ void plugin_init_all (void) write_threads_num = 5; } - start_write_threads ((size_t) write_threads_num); - if ((list_init == NULL) && (read_heap == NULL)) return; @@ -1761,6 +1760,8 @@ void plugin_init_all (void) le = le->next; } + start_write_threads ((size_t) write_threads_num); + max_read_interval = global_option_get_time ("MaxReadInterval", DEFAULT_MAX_READ_INTERVAL); diff --git a/src/daemon/utils_avltree.c b/src/daemon/utils_avltree.c index e251975b..58b8b847 100644 --- a/src/daemon/utils_avltree.c +++ b/src/daemon/utils_avltree.c @@ -652,6 +652,7 @@ int c_avl_pick (c_avl_tree_t *t, void **key, void **value) *value = n->value; free_node (n); + --t->size; rebalance (t, p); return (0); diff --git a/src/daemon/utils_avltree_test.c b/src/daemon/utils_avltree_test.c index 2a8244c9..6dbafe18 100644 --- a/src/daemon/utils_avltree_test.c +++ b/src/daemon/utils_avltree_test.c @@ -27,6 +27,7 @@ #include "testing.h" #include "collectd.h" #include "utils_avltree.h" +#include "common.h" /* STATIC_ARRAY_SIZE */ static int compare_total_count = 0; #define RESET_COUNTS() do { compare_total_count = 0; } while (0) @@ -42,30 +43,99 @@ static int compare_callback (void const *v0, void const *v1) DEF_TEST(success) { + struct { + char *key; + char *value; + } cases[] = { + {"Eeph7chu", "vai1reiV"}, + {"igh3Paiz", "teegh1Ee"}, + {"caip6Uu8", "ooteQu8n"}, + {"Aech6vah", "AijeeT0l"}, + {"Xah0et2L", "gah8Taep"}, + {"BocaeB8n", "oGaig8io"}, + {"thai8AhM", "ohjeFo3f"}, + {"ohth6ieC", "hoo8ieWo"}, + {"aej7Woow", "phahuC2s"}, + {"Hai8ier2", "Yie6eimi"}, + {"phuXi3Li", "JaiF7ieb"}, + {"Shaig5ef", "aihi5Zai"}, + {"voh6Aith", "Oozaeto0"}, + {"zaiP5kie", "seep5veM"}, + {"pae7ba7D", "chie8Ojo"}, + {"Gou2ril3", "ouVoo0ha"}, + {"lo3Thee3", "ahDu4Zuj"}, + {"Rah8kohv", "ieShoc7E"}, + {"ieN5engi", "Aevou1ah"}, + {"ooTe4OhP", "aingai5Y"}, + }; + c_avl_tree_t *t; - char key_orig[] = "foo"; - char value_orig[] = "bar"; - char *key_ret = NULL; - char *value_ret = NULL; + size_t i; RESET_COUNTS (); - t = c_avl_create (compare_callback); - OK (t != NULL); + CHECK_NOT_NULL (t = c_avl_create (compare_callback)); + + /* insert */ + for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) + { + char *key; + char *value; - OK (c_avl_insert (t, key_orig, value_orig) == 0); - OK (c_avl_size (t) == 1); + CHECK_NOT_NULL (key = strdup (cases[i].key)); + CHECK_NOT_NULL (value = strdup (cases[i].value)); + + CHECK_ZERO (c_avl_insert (t, key, value)); + EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t)); + } /* Key already exists. */ - OK (c_avl_insert (t, "foo", "qux") > 0); + for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) + EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value)); + + /* get */ + for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) + { + char *value_ret = NULL; + + CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret)); + EXPECT_EQ_STR (cases[i].value, value_ret); + } + + /* remove half */ + for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++) + { + char *key = NULL; + char *value = NULL; + + int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1)); + + CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value)); + + EXPECT_EQ_STR (cases[i].key, key); + EXPECT_EQ_STR (cases[i].value, value); + + free (key); + free (value); + + EXPECT_EQ_INT (expected_size, c_avl_size (t)); + } + + /* pick the other half */ + for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++) + { + char *key = NULL; + char *value = NULL; + + int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1)); + + EXPECT_EQ_INT (expected_size + 1, c_avl_size (t)); + EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value)); - OK (c_avl_get (t, "foo", (void *) &value_ret) == 0); - OK (value_ret == &value_orig[0]); + free (key); + free (value); - key_ret = value_ret = NULL; - OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0); - OK (key_ret == &key_orig[0]); - OK (value_ret == &value_orig[0]); - OK (c_avl_size (t) == 0); + EXPECT_EQ_INT (expected_size, c_avl_size (t)); + } c_avl_destroy (t); diff --git a/src/daemon/utils_ignorelist.c b/src/daemon/utils_ignorelist.c new file mode 100644 index 00000000..a8ca7dbb --- /dev/null +++ b/src/daemon/utils_ignorelist.c @@ -0,0 +1,338 @@ +/** + * collectd - src/utils_ignorelist.c + * Copyright (C) 2006 Lubos Stanek + * Copyright (C) 2008 Florian Forster + * + * This program is free software; you can redistribute it and/ + * or modify it under the terms of the GNU General Public Li- + * cence as published by the Free Software Foundation; either + * version 2 of the Licence, or any later version. + * + * This program is distributed in the hope that it will be use- + * ful, but WITHOUT ANY WARRANTY; without even the implied war- + * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public Licence for more details. + * + * You should have received a copy of the GNU General Public + * Licence along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * Authors: + * Lubos Stanek + * Florian Forster + **/ +/** + * ignorelist handles plugin's list of configured collectable + * entries with global ignore action + **/ +/** + * Usage: + * + * Define plugin's global pointer variable of type ignorelist_t: + * ignorelist_t *myconfig_ignore; + * If you know the state of the global ignore (IgnoreSelected), + * allocate the variable with: + * myconfig_ignore = ignorelist_create (YourKnownIgnore); + * If you do not know the state of the global ignore, + * initialize the global variable and set the ignore flag later: + * myconfig_ignore = ignorelist_init (); + * Append single entries in your cf_register'ed callback function: + * ignorelist_add (myconfig_ignore, newentry); + * When you hit the IgnoreSelected config option, + * offer it to the list: + * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore); + * That is all for the ignorelist initialization. + * Later during read and write (plugin's registered functions) get + * the information whether this entry would be collected or not: + * if (ignorelist_match (myconfig_ignore, thisentry)) + * return; + **/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "common.h" +#include "plugin.h" +#include "utils_ignorelist.h" + +/* + * private prototypes + */ +struct ignorelist_item_s +{ +#if HAVE_REGEX_H + regex_t *rmatch; /* regular expression entry identification */ +#endif + char *smatch; /* string entry identification */ + struct ignorelist_item_s *next; +}; +typedef struct ignorelist_item_s ignorelist_item_t; + +struct ignorelist_s +{ + int ignore; /* ignore entries */ + ignorelist_item_t *head; /* pointer to the first entry */ +}; + +/* *** *** *** ********************************************* *** *** *** */ +/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */ +/* *** *** *** ********************************************* *** *** *** */ + +static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item) +{ + assert ((il != NULL) && (item != NULL)); + + item->next = il->head; + il->head = item; +} + +#if HAVE_REGEX_H +static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) +{ + regex_t *re; + ignorelist_item_t *entry; + int status; + + re = malloc (sizeof (*re)); + if (re == NULL) + { + ERROR ("utils_ignorelist: malloc failed"); + return (ENOMEM); + } + memset (re, 0, sizeof (*re)); + + status = regcomp (re, re_str, REG_EXTENDED); + if (status != 0) + { + char errbuf[1024] = ""; + regerror (status, re, errbuf, sizeof (errbuf)); + ERROR ("utils_ignorelist: regcomp failed: %s", errbuf); + regfree (re); + sfree (re); + return (status); + } + + entry = malloc (sizeof (*entry)); + if (entry == NULL) + { + ERROR ("utils_ignorelist: malloc failed"); + regfree (re); + sfree (re); + return (ENOMEM); + } + memset (entry, 0, sizeof (*entry)); + entry->rmatch = re; + + ignorelist_append (il, entry); + return (0); +} /* int ignorelist_append_regex */ +#endif + +static int ignorelist_append_string(ignorelist_t *il, const char *entry) +{ + ignorelist_item_t *new; + + /* create new entry */ + if ((new = malloc(sizeof(ignorelist_item_t))) == NULL ) + { + ERROR ("cannot allocate new entry"); + return (1); + } + memset (new, '\0', sizeof(ignorelist_item_t)); + new->smatch = sstrdup(entry); + + /* append new entry */ + ignorelist_append (il, new); + + return (0); +} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */ + +#if HAVE_REGEX_H +/* + * check list for entry regex match + * return 1 if found + */ +static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) +{ + assert ((item != NULL) && (item->rmatch != NULL) + && (entry != NULL) && (strlen (entry) > 0)); + + /* match regex */ + if (regexec (item->rmatch, entry, 0, NULL, 0) == 0) + return (1); + + return (0); +} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */ +#endif + +/* + * check list for entry string match + * return 1 if found + */ +static int ignorelist_match_string (ignorelist_item_t *item, const char *entry) +{ + assert ((item != NULL) && (item->smatch != NULL) + && (entry != NULL) && (strlen (entry) > 0)); + + if (strcmp (entry, item->smatch) == 0) + return (1); + + return (0); +} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */ + + +/* *** *** *** ******************************************** *** *** *** */ +/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ +/* *** *** *** ******************************************** *** *** *** */ + +/* + * create the ignorelist_t with known ignore state + * return pointer to ignorelist_t + */ +ignorelist_t *ignorelist_create (int invert) +{ + ignorelist_t *il; + + /* smalloc exits if it failes */ + il = (ignorelist_t *) smalloc (sizeof (ignorelist_t)); + memset (il, '\0', sizeof (ignorelist_t)); + + /* + * ->ignore == 0 => collect + * ->ignore == 1 => ignore + */ + il->ignore = invert ? 0 : 1; + + return (il); +} /* ignorelist_t *ignorelist_create (int ignore) */ + +/* + * free memory used by ignorelist_t + */ +void ignorelist_free (ignorelist_t *il) +{ + ignorelist_item_t *this; + ignorelist_item_t *next; + + if (il == NULL) + return; + + for (this = il->head; this != NULL; this = next) + { + next = this->next; +#if HAVE_REGEX_H + if (this->rmatch != NULL) + { + regfree (this->rmatch); + sfree (this->rmatch); + this->rmatch = NULL; + } +#endif + if (this->smatch != NULL) + { + sfree (this->smatch); + this->smatch = NULL; + } + sfree (this); + } + + sfree (il); + il = NULL; +} /* void ignorelist_destroy (ignorelist_t *il) */ + +/* + * set ignore state of the ignorelist_t + */ +void ignorelist_set_invert (ignorelist_t *il, int invert) +{ + if (il == NULL) + { + DEBUG("ignore call with ignorelist_t == NULL"); + return; + } + + il->ignore = invert ? 0 : 1; +} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */ + +/* + * append entry into ignorelist_t + * return 0 for success + */ +int ignorelist_add (ignorelist_t *il, const char *entry) +{ + size_t entry_len; + + if (il == NULL) + { + DEBUG ("add called with ignorelist_t == NULL"); + return (1); + } + + entry_len = strlen (entry); + + /* append nothing */ + if (entry_len == 0) + { + DEBUG("not appending: empty entry"); + return (1); + } + +#if HAVE_REGEX_H + /* regex string is enclosed in "/.../" */ + if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/') + { + char *entry_copy; + size_t entry_copy_size; + int status; + + /* We need to copy `entry' since it's const */ + entry_copy_size = entry_len - 1; + entry_copy = smalloc (entry_copy_size); + sstrncpy (entry_copy, entry + 1, entry_copy_size); + + status = ignorelist_append_regex(il, entry_copy); + sfree (entry_copy); + return status; + } +#endif + + return ignorelist_append_string(il, entry); +} /* int ignorelist_add (ignorelist_t *il, const char *entry) */ + +/* + * check list for entry + * return 1 for ignored entry + */ +int ignorelist_match (ignorelist_t *il, const char *entry) +{ + ignorelist_item_t *traverse; + + /* if no entries, collect all */ + if ((il == NULL) || (il->head == NULL)) + return (0); + + if ((entry == NULL) || (strlen (entry) == 0)) + return (0); + + /* traverse list and check entries */ + for (traverse = il->head; traverse != NULL; traverse = traverse->next) + { +#if HAVE_REGEX_H + if (traverse->rmatch != NULL) + { + if (ignorelist_match_regex (traverse, entry)) + return (il->ignore); + } + else +#endif + { + if (ignorelist_match_string (traverse, entry)) + return (il->ignore); + } + } /* for traverse */ + + return (1 - il->ignore); +} /* int ignorelist_match (ignorelist_t *il, const char *entry) */ + diff --git a/src/daemon/utils_ignorelist.h b/src/daemon/utils_ignorelist.h new file mode 100644 index 00000000..b47b55ad --- /dev/null +++ b/src/daemon/utils_ignorelist.h @@ -0,0 +1,70 @@ +/** + * collectd - src/utils_ignorelist.h + * Copyright (C) 2006 Lubos Stanek + * + * This program is free software; you can redistribute it and/ + * or modify it under the terms of the GNU General Public Li- + * cence as published by the Free Software Foundation; either + * version 2 of the Licence, or any later version. + * + * This program is distributed in the hope that it will be use- + * ful, but WITHOUT ANY WARRANTY; without even the implied war- + * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public Licence for more details. + * + * You should have received a copy of the GNU General Public + * Licence along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * Authors: + * Lubos Stanek + **/ +/** + * ignorelist handles plugin's list of configured collectable + * entries with global ignore action + **/ + +#ifndef UTILS_IGNORELIST_H +#define UTILS_IGNORELIST_H 1 + +#include "collectd.h" + +#if HAVE_REGEX_H +# include +#endif + +/* public prototypes */ + +struct ignorelist_s; +typedef struct ignorelist_s ignorelist_t; + +/* + * create the ignorelist_t with known ignore state + * return pointer to ignorelist_t + */ +ignorelist_t *ignorelist_create (int invert); + +/* + * free memory used by ignorelist_t + */ +void ignorelist_free (ignorelist_t *il); + +/* + * set ignore state of the ignorelist_t + */ +void ignorelist_set_invert (ignorelist_t *il, int invert); + +/* + * append entry to ignorelist_t + * returns zero on success, non-zero upon failure. + */ +int ignorelist_add (ignorelist_t *il, const char *entry); + +/* + * check list for entry + * return 1 for ignored entry + */ +int ignorelist_match (ignorelist_t *il, const char *entry); + +#endif /* UTILS_IGNORELIST_H */ diff --git a/src/daemon/utils_subst_test.c b/src/daemon/utils_subst_test.c index 75197663..c12aa105 100644 --- a/src/daemon/utils_subst_test.c +++ b/src/daemon/utils_subst_test.c @@ -29,6 +29,10 @@ #include "common.h" /* for STATIC_ARRAY_SIZE */ #include "utils_subst.h" +#if HAVE_LIBKSTAT +kstat_ctl_t *kc; +#endif /* HAVE_LIBKSTAT */ + DEF_TEST(subst) { struct { @@ -82,7 +86,7 @@ DEF_TEST(subst) } OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == &buffer[0]); - STREQ(cases[i].want, buffer); + EXPECT_EQ_STR(cases[i].want, buffer); } return 0; @@ -112,7 +116,7 @@ DEF_TEST(subst_string) } OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == buffer); - STREQ(cases[i].want, buffer); + EXPECT_EQ_STR(cases[i].want, buffer); } return 0; diff --git a/src/daemon/utils_time.h b/src/daemon/utils_time.h index 9b08e8e4..6566a739 100644 --- a/src/daemon/utils_time.h +++ b/src/daemon/utils_time.h @@ -1,6 +1,6 @@ /** - * collectd - src/utils_time.h - * Copyright (C) 2010 Florian octo Forster + * collectd - src/daemon/utils_time.h + * Copyright (C) 2010-2015 Florian octo Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster **/ #ifndef UTILS_TIME_H @@ -42,32 +42,37 @@ /* typedef uint64_t cdtime_t; */ /* 2^30 = 1073741824 */ -#define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) * 1073741824) -#define CDTIME_T_TO_TIME_T(t) ((time_t) ((t) / 1073741824)) +#define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) << 30) + +#define MS_TO_CDTIME_T(ms) (((((cdtime_t) (ms)) / 1000) << 30) | \ + ((((((cdtime_t) (ms)) % 1000) << 30) + 500) / 1000)) +#define US_TO_CDTIME_T(us) (((((cdtime_t) (us)) / 1000000) << 30) | \ + ((((((cdtime_t) (us)) % 1000000) << 30) + 500000) / 1000000)) +#define NS_TO_CDTIME_T(ns) (((((cdtime_t) (ns)) / 1000000000) << 30) | \ + ((((((cdtime_t) (ns)) % 1000000000) << 30) + 500000000) / 1000000000)) + +#define CDTIME_T_TO_TIME_T(t) ((time_t) (((t) + (1 << 29)) >> 30)) +#define CDTIME_T_TO_MS(t) ((uint64_t) ((((t) >> 30) * 1000) + \ + ((((t) & 0x3fffffff) * 1000 + (1 << 29)) >> 30))) +#define CDTIME_T_TO_US(t) ((uint64_t) ((((t) >> 30) * 1000000) + \ + ((((t) & 0x3fffffff) * 1000000 + (1 << 29)) >> 30))) +#define CDTIME_T_TO_NS(t) ((uint64_t) ((((t) >> 30) * 1000000000) + \ + ((((t) & 0x3fffffff) * 1000000000 + (1 << 29)) >> 30))) #define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0) #define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0)) -#define MS_TO_CDTIME_T(ms) ((cdtime_t) (((double) (ms)) * 1073741.824)) -#define CDTIME_T_TO_MS(t) ((long) (((double) (t)) / 1073741.824)) -#define US_TO_CDTIME_T(us) ((cdtime_t) (((double) (us)) * 1073.741824)) -#define CDTIME_T_TO_US(t) ((suseconds_t) (((double) (t)) / 1073.741824)) -#define NS_TO_CDTIME_T(ns) ((cdtime_t) (((double) (ns)) * 1.073741824)) -#define CDTIME_T_TO_NS(t) ((long) (((double) (t)) / 1.073741824)) - #define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \ (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \ - (tvp)->tv_usec = CDTIME_T_TO_US ((cdt) % 1073741824); \ + (tvp)->tv_usec = (suseconds_t) CDTIME_T_TO_US ((cdt) & 0x3fffffff); \ } while (0) -#define TIMEVAL_TO_CDTIME_T(tv) (TIME_T_TO_CDTIME_T ((tv)->tv_sec) \ - + US_TO_CDTIME_T ((tv)->tv_usec)) +#define TIMEVAL_TO_CDTIME_T(tv) US_TO_CDTIME_T(1000000 * (tv)->tv_sec + (tv)->tv_usec) #define CDTIME_T_TO_TIMESPEC(cdt,tsp) do { \ (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \ - (tsp)->tv_nsec = CDTIME_T_TO_NS ((cdt) % 1073741824); \ + (tsp)->tv_nsec = (long) CDTIME_T_TO_NS ((cdt) & 0x3fffffff); \ } while (0) -#define TIMESPEC_TO_CDTIME_T(ts) (TIME_T_TO_CDTIME_T ((ts)->tv_sec) \ - + NS_TO_CDTIME_T ((ts)->tv_nsec)) +#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec) cdtime_t cdtime (void); diff --git a/src/daemon/utils_time_test.c b/src/daemon/utils_time_test.c new file mode 100644 index 00000000..8eac0b62 --- /dev/null +++ b/src/daemon/utils_time_test.c @@ -0,0 +1,125 @@ +/** + * collectd - src/daemon/utils_time_test.c + * Copyright (C) 2015 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#define DBL_PRECISION 1e-3 + +#include "testing.h" +#include "collectd.h" +#include "utils_time.h" + +DEF_TEST(conversion) +{ + struct { + cdtime_t t; + double d; + time_t tt; + uint64_t ms; + struct timeval tv; + struct timespec ts; + } cases[] = { + /* cdtime double time_t milliseconds timeval timespec */ + { 0, 0.0 , 0, 0, { 0, 0}, { 0, 0}}, + { 10737418240ULL, 10.0 , 10, 10000, { 10, 0}, { 10, 0}}, + {1542908534771941376ULL, 1436945549.0 , 1436945549, 1436945549000ULL, {1436945549, 0}, {1436945549, 0}}, + {1542908535540740522ULL, 1436945549.716, 1436945550, 1436945549716ULL, {1436945549, 716000}, {1436945549, 716000000}}, + // 1426076671.123 * 2^30 = 1531238166015458148.352 + {1531238166015458148ULL, 1426076671.123, 1426076671, 1426076671123ULL, {1426076671, 123000}, {1426076671, 123000000}}, + // 1426076681.234 * 2^30 = 1531238176872061730.816 + {1531238176872061731ULL, 1426076681.234, 1426076681, 1426076681234ULL, {1426076681, 234000}, {1426076681, 234000000}}, + // 1426083986.314 * 2^30 = 1531246020641985396.736 + {1531246020641985397ULL, 1426083986.314, 1426083986, 1426083986314ULL, {1426083986, 314000}, {1426083986, 314000000}}, + // 1426083986.494142531 * 2^30 = 1531246020835411966.5 + {1531246020835411967ULL, 1426083986.494, 1426083986, 1426083986494ULL, {1426083986, 494143}, {1426083986, 494142531}}, + // 1426083986.987410814 * 2^30 = 1531246021365054752.4 + {1531246021365054752ULL, 1426083986.987, 1426083987, 1426083986987ULL, {1426083986, 987411}, {1426083986, 987410814}}, + + /* These cases test the cdtime_t -> ns conversion rounds correctly. */ + // 1546167635576736987 / 2^30 = 1439980823.1524536265... + {1546167635576736987ULL, 1439980823.152, 1439980823, 1439980823152ULL, {1439980823, 152454}, {1439980823, 152453627}}, + // 1546167831554815222 / 2^30 = 1439981005.6712620165... + {1546167831554815222ULL, 1439981005.671, 1439981006, 1439981005671ULL, {1439981005, 671262}, {1439981005, 671262017}}, + // 1546167986577716567 / 2^30 = 1439981150.0475896215... + {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150, 47590}, {1439981005, 47589622}}, + }; + size_t i; + + for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) { + struct timeval tv; + struct timespec ts; + + // cdtime -> s + EXPECT_EQ_UINT64 (cases[i].tt, CDTIME_T_TO_TIME_T (cases[i].t)); + + // cdtime -> ms + EXPECT_EQ_UINT64(cases[i].ms, CDTIME_T_TO_MS (cases[i].t)); + + // cdtime -> us + CDTIME_T_TO_TIMEVAL (cases[i].t, &tv); + EXPECT_EQ_UINT64 (cases[i].tv.tv_usec, tv.tv_usec); + + // cdtime -> ns + CDTIME_T_TO_TIMESPEC (cases[i].t, &ts); + EXPECT_EQ_UINT64 (cases[i].ts.tv_nsec, ts.tv_nsec); + + // cdtime -> double + EXPECT_EQ_DOUBLE (cases[i].d, CDTIME_T_TO_DOUBLE (cases[i].t)); + } + + return 0; +} + +/* These cases test the ns -> cdtime_t conversion rounds correctly. */ +DEF_TEST(ns_to_cdtime) +{ + struct { + uint64_t ns; + cdtime_t want; + } cases[] = { + // 1439981652801860766 * 2^30 / 10^9 = 1546168526406004689.4 + {1439981652801860766ULL, 1546168526406004689ULL}, + // 1439981836985281914 * 2^30 / 10^9 = 1546168724171447263.4 + {1439981836985281914ULL, 1546168724171447263ULL}, + // 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4 + {1439981880053705608ULL, 1546168770415815077ULL}, + }; + size_t i; + + for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) { + EXPECT_EQ_UINT64 (cases[i].want, NS_TO_CDTIME_T (cases[i].ns)); + } + + return 0; +} + +int main (void) +{ + RUN_TEST(conversion); + RUN_TEST(ns_to_cdtime); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/dbi.c b/src/dbi.c index c851ba2b..94d0762d 100644 --- a/src/dbi.c +++ b/src/dbi.c @@ -64,6 +64,8 @@ struct cdbi_database_s /* {{{ */ char *name; char *select_db; + cdtime_t interval; + char *driver; char *host; cdbi_driver_option_t *driver_options; @@ -215,6 +217,7 @@ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */ * * * Driver "mysql" + * Interval 120 * DriverOption "hostname" "localhost" * ... * Query "plugin_instance0" @@ -322,6 +325,8 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ &db->queries, &db->queries_num); else if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); + else if (strcasecmp ("Interval", child->key) == 0) + status = cf_util_get_cdtime(child, &db->interval); else { WARNING ("dbi plugin: Option `%s' not allowed here.", child->key); @@ -407,7 +412,7 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */ plugin_register_complex_read (/* group = */ NULL, /* name = */ name ? name : db->name, /* callback = */ cdbi_read_database, - /* interval = */ 0, + /* interval = */ (db->interval > 0) ? db->interval : 0, /* user_data = */ &ud); free (name); } @@ -597,7 +602,7 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */ udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g), /* plugin = */ "dbi", db->name, - column_names, column_num, /* interval = */ 0); + column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0); /* 0 = error; 1 = success; */ status = dbi_result_first_row (res); /* {{{ */ diff --git a/src/disk.c b/src/disk.c index 1c3dd98d..8f8f3702 100644 --- a/src/disk.c +++ b/src/disk.c @@ -53,6 +53,10 @@ #if HAVE_IOKIT_IOBSD_H # include #endif +#if KERNEL_FREEBSD +#include +#include +#endif #if HAVE_LIMITS_H # include @@ -107,6 +111,9 @@ typedef struct diskstats static diskstats_t *disklist; /* #endif KERNEL_LINUX */ +#elif KERNEL_FREEBSD +static struct gmesh geom_tree; +/* #endif KERNEL_FREEBSD */ #elif HAVE_LIBKSTAT #define MAX_NUMDISK 1024 @@ -222,6 +229,21 @@ static int disk_init (void) /* do nothing */ /* #endif KERNEL_LINUX */ +#elif KERNEL_FREEBSD + int rv; + + rv = geom_gettree(&geom_tree); + if (rv != 0) { + ERROR ("geom_gettree() failed, returned %d", rv); + return (-1); + } + rv = geom_stats_open(); + if (rv != 0) { + ERROR ("geom_stats_open() failed, returned %d", rv); + return (-1); + } +/* #endif KERNEL_FREEBSD */ + #elif HAVE_LIBKSTAT kstat_t *ksp_chain; @@ -505,6 +527,113 @@ static int disk_read (void) IOObjectRelease (disk_list); /* #endif HAVE_IOKIT_IOKITLIB_H */ +#elif KERNEL_FREEBSD + int retry, dirty; + + void *snap = NULL; + struct devstat *snap_iter; + + struct gident *geom_id; + + const char *disk_name; + long double read_time, write_time; + + for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) { + if (snap != NULL) + geom_stats_snapshot_free(snap); + + /* Get a fresh copy of stats snapshot */ + snap = geom_stats_snapshot_get(); + if (snap == NULL) { + ERROR("disk plugin: geom_stats_snapshot_get() failed."); + return (-1); + } + + /* Check if we have dirty read from this snapshot */ + dirty = 0; + geom_stats_snapshot_reset(snap); + while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) { + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + + /* New device? refresh GEOM tree */ + if (geom_id == NULL) { + geom_deletetree(&geom_tree); + if (geom_gettree(&geom_tree) != 0) { + ERROR("disk plugin: geom_gettree() failed"); + geom_stats_snapshot_free(snap); + return (-1); + } + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + } + /* + * This should be rare: the device come right before we take the + * snapshot and went away right after it. We will handle this + * case later, so don't mark dirty but silently ignore it. + */ + if (geom_id == NULL) + continue; + + /* Only collect PROVIDER data */ + if (geom_id->lg_what != ISPROVIDER) + continue; + + /* Only collect data when rank is 1 (physical devices) */ + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + + /* Check if this is a dirty read quit for another try */ + if (snap_iter->sequence0 != snap_iter->sequence1) { + dirty = 1; + break; + } + } + } + + /* Reset iterator */ + geom_stats_snapshot_reset(snap); + for (;;) { + snap_iter = geom_stats_snapshot_next(snap); + if (snap_iter == NULL) + break; + + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + if (geom_id == NULL) + continue; + if (geom_id->lg_what != ISPROVIDER) + continue; + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + /* Skip dirty reads, if present */ + if (dirty && (snap_iter->sequence0 != snap_iter->sequence1)) + continue; + + disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name; + + if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_octets", + (derive_t)snap_iter->bytes[DEVSTAT_READ], + (derive_t)snap_iter->bytes[DEVSTAT_WRITE]); + } + + if ((snap_iter->operations[DEVSTAT_READ] != 0) || (snap_iter->operations[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_ops", + (derive_t)snap_iter->operations[DEVSTAT_READ], + (derive_t)snap_iter->operations[DEVSTAT_WRITE]); + } + + read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL); + write_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL); + if ((read_time != 0) || (write_time != 0)) { + disk_submit (disk_name, "disk_time", + (derive_t)(read_time*1000), (derive_t)(write_time*1000)); + } + } + geom_stats_snapshot_free(snap); + #elif KERNEL_LINUX FILE *fh; char buffer[1024]; diff --git a/src/dns.c b/src/dns.c index fd75dc93..3421c475 100644 --- a/src/dns.c +++ b/src/dns.c @@ -34,7 +34,6 @@ #include #include -#include /* * Private data types diff --git a/src/email.c b/src/email.c index 365af274..1bf9adda 100644 --- a/src/email.c +++ b/src/email.c @@ -50,7 +50,6 @@ # include #endif -#include #include #include diff --git a/src/exec.c b/src/exec.c old mode 100644 new mode 100755 index 8d737cea..f080ad67 --- a/src/exec.c +++ b/src/exec.c @@ -355,6 +355,31 @@ static void reset_signal_mask (void) /* {{{ */ sigprocmask (SIG_SETMASK, &ss, /* old mask = */ NULL); } /* }}} void reset_signal_mask */ +static int create_pipe (int fd_pipe[2]) /* {{{ */ +{ + char errbuf[1024]; + int status; + + status = pipe (fd_pipe); + if (status != 0) + { + ERROR ("exec plugin: pipe failed: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + return 0; +} /* }}} int create_pipe */ + +static void close_pipe (int fd_pipe[2]) /* {{{ */ +{ + if (fd_pipe[0] != -1) + close (fd_pipe[0]); + + if (fd_pipe[1] != -1) + close (fd_pipe[1]); +} /* }}} void close_pipe */ + /* * Creates three pipes (one for reading, one for writing and one for errors), * forks a child, sets up the pipes so that fd_in is connected to STDIN of @@ -363,9 +388,9 @@ static void reset_signal_mask (void) /* {{{ */ */ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) /* {{{ */ { - int fd_pipe_in[2]; - int fd_pipe_out[2]; - int fd_pipe_err[2]; + int fd_pipe_in[2] = {-1, -1}; + int fd_pipe_out[2] = {-1, -1}; + int fd_pipe_err[2] = {-1, -1}; char errbuf[1024]; int status; int pid; @@ -381,29 +406,10 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) if (pl->pid != 0) return (-1); - status = pipe (fd_pipe_in); - if (status != 0) - { - ERROR ("exec plugin: pipe failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - status = pipe (fd_pipe_out); - if (status != 0) - { - ERROR ("exec plugin: pipe failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - status = pipe (fd_pipe_err); - if (status != 0) - { - ERROR ("exec plugin: pipe failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + if ((create_pipe(fd_pipe_in) == -1) + || (create_pipe(fd_pipe_out) == -1) + || (create_pipe(fd_pipe_err) == -1)) + goto failed; sp_ptr = NULL; status = getpwnam_r (pl->user, &sp, nambuf, sizeof (nambuf), &sp_ptr); @@ -411,12 +417,13 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) { ERROR ("exec plugin: Failed to get user information for user ``%s'': %s", pl->user, sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); + goto failed; } + if (sp_ptr == NULL) { ERROR ("exec plugin: No such user: `%s'", pl->user); - return (-1); + goto failed; } uid = sp.pw_uid; @@ -424,7 +431,7 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) if (uid == 0) { ERROR ("exec plugin: Cowardly refusing to exec program as root."); - return (-1); + goto failed; } /* The group configured in the configfile is set as effective group, because @@ -442,12 +449,12 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) ERROR ("exec plugin: Failed to get group information " "for group ``%s'': %s", pl->group, sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); + goto failed; } if (NULL == gr_ptr) { ERROR ("exec plugin: No such group: `%s'", pl->group); - return (-1); + goto failed; } egid = gr.gr_gid; @@ -463,7 +470,7 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) { ERROR ("exec plugin: fork failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); + goto failed; } else if (pid == 0) { @@ -531,6 +538,13 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err) close (fd_pipe_err[0]); return (pid); + +failed: + close_pipe(fd_pipe_in); + close_pipe(fd_pipe_out); + close_pipe(fd_pipe_err); + + return (-1); } /* int fork_child }}} */ static int parse_line (char *buffer) /* {{{ */ diff --git a/src/gmond.c b/src/gmond.c index 4660713b..c778d48d 100644 --- a/src/gmond.c +++ b/src/gmond.c @@ -33,9 +33,6 @@ #if HAVE_PTHREAD_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NETDB_H # include #endif diff --git a/src/hddtemp.c b/src/hddtemp.c index 82c158ca..3de18fd9 100644 --- a/src/hddtemp.c +++ b/src/hddtemp.c @@ -35,7 +35,6 @@ #include "configfile.h" # include -# include # include # include # include /* for basename */ diff --git a/src/interface.c b/src/interface.c index df8ffb46..e17711e3 100644 --- a/src/interface.c +++ b/src/interface.c @@ -31,9 +31,6 @@ #if HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif /* One cannot include both. This sucks. */ #if HAVE_LINUX_IF_H diff --git a/src/ipc.c b/src/ipc.c index 3763f248..b4038472 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -32,6 +32,9 @@ #include "configfile.h" #if KERNEL_LINUX + /* _GNU_SOURCE is needed for struct shm_info.used_ids on musl libc */ +# define _GNU_SOURCE + /* X/OPEN tells us to use for semctl() */ /* X/OPEN tells us to use for msgctl() */ /* X/OPEN tells us to use for shmctl() */ diff --git a/src/iptables.c b/src/iptables.c index 606b24d9..806b7a45 100644 --- a/src/iptables.c +++ b/src/iptables.c @@ -29,8 +29,6 @@ #include "plugin.h" #include "configfile.h" -#include - #include #include diff --git a/src/ipvs.c b/src/ipvs.c index 38e46410..4345a465 100644 --- a/src/ipvs.c +++ b/src/ipvs.c @@ -37,9 +37,6 @@ #if HAVE_ARPA_INET_H # include #endif /* HAVE_ARPA_INET_H */ -#if HAVE_SYS_SOCKET_H -# include -#endif /* HAVE_SYS_SOCKET_H */ #if HAVE_NETINET_IN_H # include #endif /* HAVE_NETINET_IN_H */ diff --git a/src/libcollectdclient/Makefile.am b/src/libcollectdclient/Makefile.am index 5abee2f1..e81a5943 100644 --- a/src/libcollectdclient/Makefile.am +++ b/src/libcollectdclient/Makefile.am @@ -1,9 +1,5 @@ AUTOMAKE_OPTIONS = foreign no-dependencies -if COMPILER_IS_GCC -AM_CFLAGS = -Wall -Werror -endif - pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h lib_LTLIBRARIES = libcollectdclient.la nodist_pkgconfig_DATA = libcollectdclient.pc diff --git a/src/liboconfig/scanner.l b/src/liboconfig/scanner.l index 638e3a23..41d66438 100644 --- a/src/liboconfig/scanner.l +++ b/src/liboconfig/scanner.l @@ -28,6 +28,7 @@ %{ #include +#include #include "oconfig.h" #include "aux_types.h" #include "parser.h" diff --git a/src/log_logstash.c b/src/log_logstash.c index 2883e6c9..2d5f6203 100644 --- a/src/log_logstash.c +++ b/src/log_logstash.c @@ -147,7 +147,7 @@ static void log_logstash_print (yajl_gen g, int severity, * format time as a UTC ISO 8601 compliant string */ strftime (timestamp_str, sizeof (timestamp_str), - "%Y-%m-%d %H:%M:%SZ", ×tamp_tm); + "%Y-%m-%dT%H:%M:%SZ", ×tamp_tm); timestamp_str[sizeof (timestamp_str) - 1] = '\0'; if (yajl_gen_string(g, (u_char *)timestamp_str, diff --git a/src/madwifi.c b/src/madwifi.c index d3a58030..bb33b15d 100644 --- a/src/madwifi.c +++ b/src/madwifi.c @@ -96,7 +96,6 @@ #include #include -#include #if !KERNEL_LINUX # error "No applicable input method." diff --git a/src/mbmon.c b/src/mbmon.c index d23062db..5e87f00b 100644 --- a/src/mbmon.c +++ b/src/mbmon.c @@ -29,7 +29,6 @@ #include "configfile.h" #include -#include #include #include diff --git a/src/memcached.c b/src/memcached.c index 472b0897..f684abff 100644 --- a/src/memcached.c +++ b/src/memcached.c @@ -34,7 +34,6 @@ #include "configfile.h" #include -#include #include #include #include diff --git a/src/memory.c b/src/memory.c index fb2f3d38..ea16ce31 100644 --- a/src/memory.c +++ b/src/memory.c @@ -76,6 +76,7 @@ static vm_size_t pagesize; #elif HAVE_LIBKSTAT static int pagesize; static kstat_t *ksp; +static kstat_t *ksz; /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL @@ -137,6 +138,12 @@ static int memory_init (void) ksp = NULL; return (-1); } + if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0) + { + ksz = NULL; + return (-1); + } + /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYSCTL @@ -371,6 +378,8 @@ static int memory_read_internal (value_list_t *vl) long long mem_lock; long long mem_kern; long long mem_unus; + long long arcsize; + long long pp_kernel; long long physmem; @@ -378,17 +387,20 @@ static int memory_read_internal (value_list_t *vl) if (ksp == NULL) return (-1); + if (ksz == NULL) + return (-1); mem_used = get_kstat_value (ksp, "pagestotal"); mem_free = get_kstat_value (ksp, "pagesfree"); mem_lock = get_kstat_value (ksp, "pageslocked"); - mem_kern = 0; - mem_unus = 0; - + arcsize = get_kstat_value (ksz, "size"); pp_kernel = get_kstat_value (ksp, "pp_kernel"); physmem = get_kstat_value (ksp, "physmem"); availrmem = get_kstat_value (ksp, "availrmem"); + mem_kern = 0; + mem_unus = 0; + if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) { WARNING ("memory plugin: one of used, free or locked is negative."); @@ -431,11 +443,14 @@ static int memory_read_internal (value_list_t *vl) mem_lock *= pagesize; /* some? ;) */ mem_kern *= pagesize; /* it's 2011 RAM is cheap */ mem_unus *= pagesize; + mem_kern -= arcsize; + MEMORY_SUBMIT ("used", (gauge_t) mem_used, "free", (gauge_t) mem_free, "locked", (gauge_t) mem_lock, "kernel", (gauge_t) mem_kern, + "arc", (gauge_t) arcsize, "unusable", (gauge_t) mem_unus); /* #endif HAVE_LIBKSTAT */ diff --git a/src/mqtt.c b/src/mqtt.c index 210d38cb..7003fcc6 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -24,6 +24,7 @@ * Authors: * Marc Falzon * Florian octo Forster + * Jan-Piet Mens **/ // Reference: http://mosquitto.org/api/files/mosquitto-h.html @@ -48,6 +49,9 @@ #ifndef MQTT_KEEPALIVE # define MQTT_KEEPALIVE 60 #endif +#ifndef SSL_VERIFY_PEER +# define SSL_VERIFY_PEER 1 +#endif /* @@ -67,6 +71,11 @@ struct mqtt_client_conf char *username; char *password; int qos; + char *cacertificatefile; + char *certificatefile; + char *certificatekeyfile; + char *tlsprotocol; + char *ciphersuite; /* For publishing */ char *topic_prefix; @@ -176,9 +185,10 @@ static void on_message ( char *payload; int status; - if ((msg->payloadlen <= 0) - || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0)) + if (msg->payloadlen <= 0) { + DEBUG ("mqtt plugin: message has empty payload"); return; + } topic = strdup (msg->topic); name = strip_prefix (topic); @@ -207,7 +217,15 @@ static void on_message ( } vl.values_len = ds->ds_num; - payload = strdup ((void *) msg->payload); + payload = malloc (msg->payloadlen+1); + if (payload == NULL) + { + ERROR ("mqtt plugin: malloc for payload buffer failed."); + return; + } + memmove (payload, msg->payload, msg->payloadlen); + payload[msg->payloadlen] = 0; + DEBUG ("mqtt plugin: payload = \"%s\"", payload); status = parse_values (payload, &vl, ds); if (status != 0) @@ -277,6 +295,35 @@ static int mqtt_connect (mqtt_client_conf_t *conf) return (-1); } +#if LIBMOSQUITTO_MAJOR != 0 + if (conf->cacertificatefile) { + status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL, + conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL); + if (status != MOSQ_ERR_SUCCESS) { + ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status)); + mosquitto_destroy (conf->mosq); + conf->mosq = NULL; + return (-1); + } + + status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite); + if (status != MOSQ_ERR_SUCCESS) { + ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status)); + mosquitto_destroy (conf->mosq); + conf->mosq = NULL; + return (-1); + } + + status = mosquitto_tls_insecure_set(conf->mosq, false); + if (status != MOSQ_ERR_SUCCESS) { + ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status)); + mosquitto_destroy (conf->mosq); + conf->mosq = NULL; + return (-1); + } + } +#endif + if (conf->username && conf->password) { status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password); @@ -407,11 +454,11 @@ static int publish (mqtt_client_conf_t *conf, char const *topic, { char errbuf[1024]; c_complain (LOG_ERR, - &conf->complaint_cantpublish, - "plugin mqtt: mosquitto_publish failed: %s", - status == MOSQ_ERR_ERRNO ? - sstrerror(errno, errbuf, sizeof (errbuf)) : - mosquitto_strerror(status)); + &conf->complaint_cantpublish, + "mqtt plugin: mosquitto_publish failed: %s", + (status == MOSQ_ERR_ERRNO) + ? sstrerror(errno, errbuf, sizeof (errbuf)) + : mosquitto_strerror(status)); /* Mark our connection "down" regardless of the error as a safety * measure; we will try to reconnect the next time we have to publish a * message */ @@ -494,6 +541,10 @@ static int mqtt_write (const data_set_t *ds, const value_list_t *vl, * StoreRates true * Retain false * QoS 0 + * CACert "ca.pem" Enables TLS if set + * CertificateFile "client-cert.pem" optional + * CertificateKeyFile "client-key.pem" optional + * TLSProtocol "tlsv1.2" optional * */ static int mqtt_config_publisher (oconfig_item_t *ci) @@ -527,6 +578,13 @@ static int mqtt_config_publisher (oconfig_item_t *ci) conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX); conf->store_rates = 1; + status = pthread_mutex_init (&conf->lock, NULL); + if (status != 0) + { + mqtt_free (conf); + return (status); + } + C_COMPLAIN_INIT (&conf->complaint_cantpublish); for (i = 0; i < ci->children_num; i++) @@ -563,6 +621,16 @@ static int mqtt_config_publisher (oconfig_item_t *ci) cf_util_get_boolean (child, &conf->store_rates); else if (strcasecmp ("Retain", child->key) == 0) cf_util_get_boolean (child, &conf->retain); + else if (strcasecmp ("CACert", child->key) == 0) + cf_util_get_string (child, &conf->cacertificatefile); + else if (strcasecmp ("CertificateFile", child->key) == 0) + cf_util_get_string (child, &conf->certificatefile); + else if (strcasecmp ("CertificateKeyFile", child->key) == 0) + cf_util_get_string (child, &conf->certificatekeyfile); + else if (strcasecmp ("TLSProtocol", child->key) == 0) + cf_util_get_string (child, &conf->tlsprotocol); + else if (strcasecmp ("CipherSuite", child->key) == 0) + cf_util_get_string (child, &conf->ciphersuite); else ERROR ("mqtt plugin: Unknown config option: %s", child->key); } @@ -583,7 +651,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci) * User "guest" * Password "secret" * Topic "collectd/#" - * + * */ static int mqtt_config_subscriber (oconfig_item_t *ci) { @@ -615,6 +683,13 @@ static int mqtt_config_subscriber (oconfig_item_t *ci) conf->topic = strdup (MQTT_DEFAULT_TOPIC); conf->clean_session = 1; + status = pthread_mutex_init (&conf->lock, NULL); + if (status != 0) + { + mqtt_free (conf); + return (status); + } + C_COMPLAIN_INIT (&conf->complaint_cantpublish); for (i = 0; i < ci->children_num; i++) diff --git a/src/netlink.c b/src/netlink.c index aa9760f9..e1f378d9 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -30,7 +30,6 @@ #include "common.h" #include -#include #include #include diff --git a/src/network.c b/src/network.c index 0c74e224..91690006 100644 --- a/src/network.c +++ b/src/network.c @@ -39,9 +39,6 @@ #if HAVE_PTHREAD_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NETDB_H # include #endif diff --git a/src/nginx.c b/src/nginx.c index 4e4ce3bb..69ec06dc 100644 --- a/src/nginx.c +++ b/src/nginx.c @@ -188,8 +188,7 @@ static int init (void) } else { - curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, - CDTIME_T_TO_MS(plugin_get_interval())); + curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); } #endif diff --git a/src/ntpd.c b/src/ntpd.c index 952ab7ca..dbde6609 100644 --- a/src/ntpd.c +++ b/src/ntpd.c @@ -38,9 +38,6 @@ #if HAVE_NETDB_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NETINET_IN_H # include #endif diff --git a/src/olsrd.c b/src/olsrd.c index 6d0576cf..bbf387f4 100644 --- a/src/olsrd.c +++ b/src/olsrd.c @@ -30,7 +30,6 @@ #include #include -#include #include #include diff --git a/src/pf.c b/src/pf.c index 29f3a3d5..a2bd5499 100644 --- a/src/pf.c +++ b/src/pf.c @@ -26,12 +26,12 @@ #if HAVE_SYS_IOCTL_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NET_IF_H # include #endif +#if HAVE_NETINET_IN_H +# include +#endif #include diff --git a/src/pinba.c b/src/pinba.c index 9f0a8002..b6e7b152 100644 --- a/src/pinba.c +++ b/src/pinba.c @@ -29,7 +29,6 @@ #include "configfile.h" #include -#include #include #include diff --git a/src/powerdns.c b/src/powerdns.c index 7b7cab39..1050e7fa 100644 --- a/src/powerdns.c +++ b/src/powerdns.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #ifndef UNIX_PATH_MAX @@ -83,42 +82,65 @@ struct statname_lookup_s typedef struct statname_lookup_s statname_lookup_t; /* Description of statistics returned by the recursor: {{{ -all-outqueries counts the number of outgoing UDP queries since starting -answers0-1 counts the number of queries answered within 1 millisecond -answers100-1000 counts the number of queries answered within 1 second -answers10-100 counts the number of queries answered within 100 milliseconds -answers1-10 counts the number of queries answered within 10 milliseconds -answers-slow counts the number of queries answered after 1 second -cache-entries shows the number of entries in the cache -cache-hits counts the number of cache hits since starting -cache-misses counts the number of cache misses since starting -chain-resends number of queries chained to existing outstanding query -client-parse-errors counts number of client packets that could not be parsed -concurrent-queries shows the number of MThreads currently running -dlg-only-drops number of records dropped because of delegation only setting -negcache-entries shows the number of entries in the Negative answer cache -noerror-answers counts the number of times it answered NOERROR since starting -nsspeeds-entries shows the number of entries in the NS speeds map -nsset-invalidations number of times an nsset was dropped because it no longer worked -nxdomain-answers counts the number of times it answered NXDOMAIN since starting -outgoing-timeouts counts the number of timeouts on outgoing UDP queries since starting -qa-latency shows the current latency average -questions counts all End-user initiated queries with the RD bit set -resource-limits counts number of queries that could not be performed because of resource limits -server-parse-errors counts number of server replied packets that could not be parsed -servfail-answers counts the number of times it answered SERVFAIL since starting -spoof-prevents number of times PowerDNS considered itself spoofed, and dropped the data -sys-msec number of CPU milliseconds spent in 'system' mode -tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections -tcp-outqueries counts the number of outgoing TCP queries since starting -tcp-questions counts all incoming TCP queries (since starting) -throttled-out counts the number of throttled outgoing UDP queries since starting -throttle-entries shows the number of entries in the throttle map -unauthorized-tcp number of TCP questions denied because of allow-from restrictions -unauthorized-udp number of UDP questions denied because of allow-from restrictions -unexpected-packets number of answers from remote servers that were unexpected (might point to spoofing) -uptime number of seconds process has been running (since 3.1.5) -user-msec number of CPU milliseconds spent in 'user' mode +all-outqueries counts the number of outgoing UDP queries since starting +answers-slow counts the number of queries answered after 1 second +answers0-1 counts the number of queries answered within 1 millisecond +answers1-10 counts the number of queries answered within 10 milliseconds +answers10-100 counts the number of queries answered within 100 milliseconds +answers100-1000 counts the number of queries answered within 1 second +cache-bytes size of the cache in bytes (since 3.3.1) +cache-entries shows the number of entries in the cache +cache-hits counts the number of cache hits since starting, this does not include hits that got answered from the packet-cache +cache-misses counts the number of cache misses since starting +case-mismatches counts the number of mismatches in character case since starting +chain-resends number of queries chained to existing outstanding query +client-parse-errors counts number of client packets that could not be parsed +concurrent-queries shows the number of MThreads currently running +dlg-only-drops number of records dropped because of delegation only setting +dont-outqueries number of outgoing queries dropped because of 'dont-query' setting (since 3.3) +edns-ping-matches number of servers that sent a valid EDNS PING respons +edns-ping-mismatches number of servers that sent an invalid EDNS PING response +failed-host-entries number of servers that failed to resolve +ipv6-outqueries number of outgoing queries over IPv6 +ipv6-questions counts all End-user initiated queries with the RD bit set, received over IPv6 UDP +malloc-bytes returns the number of bytes allocated by the process (broken, always returns 0) +max-mthread-stack maximum amount of thread stack ever used +negcache-entries shows the number of entries in the Negative answer cache +no-packet-error number of errorneous received packets +noedns-outqueries number of queries sent out without EDNS +noerror-answers counts the number of times it answered NOERROR since starting +noping-outqueries number of queries sent out without ENDS PING +nsset-invalidations number of times an nsset was dropped because it no longer worked +nsspeeds-entries shows the number of entries in the NS speeds map +nxdomain-answers counts the number of times it answered NXDOMAIN since starting +outgoing-timeouts counts the number of timeouts on outgoing UDP queries since starting +over-capacity-drops questions dropped because over maximum concurrent query limit (since 3.2) +packetcache-bytes size of the packet cache in bytes (since 3.3.1) +packetcache-entries size of packet cache (since 3.2) +packetcache-hits packet cache hits (since 3.2) +packetcache-misses packet cache misses (since 3.2) +policy-drops packets dropped because of (Lua) policy decision +qa-latency shows the current latency average +questions counts all end-user initiated queries with the RD bit set +resource-limits counts number of queries that could not be performed because of resource limits +security-status security status based on security polling +server-parse-errors counts number of server replied packets that could not be parsed +servfail-answers counts the number of times it answered SERVFAIL since starting +spoof-prevents number of times PowerDNS considered itself spoofed, and dropped the data +sys-msec number of CPU milliseconds spent in 'system' mode +tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections +tcp-clients counts the number of currently active TCP/IP clients +tcp-outqueries counts the number of outgoing TCP queries since starting +tcp-questions counts all incoming TCP queries (since starting) +throttle-entries shows the number of entries in the throttle map +throttled-out counts the number of throttled outgoing UDP queries since starting +throttled-outqueries idem to throttled-out +unauthorized-tcp number of TCP questions denied because of allow-from restrictions +unauthorized-udp number of UDP questions denied because of allow-from restrictions +unexpected-packets number of answers from remote servers that were unexpected (might point to spoofing) +unreachables number of times nameservers were unreachable since starting +uptime number of seconds process has been running (since 3.1.5) +user-msec number of CPU milliseconds spent in 'user' mode }}} */ const char* const default_server_fields[] = /* {{{ */ @@ -157,8 +179,13 @@ statname_lookup_t lookup_table[] = /* {{{ */ {"udp-answers-bytes", "total_bytes", "udp-answers-bytes"}, /* Cache stuff */ + {"cache-bytes", "cache_size", "cache-bytes"}, + {"packetcache-bytes", "cache_size", "packet-bytes"}, + {"packetcache-entries", "cache_size", "packet-entries"}, {"packetcache-hit", "cache_result", "packet-hit"}, + {"packetcache-hits", "cache_result", "packet-hit"}, {"packetcache-miss", "cache_result", "packet-miss"}, + {"packetcache-misses", "cache_result", "packet-miss"}, {"packetcache-size", "cache_size", "packet"}, {"key-cache-size", "cache_size", "key"}, {"meta-cache-size", "cache_size", "meta"}, @@ -179,6 +206,7 @@ statname_lookup_t lookup_table[] = /* {{{ */ {"corrupt-packets", "ipt_packets", "corrupt"}, {"deferred-cache-inserts", "counter", "cache-deferred_insert"}, {"deferred-cache-lookup", "counter", "cache-deferred_lookup"}, + {"dont-outqueries", "dns_question", "dont-outqueries"}, {"qsize-a", "cache_size", "answers"}, {"qsize-q", "cache_size", "questions"}, {"servfail-packets", "ipt_packets", "servfail"}, @@ -195,52 +223,67 @@ statname_lookup_t lookup_table[] = /* {{{ */ * Recursor statistics * ***********************/ /* Answers by return code */ - {"noerror-answers", "dns_rcode", "NOERROR"}, - {"nxdomain-answers", "dns_rcode", "NXDOMAIN"}, - {"servfail-answers", "dns_rcode", "SERVFAIL"}, + {"noerror-answers", "dns_rcode", "NOERROR"}, + {"nxdomain-answers", "dns_rcode", "NXDOMAIN"}, + {"servfail-answers", "dns_rcode", "SERVFAIL"}, /* CPU utilization */ - {"sys-msec", "cpu", "system"}, - {"user-msec", "cpu", "user"}, + {"sys-msec", "cpu", "system"}, + {"user-msec", "cpu", "user"}, /* Question-to-answer latency */ - {"qa-latency", "latency", NULL}, + {"qa-latency", "latency", NULL}, /* Cache */ - {"cache-entries", "cache_size", NULL}, - {"cache-hits", "cache_result", "hit"}, - {"cache-misses", "cache_result", "miss"}, + {"cache-entries", "cache_size", NULL}, + {"cache-hits", "cache_result", "hit"}, + {"cache-misses", "cache_result", "miss"}, /* Total number of questions.. */ - {"questions", "dns_qtype", "total"}, + {"questions", "dns_qtype", "total"}, /* All the other stuff.. */ - {"all-outqueries", "dns_question", "outgoing"}, - {"answers0-1", "dns_answer", "0_1"}, - {"answers1-10", "dns_answer", "1_10"}, - {"answers10-100", "dns_answer", "10_100"}, - {"answers100-1000", "dns_answer", "100_1000"}, - {"answers-slow", "dns_answer", "slow"}, - {"chain-resends", "dns_question", "chained"}, - {"client-parse-errors", "counter", "drops-client_parse_error"}, - {"concurrent-queries", "dns_question", "concurrent"}, - {"dlg-only-drops", "counter", "drops-delegation_only"}, - {"negcache-entries", "cache_size", "negative"}, - {"nsspeeds-entries", "gauge", "entries-ns_speeds"}, - {"nsset-invalidations", "counter", "ns_set_invalidation"}, - {"outgoing-timeouts", "counter", "drops-timeout_outgoing"}, - {"resource-limits", "counter", "drops-resource_limit"}, - {"server-parse-errors", "counter", "drops-server_parse_error"}, - {"spoof-prevents", "counter", "drops-spoofed"}, - {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"}, - {"tcp-outqueries", "dns_question", "outgoing-tcp"}, - {"tcp-questions", "dns_question", "incoming-tcp"}, - {"throttled-out", "dns_question", "outgoing-throttled"}, - {"throttle-entries", "gauge", "entries-throttle"}, - {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"}, - {"unauthorized-udp", "counter", "denied-unauthorized_udp"}, - {"unexpected-packets", "dns_answer", "unexpected"}, - {"uptime", "uptime", NULL} + {"all-outqueries", "dns_question", "outgoing"}, + {"answers0-1", "dns_answer", "0_1"}, + {"answers1-10", "dns_answer", "1_10"}, + {"answers10-100", "dns_answer", "10_100"}, + {"answers100-1000", "dns_answer", "100_1000"}, + {"answers-slow", "dns_answer", "slow"}, + {"case-mismatches", "counter", "case_mismatches"}, + {"chain-resends", "dns_question", "chained"}, + {"client-parse-errors", "counter", "drops-client_parse_error"}, + {"concurrent-queries", "dns_question", "concurrent"}, + {"dlg-only-drops", "counter", "drops-delegation_only"}, + {"edns-ping-matches", "counter", "edns-ping_matches"}, + {"edns-ping-mismatches", "counter", "edns-ping_mismatches"}, + {"failed-host-entries", "counter", "entries-failed_host"}, + {"ipv6-outqueries", "dns_question", "outgoing-ipv6"}, + {"ipv6-questions", "dns_question", "incoming-ipv6"}, + {"malloc-bytes", "gauge", "malloc_bytes"}, + {"max-mthread-stack", "gauge", "max_mthread_stack"}, + {"no-packet-error", "gauge", "no_packet_error"}, + {"noedns-outqueries", "dns_question", "outgoing-noedns"}, + {"noping-outqueries", "dns_question", "outgoing-noping"}, + {"over-capacity-drops", "dns_question", "incoming-over_capacity"}, + {"negcache-entries", "cache_size", "negative"}, + {"nsspeeds-entries", "gauge", "entries-ns_speeds"}, + {"nsset-invalidations", "counter", "ns_set_invalidation"}, + {"outgoing-timeouts", "counter", "drops-timeout_outgoing"}, + {"policy-drops", "counter", "drops-policy"}, + {"resource-limits", "counter", "drops-resource_limit"}, + {"server-parse-errors", "counter", "drops-server_parse_error"}, + {"spoof-prevents", "counter", "drops-spoofed"}, + {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"}, + {"tcp-clients", "gauge", "clients-tcp"}, + {"tcp-outqueries", "dns_question", "outgoing-tcp"}, + {"tcp-questions", "dns_question", "incoming-tcp"}, + {"throttled-out", "dns_question", "outgoing-throttled"}, + {"throttle-entries", "gauge", "entries-throttle"}, + {"throttled-outqueries", "dns_question", "outgoing-throttle"}, + {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"}, + {"unauthorized-udp", "counter", "denied-unauthorized_udp"}, + {"unexpected-packets", "dns_answer", "unexpected"}, + {"uptime", "uptime", NULL} }; /* }}} */ int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table); @@ -250,14 +293,12 @@ static llist_t *list = NULL; static char *local_sockpath = NULL; /* TODO: Do this before 4.4: - * - Recursor: - * - Complete list of known pdns -> collectd mappings. * - Update the collectd.conf(5) manpage. * * -octo */ -/* */ +/* */ static void submit (const char *plugin_instance, /* {{{ */ const char *pdns_type, const char *value) { diff --git a/src/processes.c b/src/processes.c index 24dbf492..d094e73e 100644 --- a/src/processes.c +++ b/src/processes.c @@ -2027,18 +2027,18 @@ static int ps_read (void) pse.io_syscw = -1; ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse); - } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ - switch (procs[i].ki_stat) - { - case SSTOP: stopped++; break; - case SSLEEP: sleeping++; break; - case SRUN: running++; break; - case SIDL: idle++; break; - case SWAIT: wait++; break; - case SLOCK: blocked++; break; - case SZOMB: zombies++; break; - } + switch (procs[i].ki_stat) + { + case SSTOP: stopped++; break; + case SSLEEP: sleeping++; break; + case SRUN: running++; break; + case SIDL: idle++; break; + case SWAIT: wait++; break; + case SLOCK: blocked++; break; + case SZOMB: zombies++; break; + } + } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */ } kvm_close(kd); @@ -2163,18 +2163,18 @@ static int ps_read (void) pse.cswitch_invol = -1; ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse); - } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */ - switch (procs[i].p_stat) - { - case SSTOP: stopped++; break; - case SSLEEP: sleeping++; break; - case SRUN: running++; break; - case SIDL: idle++; break; - case SONPROC: onproc++; break; - case SDEAD: dead++; break; - case SZOMB: zombies++; break; - } + switch (procs[i].p_stat) + { + case SSTOP: stopped++; break; + case SSLEEP: sleeping++; break; + case SRUN: running++; break; + case SIDL: idle++; break; + case SONPROC: onproc++; break; + case SDEAD: dead++; break; + case SZOMB: zombies++; break; + } + } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */ } kvm_close(kd); diff --git a/src/python.c b/src/python.c index b7cc5b91..210d785c 100644 --- a/src/python.c +++ b/src/python.c @@ -302,7 +302,7 @@ void cpy_log_exception(const char *context) { Py_XDECREF(traceback); return; } - list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. */ + list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */ if (list) l = PyObject_Length(list); for (i = 0; i < l; ++i) { @@ -322,9 +322,6 @@ void cpy_log_exception(const char *context) { } Py_XDECREF(list); PyErr_Clear(); - Py_DECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); } static int cpy_read_callback(user_data_t *data) { diff --git a/src/routeros.c b/src/routeros.c index 400ee42b..667c2fa5 100644 --- a/src/routeros.c +++ b/src/routeros.c @@ -331,7 +331,7 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */ router_data = malloc (sizeof (*router_data)); if (router_data == NULL) return (-1); - memset (router_data, 0, sizeof (router_data)); + memset (router_data, 0, sizeof (*router_data)); router_data->connection = NULL; router_data->node = NULL; router_data->service = NULL; diff --git a/src/snmp.c b/src/snmp.c index d9a932a3..6a03a19d 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -924,8 +924,7 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, tmp_unsigned = (uint32_t) *vl->val.integer; tmp_signed = (int32_t) *vl->val.integer; - if ((vl->type == ASN_INTEGER) - || (vl->type == ASN_GAUGE)) + if (vl->type == ASN_INTEGER) prefer_signed = 1; DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned); @@ -1681,7 +1680,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data) if (host->sess_handle == NULL) { - DEBUG ("snmp plugin: csnmp_read_table: host->sess_handle == NULL"); + DEBUG ("snmp plugin: csnmp_read_value: host->sess_handle == NULL"); return (-1); } diff --git a/src/statsd.c b/src/statsd.c index 5b0bdd69..8047b1a6 100644 --- a/src/statsd.c +++ b/src/statsd.c @@ -35,7 +35,6 @@ #include #include -#include #include #include @@ -851,8 +850,19 @@ static int statsd_metric_submit_unsafe (char const *name, /* {{{ */ else values[0].gauge = (gauge_t) c_avl_size (metric->set); } - else - values[0].derive = (derive_t) metric->value; + else { /* STATSD_COUNTER */ + /* + * Expand a single value to two metrics: + * + * - The absolute counter, as a gauge + * - A derived rate for this counter + */ + values[0].derive = (derive_t) metric->value; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type, "gauge", sizeof (vl.type)); + values[0].gauge = (gauge_t) metric->value; + } return (plugin_dispatch_values (&vl)); } /* }}} int statsd_metric_submit_unsafe */ @@ -942,7 +952,7 @@ static int statsd_shutdown (void) /* {{{ */ while (c_avl_pick (metrics_tree, &key, &value) == 0) { sfree (key); - sfree (value); + statsd_metric_free (value); } c_avl_destroy (metrics_tree); metrics_tree = NULL; diff --git a/src/table.c b/src/table.c index b0bc95f8..4e34a9ec 100644 --- a/src/table.c +++ b/src/table.c @@ -458,7 +458,7 @@ static int tbl_parse_line (tbl_t *tbl, char *line, size_t len) } if (i <= tbl->max_colnum) { - log_err ("Not enough columns in line " + log_warn ("Not enough columns in line " "(expected at least %zu, got %zu).", tbl->max_colnum + 1, i); return -1; @@ -490,11 +490,11 @@ static int tbl_read_table (tbl_t *tbl) while (NULL != fgets (buf, sizeof (buf), fh)) { if ('\0' != buf[sizeof (buf) - 1]) { buf[sizeof (buf) - 1] = '\0'; - log_err ("Table %s: Truncated line: %s", tbl->file, buf); + log_warn ("Table %s: Truncated line: %s", tbl->file, buf); } if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) { - log_err ("Table %s: Failed to parse line: %s", tbl->file, buf); + log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf); continue; } } diff --git a/src/tcpconns.c b/src/tcpconns.c index 5d4bb696..8f40be6f 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -71,13 +71,10 @@ #if KERNEL_LINUX # include -/* sys/socket.h is necessary to compile when using netlink on older systems. */ -# include # include #if HAVE_LINUX_INET_DIAG_H # include #endif -# include # include /* #endif KERNEL_LINUX */ @@ -90,9 +87,6 @@ #if HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_SOCKET_H -# include -#endif #if HAVE_NET_IF_H # include #endif @@ -113,7 +107,6 @@ /* This is for OpenBSD and NetBSD. */ #elif HAVE_LIBKVM_NLIST # include -# include # include # include # include diff --git a/src/teamspeak2.c b/src/teamspeak2.c index 201e1828..56e8d14e 100644 --- a/src/teamspeak2.c +++ b/src/teamspeak2.c @@ -28,7 +28,6 @@ #include #include #include -#include #include /* diff --git a/src/testing.h b/src/testing.h index 84a12429..0c415e48 100644 --- a/src/testing.h +++ b/src/testing.h @@ -24,6 +24,8 @@ * Florian octo Forster */ +#include + static int fail_count__ = 0; static int check_count__ = 0; @@ -50,36 +52,50 @@ static int check_count__ = 0; } while (0) #define OK(cond) OK1(cond, #cond) -#define STREQ(expect, actual) do { \ +#define EXPECT_EQ_STR(expect, actual) do { \ if (strcmp (expect, actual) != 0) { \ - printf ("not ok %i - %s incorrect: expected \"%s\", got \"%s\"\n", \ - ++check_count__, #actual, expect, actual); \ + printf ("not ok %i - %s = \"%s\", want \"%s\"\n", \ + ++check_count__, #actual, actual, expect); \ + return (-1); \ + } \ + printf ("ok %i - %s = \"%s\"\n", ++check_count__, #actual, actual); \ +} while (0) + +#define EXPECT_EQ_INT(expect, actual) do { \ + int want__ = (int) expect; \ + int got__ = (int) actual; \ + if (got__ != want__) { \ + printf ("not ok %i - %s = %d, want %d\n", \ + ++check_count__, #actual, got__, want__); \ return (-1); \ } \ - printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \ + printf ("ok %i - %s = %d\n", ++check_count__, #actual, got__); \ } while (0) -#define EXPECT_INTEQ(expect, actual) do { \ - if ((expect) != (actual)) {\ - printf ("not ok %i - %s incorrect: expected %d, got %d\n", \ - ++check_count__, #actual, expect, actual); \ +#define EXPECT_EQ_UINT64(expect, actual) do { \ + uint64_t want__ = (uint64_t) expect; \ + uint64_t got__ = (uint64_t) actual; \ + if (got__ != want__) { \ + printf ("not ok %i - %s = %"PRIu64", want %"PRIu64"\n", \ + ++check_count__, #actual, got__, want__); \ return (-1); \ } \ - printf ("ok %i - %s evaluates to %d\n", ++check_count__, #actual, expect); \ + printf ("ok %i - %s = %"PRIu64"\n", ++check_count__, #actual, got__); \ } while (0) -#define DBLEQ(expect, actual) do { \ - double e = (expect); double a = (actual); \ - if (isnan (e) && !isnan (a)) { \ - printf ("not ok %i - %s incorrect: expected %.15g, got %.15g\n", \ - ++check_count__, #actual, e, a); \ +#define EXPECT_EQ_DOUBLE(expect, actual) do { \ + double want__ = (double) expect; \ + double got__ = (double) actual; \ + if (isnan (want__) && !isnan (got__)) { \ + printf ("not ok %i - %s = %.15g, want %.15g\n", \ + ++check_count__, #actual, got__, want__); \ return (-1); \ - } else if (!isnan (e) && (((e-a) < -DBL_PRECISION) || ((e-a) > DBL_PRECISION))) { \ - printf ("not ok %i - %s incorrect: expected %.15g, got %.15g\n", \ - ++check_count__, #actual, e, a); \ + } else if (!isnan (want__) && (((want__-got__) < -DBL_PRECISION) || ((want__-got__) > DBL_PRECISION))) { \ + printf ("not ok %i - %s = %.15g, want %.15g\n", \ + ++check_count__, #actual, got__, want__); \ return (-1); \ } \ - printf ("ok %i - %s evaluates to %.15g\n", ++check_count__, #actual, e); \ + printf ("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \ } while (0) #define CHECK_NOT_NULL(expr) do { \ diff --git a/src/types.db b/src/types.db index 38fb546c..5847218a 100644 --- a/src/types.db +++ b/src/types.db @@ -14,7 +14,8 @@ cache_eviction value:DERIVE:0:U cache_operation value:DERIVE:0:U cache_ratio value:GAUGE:0:100 cache_result value:DERIVE:0:U -cache_size value:GAUGE:0:U +cache_size value:GAUGE:0:1125899906842623 +capacity value:GAUGE:0:U ceph_bytes value:GAUGE:U:U ceph_latency value:GAUGE:U:U ceph_rate value:DERIVE:0:U diff --git a/src/unixsock.c b/src/unixsock.c index 664c0184..e6c75a65 100644 --- a/src/unixsock.c +++ b/src/unixsock.c @@ -39,7 +39,6 @@ /* Folks without pthread will need to disable this plugin. */ #include -#include #include #include diff --git a/src/utils_dns.c b/src/utils_dns.c index f83fc02c..4c763a14 100644 --- a/src/utils_dns.c +++ b/src/utils_dns.c @@ -40,10 +40,6 @@ #include "plugin.h" #include "common.h" -#if HAVE_SYS_SOCKET_H -# include -#endif - #if HAVE_NET_IF_ARP_H # include #endif diff --git a/src/utils_ignorelist.c b/src/utils_ignorelist.c deleted file mode 100644 index a8ca7dbb..00000000 --- a/src/utils_ignorelist.c +++ /dev/null @@ -1,338 +0,0 @@ -/** - * collectd - src/utils_ignorelist.c - * Copyright (C) 2006 Lubos Stanek - * Copyright (C) 2008 Florian Forster - * - * This program is free software; you can redistribute it and/ - * or modify it under the terms of the GNU General Public Li- - * cence as published by the Free Software Foundation; either - * version 2 of the Licence, or any later version. - * - * This program is distributed in the hope that it will be use- - * ful, but WITHOUT ANY WARRANTY; without even the implied war- - * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public Licence for more details. - * - * You should have received a copy of the GNU General Public - * Licence along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * Authors: - * Lubos Stanek - * Florian Forster - **/ -/** - * ignorelist handles plugin's list of configured collectable - * entries with global ignore action - **/ -/** - * Usage: - * - * Define plugin's global pointer variable of type ignorelist_t: - * ignorelist_t *myconfig_ignore; - * If you know the state of the global ignore (IgnoreSelected), - * allocate the variable with: - * myconfig_ignore = ignorelist_create (YourKnownIgnore); - * If you do not know the state of the global ignore, - * initialize the global variable and set the ignore flag later: - * myconfig_ignore = ignorelist_init (); - * Append single entries in your cf_register'ed callback function: - * ignorelist_add (myconfig_ignore, newentry); - * When you hit the IgnoreSelected config option, - * offer it to the list: - * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore); - * That is all for the ignorelist initialization. - * Later during read and write (plugin's registered functions) get - * the information whether this entry would be collected or not: - * if (ignorelist_match (myconfig_ignore, thisentry)) - * return; - **/ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include "common.h" -#include "plugin.h" -#include "utils_ignorelist.h" - -/* - * private prototypes - */ -struct ignorelist_item_s -{ -#if HAVE_REGEX_H - regex_t *rmatch; /* regular expression entry identification */ -#endif - char *smatch; /* string entry identification */ - struct ignorelist_item_s *next; -}; -typedef struct ignorelist_item_s ignorelist_item_t; - -struct ignorelist_s -{ - int ignore; /* ignore entries */ - ignorelist_item_t *head; /* pointer to the first entry */ -}; - -/* *** *** *** ********************************************* *** *** *** */ -/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */ -/* *** *** *** ********************************************* *** *** *** */ - -static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item) -{ - assert ((il != NULL) && (item != NULL)); - - item->next = il->head; - il->head = item; -} - -#if HAVE_REGEX_H -static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) -{ - regex_t *re; - ignorelist_item_t *entry; - int status; - - re = malloc (sizeof (*re)); - if (re == NULL) - { - ERROR ("utils_ignorelist: malloc failed"); - return (ENOMEM); - } - memset (re, 0, sizeof (*re)); - - status = regcomp (re, re_str, REG_EXTENDED); - if (status != 0) - { - char errbuf[1024] = ""; - regerror (status, re, errbuf, sizeof (errbuf)); - ERROR ("utils_ignorelist: regcomp failed: %s", errbuf); - regfree (re); - sfree (re); - return (status); - } - - entry = malloc (sizeof (*entry)); - if (entry == NULL) - { - ERROR ("utils_ignorelist: malloc failed"); - regfree (re); - sfree (re); - return (ENOMEM); - } - memset (entry, 0, sizeof (*entry)); - entry->rmatch = re; - - ignorelist_append (il, entry); - return (0); -} /* int ignorelist_append_regex */ -#endif - -static int ignorelist_append_string(ignorelist_t *il, const char *entry) -{ - ignorelist_item_t *new; - - /* create new entry */ - if ((new = malloc(sizeof(ignorelist_item_t))) == NULL ) - { - ERROR ("cannot allocate new entry"); - return (1); - } - memset (new, '\0', sizeof(ignorelist_item_t)); - new->smatch = sstrdup(entry); - - /* append new entry */ - ignorelist_append (il, new); - - return (0); -} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */ - -#if HAVE_REGEX_H -/* - * check list for entry regex match - * return 1 if found - */ -static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) -{ - assert ((item != NULL) && (item->rmatch != NULL) - && (entry != NULL) && (strlen (entry) > 0)); - - /* match regex */ - if (regexec (item->rmatch, entry, 0, NULL, 0) == 0) - return (1); - - return (0); -} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */ -#endif - -/* - * check list for entry string match - * return 1 if found - */ -static int ignorelist_match_string (ignorelist_item_t *item, const char *entry) -{ - assert ((item != NULL) && (item->smatch != NULL) - && (entry != NULL) && (strlen (entry) > 0)); - - if (strcmp (entry, item->smatch) == 0) - return (1); - - return (0); -} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */ - - -/* *** *** *** ******************************************** *** *** *** */ -/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ -/* *** *** *** ******************************************** *** *** *** */ - -/* - * create the ignorelist_t with known ignore state - * return pointer to ignorelist_t - */ -ignorelist_t *ignorelist_create (int invert) -{ - ignorelist_t *il; - - /* smalloc exits if it failes */ - il = (ignorelist_t *) smalloc (sizeof (ignorelist_t)); - memset (il, '\0', sizeof (ignorelist_t)); - - /* - * ->ignore == 0 => collect - * ->ignore == 1 => ignore - */ - il->ignore = invert ? 0 : 1; - - return (il); -} /* ignorelist_t *ignorelist_create (int ignore) */ - -/* - * free memory used by ignorelist_t - */ -void ignorelist_free (ignorelist_t *il) -{ - ignorelist_item_t *this; - ignorelist_item_t *next; - - if (il == NULL) - return; - - for (this = il->head; this != NULL; this = next) - { - next = this->next; -#if HAVE_REGEX_H - if (this->rmatch != NULL) - { - regfree (this->rmatch); - sfree (this->rmatch); - this->rmatch = NULL; - } -#endif - if (this->smatch != NULL) - { - sfree (this->smatch); - this->smatch = NULL; - } - sfree (this); - } - - sfree (il); - il = NULL; -} /* void ignorelist_destroy (ignorelist_t *il) */ - -/* - * set ignore state of the ignorelist_t - */ -void ignorelist_set_invert (ignorelist_t *il, int invert) -{ - if (il == NULL) - { - DEBUG("ignore call with ignorelist_t == NULL"); - return; - } - - il->ignore = invert ? 0 : 1; -} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */ - -/* - * append entry into ignorelist_t - * return 0 for success - */ -int ignorelist_add (ignorelist_t *il, const char *entry) -{ - size_t entry_len; - - if (il == NULL) - { - DEBUG ("add called with ignorelist_t == NULL"); - return (1); - } - - entry_len = strlen (entry); - - /* append nothing */ - if (entry_len == 0) - { - DEBUG("not appending: empty entry"); - return (1); - } - -#if HAVE_REGEX_H - /* regex string is enclosed in "/.../" */ - if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/') - { - char *entry_copy; - size_t entry_copy_size; - int status; - - /* We need to copy `entry' since it's const */ - entry_copy_size = entry_len - 1; - entry_copy = smalloc (entry_copy_size); - sstrncpy (entry_copy, entry + 1, entry_copy_size); - - status = ignorelist_append_regex(il, entry_copy); - sfree (entry_copy); - return status; - } -#endif - - return ignorelist_append_string(il, entry); -} /* int ignorelist_add (ignorelist_t *il, const char *entry) */ - -/* - * check list for entry - * return 1 for ignored entry - */ -int ignorelist_match (ignorelist_t *il, const char *entry) -{ - ignorelist_item_t *traverse; - - /* if no entries, collect all */ - if ((il == NULL) || (il->head == NULL)) - return (0); - - if ((entry == NULL) || (strlen (entry) == 0)) - return (0); - - /* traverse list and check entries */ - for (traverse = il->head; traverse != NULL; traverse = traverse->next) - { -#if HAVE_REGEX_H - if (traverse->rmatch != NULL) - { - if (ignorelist_match_regex (traverse, entry)) - return (il->ignore); - } - else -#endif - { - if (ignorelist_match_string (traverse, entry)) - return (il->ignore); - } - } /* for traverse */ - - return (1 - il->ignore); -} /* int ignorelist_match (ignorelist_t *il, const char *entry) */ - diff --git a/src/utils_ignorelist.h b/src/utils_ignorelist.h deleted file mode 100644 index b47b55ad..00000000 --- a/src/utils_ignorelist.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * collectd - src/utils_ignorelist.h - * Copyright (C) 2006 Lubos Stanek - * - * This program is free software; you can redistribute it and/ - * or modify it under the terms of the GNU General Public Li- - * cence as published by the Free Software Foundation; either - * version 2 of the Licence, or any later version. - * - * This program is distributed in the hope that it will be use- - * ful, but WITHOUT ANY WARRANTY; without even the implied war- - * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public Licence for more details. - * - * You should have received a copy of the GNU General Public - * Licence along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * Authors: - * Lubos Stanek - **/ -/** - * ignorelist handles plugin's list of configured collectable - * entries with global ignore action - **/ - -#ifndef UTILS_IGNORELIST_H -#define UTILS_IGNORELIST_H 1 - -#include "collectd.h" - -#if HAVE_REGEX_H -# include -#endif - -/* public prototypes */ - -struct ignorelist_s; -typedef struct ignorelist_s ignorelist_t; - -/* - * create the ignorelist_t with known ignore state - * return pointer to ignorelist_t - */ -ignorelist_t *ignorelist_create (int invert); - -/* - * free memory used by ignorelist_t - */ -void ignorelist_free (ignorelist_t *il); - -/* - * set ignore state of the ignorelist_t - */ -void ignorelist_set_invert (ignorelist_t *il, int invert); - -/* - * append entry to ignorelist_t - * returns zero on success, non-zero upon failure. - */ -int ignorelist_add (ignorelist_t *il, const char *entry); - -/* - * check list for entry - * return 1 for ignored entry - */ -int ignorelist_match (ignorelist_t *il, const char *entry); - -#endif /* UTILS_IGNORELIST_H */ diff --git a/src/utils_latency_test.c b/src/utils_latency_test.c index b039c546..5769ec95 100644 --- a/src/utils_latency_test.c +++ b/src/utils_latency_test.c @@ -59,10 +59,10 @@ DEF_TEST(simple) i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val)); latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val)); - DBLEQ (cases[i].min, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l))); - DBLEQ (cases[i].max, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l))); - DBLEQ (cases[i].sum, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l))); - DBLEQ (cases[i].avg, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l))); + EXPECT_EQ_DOUBLE (cases[i].min, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l))); + EXPECT_EQ_DOUBLE (cases[i].max, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l))); + EXPECT_EQ_DOUBLE (cases[i].sum, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l))); + EXPECT_EQ_DOUBLE (cases[i].avg, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l))); } latency_counter_destroy (l); @@ -80,15 +80,15 @@ DEF_TEST(percentile) latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1)); } - DBLEQ ( 1.0, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l))); - DBLEQ (100.0, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l))); - DBLEQ (100.0 * 101.0 / 2.0, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l))); - DBLEQ ( 50.5, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l))); + EXPECT_EQ_DOUBLE ( 1.0, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l))); + EXPECT_EQ_DOUBLE (100.0, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l))); + EXPECT_EQ_DOUBLE (100.0 * 101.0 / 2.0, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l))); + EXPECT_EQ_DOUBLE ( 50.5, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l))); - DBLEQ (50.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 50.0))); - DBLEQ (80.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 80.0))); - DBLEQ (95.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 95.0))); - DBLEQ (99.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 99.0))); + EXPECT_EQ_DOUBLE (50.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 50.0))); + EXPECT_EQ_DOUBLE (80.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 80.0))); + EXPECT_EQ_DOUBLE (95.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 95.0))); + EXPECT_EQ_DOUBLE (99.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 99.0))); CHECK_ZERO (latency_counter_get_percentile (l, -1.0)); CHECK_ZERO (latency_counter_get_percentile (l, 101.0)); diff --git a/src/utils_mount.c b/src/utils_mount.c index b63a81ad..afeb39e1 100644 --- a/src/utils_mount.c +++ b/src/utils_mount.c @@ -571,6 +571,64 @@ static cu_mount_t *cu_mount_gen_getmntent (void) #warn "This version of `getmntent' hat not yet been implemented!" /* #endif HAVE_SEQ_GETMNTENT */ +#elif HAVE_GETMNTENT_R +static cu_mount_t *cu_mount_getmntent (void) +{ + FILE *fp; + struct mntent me; + char mntbuf[1024]; + + cu_mount_t *first = NULL; + cu_mount_t *last = NULL; + cu_mount_t *new = NULL; + + DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB); + + if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL) + { + char errbuf[1024]; + ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB, + sstrerror (errno, errbuf, sizeof (errbuf))); + return (NULL); + } + + while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) )) + { + if ((new = malloc (sizeof (cu_mount_t))) == NULL) + break; + memset (new, '\0', sizeof (cu_mount_t)); + + /* Copy values from `struct mntent *' */ + new->dir = sstrdup (me.mnt_dir); + new->spec_device = sstrdup (me.mnt_fsname); + new->type = sstrdup (me.mnt_type); + new->options = sstrdup (me.mnt_opts); + new->device = get_device_name (new->options); + new->next = NULL; + + DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}", + new->dir, new->spec_device, new->type, new->options, new->device); + + /* Append to list */ + if (first == NULL) + { + first = new; + last = new; + } + else + { + last->next = new; + last = new; + } + } + + endmntent (fp); + + DEBUG ("utils_mount: return (0x%p)", (void *) first); + + return (first); +} /* HAVE_GETMNTENT_R */ + #elif HAVE_ONE_GETMNTENT static cu_mount_t *cu_mount_getmntent (void) { diff --git a/src/utils_mount_test.c b/src/utils_mount_test.c index c5ffbfbc..b4cb4321 100644 --- a/src/utils_mount_test.c +++ b/src/utils_mount_test.c @@ -28,6 +28,10 @@ #include "collectd.h" #include "utils_mount.h" +#if HAVE_LIBKSTAT +kstat_ctl_t *kc; +#endif /* HAVE_LIBKSTAT */ + DEF_TEST(cu_mount_checkoption) { char line_opts[] = "foo=one,bar=two,qux=three"; @@ -77,14 +81,14 @@ DEF_TEST(cu_mount_getoptionvalue) char line_opts[] = "foo=one,bar=two,qux=three"; char line_bool[] = "one,two,three"; - STREQ ("one", cu_mount_getoptionvalue (line_opts, "foo=")); - STREQ ("two", cu_mount_getoptionvalue (line_opts, "bar=")); - STREQ ("three", cu_mount_getoptionvalue (line_opts, "qux=")); + EXPECT_EQ_STR ("one", cu_mount_getoptionvalue (line_opts, "foo=")); + EXPECT_EQ_STR ("two", cu_mount_getoptionvalue (line_opts, "bar=")); + EXPECT_EQ_STR ("three", cu_mount_getoptionvalue (line_opts, "qux=")); OK (NULL == cu_mount_getoptionvalue (line_opts, "unknown=")); - STREQ ("", cu_mount_getoptionvalue (line_bool, "one")); - STREQ ("", cu_mount_getoptionvalue (line_bool, "two")); - STREQ ("", cu_mount_getoptionvalue (line_bool, "three")); + EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "one")); + EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "two")); + EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "three")); OK (NULL == cu_mount_getoptionvalue (line_bool, "four")); return (0); diff --git a/src/utils_vl_lookup.c b/src/utils_vl_lookup.c index 75c02061..f85910e1 100644 --- a/src/utils_vl_lookup.c +++ b/src/utils_vl_lookup.c @@ -33,6 +33,10 @@ #include "utils_vl_lookup.h" #include "utils_avltree.h" +#if HAVE_LIBKSTAT +kstat_ctl_t *kc; +#endif /* HAVE_LIBKSTAT */ + #if BUILD_TEST # define sstrncpy strncpy # define plugin_log(s, ...) do { \ @@ -304,9 +308,10 @@ static int lu_handle_user_class (lookup_t *obj, /* {{{ */ { /* call lookup_class_callback_t() and insert into the list of user objects. */ user_obj = lu_create_user_obj (obj, ds, vl, user_class); - pthread_mutex_unlock (&user_class->lock); - if (user_obj == NULL) + if (user_obj == NULL) { + pthread_mutex_unlock (&user_class->lock); return (-1); + } } pthread_mutex_unlock (&user_class->lock); diff --git a/src/virt.c b/src/virt.c index dff8f71d..6824b134 100644 --- a/src/virt.c +++ b/src/virt.c @@ -128,7 +128,7 @@ enum plginst_field { }; static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] = - { plginst_name }; + { plginst_none }; /* InterfaceFormat. */ enum if_field { @@ -417,8 +417,8 @@ lv_config (const char *key, const char *value) else if (strcasecmp (fields[i], "uuid") == 0) hostname_format[i] = hf_uuid; else { - sfree (value_copy); ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]); + sfree (value_copy); return -1; } } @@ -449,13 +449,16 @@ lv_config (const char *key, const char *value) } for (i = 0; i < n; ++i) { - if (strcasecmp (fields[i], "name") == 0) + if (strcasecmp (fields[i], "none") == 0) { + plugin_instance_format[i] = plginst_none; + break; + } else if (strcasecmp (fields[i], "name") == 0) plugin_instance_format[i] = plginst_name; else if (strcasecmp (fields[i], "uuid") == 0) plugin_instance_format[i] = plginst_uuid; else { + ERROR (PLUGIN_NAME " plugin: unknown PluginInstanceFormat field: %s", fields[i]); sfree (value_copy); - ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]); return -1; } } diff --git a/src/write_graphite.c b/src/write_graphite.c index f82f852f..7fc9eb9f 100644 --- a/src/write_graphite.c +++ b/src/write_graphite.c @@ -54,7 +54,6 @@ /* Folks without pthread will need to disable this plugin. */ #include -#include #include #define WG_DEFAULT_NODE "localhost" diff --git a/src/write_http.c b/src/write_http.c index ed596bbf..868bca84 100644 --- a/src/write_http.c +++ b/src/write_http.c @@ -59,6 +59,7 @@ struct wh_callback_s char *clientkeypass; long sslversion; _Bool store_rates; + _Bool log_http_error; int low_speed_limit; time_t low_speed_time; int timeout; @@ -80,6 +81,19 @@ struct wh_callback_s }; typedef struct wh_callback_s wh_callback_t; +static void wh_log_http_error (wh_callback_t *cb) +{ + if (!cb->log_http_error) + return; + + long http_code = 0; + + curl_easy_getinfo (cb->curl, CURLINFO_RESPONSE_CODE, &http_code); + + if (http_code != 200) + INFO ("write_http plugin: HTTP Error code: %lu", http_code); +} + static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */ { memset (cb->send_buffer, 0, cb->send_buffer_size); @@ -101,6 +115,9 @@ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */ curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer); status = curl_easy_perform (cb->curl); + + wh_log_http_error (cb); + if (status != CURLE_OK) { ERROR ("write_http plugin: curl_easy_perform failed with " @@ -538,6 +555,7 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */ cb->sslversion = CURL_SSLVERSION_DEFAULT; cb->low_speed_limit = 0; cb->timeout = 0; + cb->log_http_error = 0; pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); @@ -609,6 +627,8 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */ cf_util_get_int (child, &cb->low_speed_limit); else if (strcasecmp ("Timeout", child->key) == 0) cf_util_get_int (child, &cb->timeout); + else if (strcasecmp ("LogHttpError", child->key) == 0) + cf_util_get_boolean (child, &cb->log_http_error); else { ERROR ("write_http plugin: Invalid configuration " diff --git a/src/write_log.c b/src/write_log.c index e37aae9f..ebf0e124 100644 --- a/src/write_log.c +++ b/src/write_log.c @@ -35,7 +35,6 @@ /* Folks without pthread will need to disable this plugin. */ #include -#include #include #define WL_BUF_SIZE 8192 diff --git a/src/write_redis.c b/src/write_redis.c index 7ba476c9..1eb082fb 100644 --- a/src/write_redis.c +++ b/src/write_redis.c @@ -46,6 +46,8 @@ struct wr_node_s struct timeval timeout; char *prefix; int database; + int max_set_size; + _Bool store_rates; redisContext *conn; pthread_mutex_t lock; @@ -68,7 +70,6 @@ static int wr_write (const data_set_t *ds, /* {{{ */ char *value_ptr; int status; redisReply *rr; - int i; status = FORMAT_VL (ident, sizeof (ident), vl); if (status != 0) @@ -81,40 +82,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */ memset (value, 0, sizeof (value)); value_size = sizeof (value); value_ptr = &value[0]; - -#define APPEND(...) do { \ - status = snprintf (value_ptr, value_size, __VA_ARGS__); \ - if (((size_t) status) > value_size) \ - { \ - value_ptr += value_size; \ - value_size = 0; \ - } \ - else \ - { \ - value_ptr += status; \ - value_size -= status; \ - } \ -} while (0) - - APPEND ("%s:", time); - - for (i = 0; i < ds->ds_num; i++) - { - if (ds->ds[i].type == DS_TYPE_COUNTER) - APPEND ("%llu", vl->values[i].counter); - else if (ds->ds[i].type == DS_TYPE_GAUGE) - APPEND (GAUGE_FORMAT, vl->values[i].gauge); - else if (ds->ds[i].type == DS_TYPE_DERIVE) - APPEND ("%"PRIi64, vl->values[i].derive); - else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) - APPEND ("%"PRIu64, vl->values[i].absolute); - else - assert (23 == 42); - } - -#undef APPEND - - status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0); + status = format_values (value_ptr, value_size, ds, vl, node->store_rates); pthread_mutex_lock (&node->lock); if (status != 0) return (status); @@ -139,7 +107,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */ pthread_mutex_unlock (&node->lock); return (-1); } - + rr = redisCommand(node->conn, "SELECT %d", node->database); if (rr == NULL) WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr); @@ -153,6 +121,15 @@ static int wr_write (const data_set_t *ds, /* {{{ */ else freeReplyObject (rr); + if (node->max_set_size >= 0) + { + rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1); + if (rr == NULL) + WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr); + else + freeReplyObject (rr); + } + /* TODO(octo): This is more overhead than necessary. Use the cache and * metadata to determine if it is a new metric and call SADD only once for * each metric. */ @@ -204,6 +181,8 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */ node->conn = NULL; node->prefix = NULL; node->database = 0; + node->max_set_size = -1; + node->store_rates = 1; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); @@ -238,6 +217,12 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */ else if (strcasecmp ("Database", child->key) == 0) { status = cf_util_get_int (child, &node->database); } + else if (strcasecmp ("MaxSetSize", child->key) == 0) { + status = cf_util_get_int (child, &node->max_set_size); + } + else if (strcasecmp ("StoreRates", child->key) == 0) { + status = cf_util_get_boolean (child, &node->store_rates); + } else WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".", child->key); diff --git a/src/write_riemann.c b/src/write_riemann.c index 26fa3f45..73d202c4 100644 --- a/src/write_riemann.c +++ b/src/write_riemann.c @@ -33,7 +33,6 @@ #include "utils_cache.h" #include "riemann.pb-c.h" -#include #include #include #include diff --git a/src/write_sensu.c b/src/write_sensu.c index 791acb30..67c04969 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -29,7 +29,6 @@ #include "common.h" #include "configfile.h" #include "utils_cache.h" -#include #include #include #include diff --git a/src/write_tsdb.c b/src/write_tsdb.c index 2c39ec16..4a626144 100644 --- a/src/write_tsdb.c +++ b/src/write_tsdb.c @@ -49,7 +49,6 @@ #include "utils_cache.h" #include -#include #include #ifndef WT_DEFAULT_NODE diff --git a/src/zfs_arc.c b/src/zfs_arc.c index f0d23239..dd633d5f 100644 --- a/src/zfs_arc.c +++ b/src/zfs_arc.c @@ -251,6 +251,9 @@ static int za_read (void) /* Sizes */ za_read_gauge (ksp, "size", "cache_size", "arc"); + za_read_gauge (ksp, "c", "cache_size", "c"); + za_read_gauge (ksp, "c_min", "cache_size", "c_min"); + za_read_gauge (ksp, "c_max", "cache_size", "c_max"); /* The "l2_size" value has disappeared from Solaris some time in * early 2013, and has only reappeared recently in Solaris 11.2. diff --git a/src/zookeeper.c b/src/zookeeper.c index 63ee6c90..abdbf20f 100644 --- a/src/zookeeper.c +++ b/src/zookeeper.c @@ -29,7 +29,6 @@ #include "plugin.h" #include -#include #include #include #include diff --git a/version-gen.sh b/version-gen.sh index b09be8e7..493a6ebf 100755 --- a/version-gen.sh +++ b/version-gen.sh @@ -2,12 +2,12 @@ DEFAULT_VERSION="5.5.0.git" -VERSION="`git describe 2> /dev/null | grep collectd | sed -e 's/^collectd-//'`" +if [ -d .git ]; then + VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`" +fi if test -z "$VERSION"; then VERSION="$DEFAULT_VERSION" fi -VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`" - printf "%s" "$VERSION"