From: Florian Forster Date: Mon, 18 Aug 2014 07:50:34 +0000 (+0200) Subject: Merge branch 'collectd-5.4' X-Git-Tag: collectd-5.5.0~222 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=103f05e098865196fc5f28df51e99b64fd6b5202;hp=-c Merge branch 'collectd-5.4' Conflicts: configure.ac src/curl_json.c src/lvm.c src/write_riemann.c --- 103f05e098865196fc5f28df51e99b64fd6b5202 diff --combined ChangeLog index 8cd1579e,a2c46f00..8112afac --- a/ChangeLog +++ b/ChangeLog @@@ -1,3 -1,27 +1,27 @@@ + 2014-01-26, Version 5.4.1 + * amqp plugin: Add support for RabbitMQ 0.4.x to avoid compiler + warnings. Thanks to Sebastian Harl for implementing this. + * apache / network plugins: Improved initialization order hopefully + resolved gcrypt initialization problems. + * aquaero plugin: The type used to submit fan utilization was fixed. + Thanks to Alex Deymo for the patch. + * cgroups plugin: A small memory leak was fixed. Checking the existence + of a mount option without a value was fixed. More permissive parsing + of the cpuacct.stats file fixes support for some versions of Linux. + Thanks to Marc Fournier for bug reports and patches. + * curl plugin: Fix blocks without an instance. Thanks to + Alexander Golovko for reporting and Sebastian Harl for fixing this. + * curl_json plugin: Potentially invalid memory access has been + sanitized. Thanks to Jim Radford for his patch. + * interface plugin: Fix behavior under FreeBSD 10: Reporting of + per-address statistics caused duplicate updates to the same metric. + Thanks to demon / @trtrmitya for the patch. + * write_graphite plugin: Use TCP to connect to Graphite by default. The + default changed from TCP to UDP between 5.3.1 and 5.4.0, which is a + regression. Thanks to Marc Fournier for fixing this. Reconnect + behavior was improved. Thanks to Michael Hart for his patch. + * zfs_arc plugin: Collect "allocated" and "stolen" on FreeBSD only. + 2013-08-18, Version 5.4.0 * collectd: The "LoadPlugin" config option no longer attempts to load plugins twice. If more than one "LoadPlugin" statement or block is @@@ -1632,7 -1656,7 +1656,7 @@@ 2008-07-15, Version 4.4.2 * build system: Use pkg-config to detect the upsclient library. - * collectd: Try even harder to determine the endianess of the + * collectd: Try even harder to determine the endianness of the architecture collectd is being built on. * disk plugin: Fix for Linux 2.4: A wrong field was used as the name of disks. @@@ -1697,7 -1721,7 +1721,7 @@@ 2008-08-30, Version 4.3.4 * Build system: Improved detection of and linking with the statgrab library. - * collectd: Portability fixes, especially to determine endianess more + * collectd: Portability fixes, especially to determine endianness more reliable. * Various plugins: Fix format strings. * disk plugin: A fix for giving disks under Linux 2.4 the right names diff --combined configure.ac index 92fd8778,d38cbb5d..0df56782 --- a/configure.ac +++ b/configure.ac @@@ -404,6 -404,18 +404,18 @@@ AC_CHECK_HEADERS(linux/if.h, [], [] # include #endif ]) + AC_CHECK_HEADERS(linux/inet_diag.h, [], [], + [ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + #if HAVE_LINUX_INET_DIAG_H + # include + #endif + ]) AC_CHECK_HEADERS(linux/netdevice.h, [], [], [ #if HAVE_SYS_TYPES_H @@@ -981,7 -993,7 +993,7 @@@ if test "x$fp_layout_type" = "xunknown" uint8_t c[8]; double d; - d = 8.642135e130; + d = 8.642135e130; memcpy ((void *) &i0, (void *) &d, 8); i1 = i0; @@@ -1036,7 -1048,7 +1048,7 @@@ if test "x$fp_layout_type" = "xunknown" uint8_t c[8]; double d; - d = 8.642135e130; + d = 8.642135e130; memcpy ((void *) &i0, (void *) &d, 8); i1 = endianflip (i0); @@@ -1085,7 -1097,7 +1097,7 @@@ if test "x$fp_layout_type" = "xunknown" uint8_t c[8]; double d; - d = 8.642135e130; + d = 8.642135e130; memcpy ((void *) &i0, (void *) &d, 8); i1 = intswap (i0); @@@ -1122,17 -1134,6 +1134,17 @@@ els AC_MSG_ERROR([Didn't find out how doubles are stored in memory. Sorry.]) fi; fi; fi +# --with-useragent {{{ +AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])], +[ + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + AC_DEFINE_UNQUOTED(COLLECTD_USERAGENT, ["$withval"], [User agent for http requests]) + fi +]) + +# }}} + have_getfsstat="no" AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"]) have_getvfsstat="no" @@@ -1218,10 -1219,9 +1230,9 @@@ if test "x$have_getmntent" = "xgen"; th fi # Check for htonll - AC_MSG_CHECKING([if have htonll defined]) - - have_htonll="no" - AC_LINK_IFELSE([AC_LANG_PROGRAM( + AC_CACHE_CHECK([if have htonll defined], + [c_cv_have_htonll], + AC_LINK_IFELSE([AC_LANG_PROGRAM( [[[ #include #include @@@ -1233,12 -1233,14 +1244,14 @@@ return htonll(0); ]]] )], - [ - have_htonll="yes" - AC_DEFINE(HAVE_HTONLL, 1, [Define if the function htonll exists.]) - ]) - - AC_MSG_RESULT([$have_htonll]) + [c_cv_have_htonll="yes"], + [c_cv_have_htonll="no"] - ) ++ ) + ) + if test "x$c_cv_have_htonll" = "xyes" + then + AC_DEFINE(HAVE_HTONLL, 1, [Define if the function htonll exists.]) + fi # Check for structures AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_opackets, struct if_data.ifi_ierrors], @@@ -1258,6 -1260,13 +1271,13 @@@ AC_CHECK_MEMBERS([struct net_device_sta #include #include ]) + AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states], + [AC_DEFINE(HAVE_STRUCT_LINUX_INET_DIAG_REQ, 1, [Define if struct inet_diag_req exists and is usable.])], + [], + [ + #include + ]) + AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [], [], @@@ -1368,8 -1377,8 +1388,8 @@@ AC_CHECK_LIB(hal,libhal_device_property [with_libhal="no"]) if test "x$with_libhal" = "xyes"; then if test "x$PKG_CONFIG" != "x"; then - BUILD_WITH_LIBHAL_CFLAGS="`pkg-config --cflags hal`" - BUILD_WITH_LIBHAL_LIBS="`pkg-config --libs hal`" + BUILD_WITH_LIBHAL_CFLAGS="`$PKG_CONFIG --cflags hal`" + BUILD_WITH_LIBHAL_LIBS="`$PKG_CONFIG --libs hal`" AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS) AC_SUBST(BUILD_WITH_LIBHAL_LIBS) fi @@@ -1380,7 -1389,7 +1400,7 @@@ collectd additional packages:] AM_CONDITIONAL([BUILD_FREEBSD],[test "x$x$ac_system" = "xFreeBSD"]) -AM_CONDITIONAL([BUILD_AIX],[test "x$x$ac_system" = "xAIX"]) +AM_CONDITIONAL([BUILD_AIX],[test "x$x$ac_system" = "xAIX"]) if test "x$ac_system" = "xAIX" then @@@ -1710,7 -1719,6 +1730,7 @@@ the LDFLAGS="$LDFLAGS $with_libdbi_ldflags" AC_CHECK_LIB(dbi, dbi_initialize, [with_libdbi="yes"], [with_libdbi="no (Symbol 'dbi_initialize' not found)"]) + AC_CHECK_LIB(dbi, dbi_driver_open_r, [with_libdbi_r="yes"], [with_libdbi_r="no"]) CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" @@@ -1723,11 -1731,6 +1743,11 @@@ the AC_SUBST(BUILD_WITH_LIBDBI_CPPFLAGS) AC_SUBST(BUILD_WITH_LIBDBI_LDFLAGS) AC_SUBST(BUILD_WITH_LIBDBI_LIBS) + + if test "x$with_libdbi_r" = "xyes" + then + AC_DEFINE(HAVE_LIBDBI_R, 1, [Define if reentrant dbi facility is present and usable.]) + fi fi AM_CONDITIONAL(BUILD_WITH_LIBDBI, test "x$with_libdbi" = "xyes") # }}} @@@ -1946,7 -1949,10 +1966,7 @@@ AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, te # --with-libiptc {{{ AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])], [ - if test "x$withval" = "xshipped" - then - with_libiptc="own" - else if test "x$withval" = "xyes" + if test "x$withval" = "xyes" then with_libiptc="pkgconfig" else if test "x$withval" = "xno" @@@ -1956,7 -1962,7 +1976,7 @@@ with_libiptc="yes" with_libiptc_cflags="-I$withval/include" with_libiptc_libs="-L$withval/lib" - fi; fi; fi + fi; fi ], [ if test "x$ac_system" = "xLinux" @@@ -2028,6 -2034,28 +2048,6 @@@ f CPPFLAGS="$SAVE_CPPFLAGS" -if test "x$with_libiptc" = "xown" -then - with_libiptc_cflags="" - with_libiptc_libs="" -fi -if test "x$with_libiptc" = "xown" -then - AC_CHECK_HEADERS(linux/netfilter_ipv4/ip_tables.h linux/netfilter_ipv6/ip6_tables.h linux/netfilter/x_tables.h, [], - [ - with_libiptc="no (Linux iptables headers not found)" - ], - [ -#include "$srcdir/src/owniptc/ipt_kernel_headers.h" - ]) -fi -AM_CONDITIONAL(BUILD_WITH_OWN_LIBIPTC, test "x$with_libiptc" = "xown") -if test "x$with_libiptc" = "xown" -then - AC_DEFINE(OWN_LIBIPTC, 1, [Define to 1 if we use the shipped iptc library.]) - with_libiptc="yes" -fi - AM_CONDITIONAL(BUILD_WITH_LIBIPTC, test "x$with_libiptc" = "xyes") if test "x$with_libiptc" = "xyes" then @@@ -2241,7 -2269,7 +2261,7 @@@ the CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags" LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags" - AC_CHECK_LIB(lvm2app, lvm_init, [with_liblvm2app="yes"], [with_liblvm2app="no (Symbol 'lvm_init' not found)"]) + AC_CHECK_LIB(lvm2app, lvm_lv_get_property, [with_liblvm2app="yes"], [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"]) CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" @@@ -2643,15 -2671,6 +2663,15 @@@ return (retval) fi if test "x$with_libmnl" = "xyes" then + AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors], + [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])], + [], + [ + #include + ]) +fi +if test "x$with_libmnl" = "xyes" +then AC_CHECK_LIB(mnl, mnl_nlmsg_get_payload, [with_libmnl="yes"], [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"], @@@ -2775,7 -2794,7 +2795,7 @@@ the else SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $with_snmp_cflags" - + AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]) CPPFLAGS="$SAVE_CPPFLAGS" @@@ -3002,7 -3021,7 +3022,7 @@@ if test "x$with_libowcapi" = "xyes then SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$with_libowcapi_cppflags" - + AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"]) CPPFLAGS="$SAVE_CPPFLAGS" @@@ -3013,7 -3032,7 +3033,7 @@@ the SAVE_CPPFLAGS="$CPPFLAGS" LDFLAGS="$with_libowcapi_libs" CPPFLAGS="$with_libowcapi_cppflags" - + AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"]) LDFLAGS="$SAVE_LDFLAGS" @@@ -3576,61 -3595,43 +3596,96 @@@ f CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes") + + with_amqp_tcp_socket="no" + if test "x$with_librabbitmq" = "xyes" + then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" + LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags" + LIBS="-lrabbitmq" + + AC_CHECK_HEADERS(amqp_tcp_socket.h amqp_socket.h) + AC_CHECK_FUNC(amqp_tcp_socket_new, [with_amqp_tcp_socket="yes"], [with_amqp_tcp_socket="no"]) + if test "x$with_amqp_tcp_socket" = "xyes" + then + AC_DEFINE(HAVE_AMQP_TCP_SOCKET, 1, + [Define if librabbitmq provides the new TCP socket interface.]) + fi + + AC_CHECK_DECLS(amqp_socket_close, + [amqp_socket_close_decl="yes"], [amqp_socket_close_decl="no"], + [[ + #include + #ifdef HAVE_AMQP_TCP_SOCKET_H + # include + #endif + #ifdef HAVE_AMQP_SOCKET_H + # include + #endif + ]]) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" + fi # }}} +# --with-librdkafka {{{ +AC_ARG_WITH(librdkafka, [AS_HELP_STRING([--with-librdkafka@<:@=PREFIX@:>@], [Path to librdkafka.])], +[ + if test "x$withval" = "xno" && test "x$withval" != "xyes" + then + with_librdkafka_cppflags="-I$withval/include" + with_librdkafka_ldflags="-L$withval/lib" + with_librdkafka="yes" + else + with_librdkafka="$withval" + fi +], +[ + with_librdkafka="yes" +]) +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" + +if test "x$with_librdkafka" = "xyes" +then + AC_CHECK_HEADERS(librdkafka/rdkafka.h, [with_librdkafka="yes"], [with_librdkafka="no (librdkafka/rdkafka.h not found)"]) +fi + +if test "x$with_librdkafka" = "xyes" +then + AC_CHECK_LIB(rdkafka, rd_kafka_new, [with_librdkafka="yes"], [with_librdkafka="no (Symbol 'rd_kafka_new' not found)"]) + AC_CHECK_LIB(rdkafka, rd_kafka_conf_set_log_cb, [with_librdkafka_log_cb="yes"], [with_librdkafka_log_cb="no"]) + AC_CHECK_LIB(rdkafka, rd_kafka_conf_set_logger, [with_librdkafka_logger="yes"], [with_librdkafka_logger="no"]) +fi +if test "x$with_librdkafka" = "xyes" +then + BUILD_WITH_LIBRDKAFKA_CPPFLAGS="$with_librdkafka_cppflags" + BUILD_WITH_LIBRDKAFKA_LDFLAGS="$with_librdkafka_ldflags" + BUILD_WITH_LIBRDKAFKA_LIBS="-lrdkafka" + AC_SUBST(BUILD_WITH_LIBRDKAFKA_CPPFLAGS) + AC_SUBST(BUILD_WITH_LIBRDKAFKA_LDFLAGS) + AC_SUBST(BUILD_WITH_LIBRDKAFKA_LIBS) + AC_DEFINE(HAVE_LIBRDKAFKA, 1, [Define if librdkafka is present and usable.]) + if test "x$with_librdkafka_log_cb" = "xyes" + then + AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.]) + fi + if test "x$with_librdkafka_logger" = "xyes" + then + AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.]) + fi +fi +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" +AM_CONDITIONAL(BUILD_WITH_LIBRDKAFKA, test "x$with_librdkafka" = "xyes") + +# }}} + # --with-librouteros {{{ AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])], [ @@@ -3844,18 -3845,20 +3899,20 @@@ AC_ARG_WITH(libsigrok, [AS_HELP_STRING( with_libsigrok_ldflags="-L$withval/lib" fi fi - ],[]) + ],[with_libsigrok="yes"]) # libsigrok has a glib dependency if test "x$with_libsigrok" = "xyes" then - if test -z "m4_ifdef([AM_PATH_GLIB_2_0], [yes], [])" - then - with_libsigrok="no (glib not available)" - else - AM_PATH_GLIB_2_0([2.28.0], - [with_libsigrok_cflags="$with_libsigrok_cflags $GLIB_CFLAGS"; with_libsigrok_ldflags="$with_libsigrok_ldflags $GLIB_LIBS"]) - fi + m4_ifdef([AM_PATH_GLIB_2_0], + [ + AM_PATH_GLIB_2_0([2.28.0], + [with_libsigrok_cflags="$with_libsigrok_cflags $GLIB_CFLAGS"; with_libsigrok_ldflags="$with_libsigrok_ldflags $GLIB_LIBS"]) + ], + [ + with_libsigrok="no (glib not available)" + ] + ) fi # libsigrok headers @@@ -4039,8 -4042,8 +4096,8 @@@ the if $PKG_CONFIG --exists tokyotyrant then with_libtokyotyrant_cppflags="$with_libtokyotyrant_cppflags `$PKG_CONFIG --cflags tokyotyrant`" - with_libtokyotyrant_ldflags="$with_libtokyotyrant_ldflags `pkg-config --libs-only-L tokyotyrant`" - with_libtokyotyrant_libs="$with_libtokyotyrant_libs `pkg-config --libs-only-l tokyotyrant`" + with_libtokyotyrant_ldflags="$with_libtokyotyrant_ldflags `$PKG_CONFIG --libs-only-L tokyotyrant`" + with_libtokyotyrant_libs="$with_libtokyotyrant_libs `$PKG_CONFIG --libs-only-l tokyotyrant`" fi fi @@@ -4073,7 -4076,7 +4130,7 @@@ CPPFLAGS="$SAVE_CPPFLAGS LDFLAGS="$SAVE_LDFLAGS" if test "x$with_libtokyotyrant" = "xyes" -then +then BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS="$with_libtokyotyrant_cppflags" BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS="$with_libtokyotyrant_ldflags" BUILD_WITH_LIBTOKYOTYRANT_LIBS="$with_libtokyotyrant_libs" @@@ -4084,67 -4087,6 +4141,67 @@@ f AM_CONDITIONAL(BUILD_WITH_LIBTOKYOTYRANT, test "x$with_libtokyotyrant" = "xyes") # }}} +# --with-libudev {{{ +with_libudev_cflags="" +with_libudev_ldflags="" +AC_ARG_WITH(libudev, [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])], +[ + if test "x$withval" = "xno" + then + with_libudev="no" + else + with_libudev="yes" + if test "x$withval" != "xyes" + then + with_libudev_cflags="-I$withval/include" + with_libudev_ldflags="-L$withval/lib" + with_libudev="yes" + fi + fi +], +[ + if test "x$ac_system" = "xLinux" + then + with_libudev="yes" + else + with_libudev="no (Linux only library)" + fi +]) +if test "x$with_libudev" = "xyes" +then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libudev_cflags" + + AC_CHECK_HEADERS(libudev.h, [], [with_libudev="no (libudev.h not found)"]) + + CPPFLAGS="$SAVE_CPPFLAGS" +fi +if test "x$with_libudev" = "xyes" +then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS $with_libudev_cflags" + LDFLAGS="$LDFLAGS $with_libudev_ldflags" + + AC_CHECK_LIB(udev, udev_new, + [ + AC_DEFINE(HAVE_LIBUDEV, 1, [Define to 1 if you have the udev library (-ludev).]) + ], + [with_libudev="no (libudev not found)"]) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" +fi +if test "x$with_libudev" = "xyes" +then + BUILD_WITH_LIBUDEV_CFLAGS="$with_libudev_cflags" + BUILD_WITH_LIBUDEV_LDFLAGS="$with_libudev_ldflags" + AC_SUBST(BUILD_WITH_LIBUDEV_CFLAGS) + AC_SUBST(BUILD_WITH_LIBUDEV_LDFLAGS) +fi +AM_CONDITIONAL(BUILD_WITH_LIBUDEV, test "x$with_libudev" = "xyes") +# }}} + # --with-libupsclient {{{ with_libupsclient_config="" with_libupsclient_cflags="" @@@ -4557,7 -4499,7 +4614,7 @@@ with_libvirt_cflags=" with_libvirt_ldflags="" if test "x$PKG_CONFIG" != "x" then - pkg-config --exists 'libxml-2.0' 2>/dev/null + $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null if test "$?" = "0" then with_libxml2="yes" @@@ -4565,7 -4507,7 +4622,7 @@@ with_libxml2="no (pkg-config doesn't know libxml-2.0)" fi - pkg-config --exists libvirt 2>/dev/null + $PKG_CONFIG --exists libvirt 2>/dev/null if test "$?" = "0" then with_libvirt="yes" @@@ -4575,12 -4517,12 +4632,12 @@@ fi if test "x$with_libxml2" = "xyes" then - with_libxml2_cflags="`pkg-config --cflags libxml-2.0`" + with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`" if test $? -ne 0 then with_libxml2="no" fi - with_libxml2_ldflags="`pkg-config --libs libxml-2.0`" + with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`" if test $? -ne 0 then with_libxml2="no" @@@ -4620,12 -4562,12 +4677,12 @@@ if test "x$with_libxml2" = "xyes"; the fi if test "x$with_libvirt" = "xyes" then - with_libvirt_cflags="`pkg-config --cflags libvirt`" + with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`" if test $? -ne 0 then with_libvirt="no" fi - with_libvirt_ldflags="`pkg-config --libs libvirt`" + with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`" if test $? -ne 0 then with_libvirt="no" @@@ -4881,7 -4823,6 +4938,7 @@@ dependency_warning="no dependency_error="no" plugin_ascent="no" +plugin_barometer="no" plugin_battery="no" plugin_bind="no" plugin_cgroups="no" @@@ -4893,7 -4834,6 +4950,7 @@@ plugin_curl_json="no plugin_curl_xml="no" plugin_df="no" plugin_disk="no" +plugin_drbd="no" plugin_entropy="no" plugin_ethstat="no" plugin_fscache="no" @@@ -4903,7 -4843,6 +4960,7 @@@ plugin_ipvs="no plugin_irq="no" plugin_libvirt="no" plugin_load="no" +plugin_log_logstash="no" plugin_memory="no" plugin_multimeter="no" plugin_nfs="no" @@@ -4934,7 -4873,6 +4991,7 @@@ the plugin_cpu="yes" plugin_cpufreq="yes" plugin_disk="yes" + plugin_drbd="yes" plugin_entropy="yes" plugin_fscache="yes" plugin_interface="yes" @@@ -5022,23 -4960,6 +5079,23 @@@ the plugin_tape="yes" fi +# libi2c-dev +with_libi2c="no" +if test "x$ac_system" = "xLinux" +then +AC_CHECK_DECL(i2c_smbus_read_i2c_block_data, + [with_libi2c="yes"], + [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"], + [[#include + #include ]]) +fi + +if test "x$with_libi2c" = "xyes" +then + plugin_barometer="yes" +fi + + # libstatgrab if test "x$with_libstatgrab" = "xyes" then @@@ -5152,11 -5073,6 +5209,11 @@@ the plugin_load="yes" fi +if test "x$with_libyajl" = "xyes" +then + plugin_log_logstash="yes" +fi + if test "x$c_cv_have_libperl$c_cv_have_perl_ithreads" = "xyesyes" then plugin_perl="yes" @@@ -5170,10 -5086,7 +5227,10 @@@ f if test "x$have_termios_h" = "xyes" then - plugin_multimeter="yes" + if test "x$ac_system" != "xAIX" + then + plugin_multimeter="yes" + fi plugin_ted="yes" fi @@@ -5238,7 -5151,6 +5295,7 @@@ AC_PLUGIN([apcups], [yes] AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple's hardware sensors]) AC_PLUGIN([aquaero], [$with_libaquaero5], [Aquaero's hardware sensors]) AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics]) +AC_PLUGIN([barometer], [$plugin_barometer], [Barometer sensor on I2C]) AC_PLUGIN([battery], [$plugin_battery], [Battery statistics]) AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics]) AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics]) @@@ -5253,7 -5165,6 +5310,7 @@@ AC_PLUGIN([cgroups], [$plugin_cgrou AC_PLUGIN([dbi], [$with_libdbi], [General database statistics]) AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics]) +AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics]) AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis]) AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) @@@ -5272,7 -5183,6 +5329,7 @@@ AC_PLUGIN([java], [$with_java] AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics]) AC_PLUGIN([load], [$plugin_load], [System load]) AC_PLUGIN([logfile], [yes], [File logging plugin]) +AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging]) AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics]) AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics]) AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics]) @@@ -5350,11 -5260,9 +5407,11 @@@ AC_PLUGIN([vserver], [$plugin_vserv AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics]) AC_PLUGIN([write_graphite], [yes], [Graphite / Carbon output plugin]) AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin]) +AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin]) AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin]) AC_PLUGIN([write_redis], [$with_libcredis], [Redis output plugin]) AC_PLUGIN([write_riemann], [$have_protoc_c], [Riemann output plugin]) +AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin]) AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics]) AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics]) @@@ -5362,7 -5270,6 +5419,7 @@@ dnl Default configuration fil # Load either syslog or logfile LOAD_PLUGIN_SYSLOG="" LOAD_PLUGIN_LOGFILE="" +LOAD_PLUGIN_LOG_LOGSTASH="" AC_MSG_CHECKING([which default log plugin to load]) default_log_plugin="none" @@@ -5384,20 -5291,10 +5441,20 @@@ the else LOAD_PLUGIN_LOGFILE="##" fi + +if test "x$enable_log_logstash" = "xyes" +then + LOAD_PLUGIN_LOG_LOGSTASH="#" +else + LOAD_PLUGIN_LOG_LOGSTASH="##" +fi + + AC_MSG_RESULT([$default_log_plugin]) AC_SUBST(LOAD_PLUGIN_SYSLOG) AC_SUBST(LOAD_PLUGIN_LOGFILE) +AC_SUBST(LOAD_PLUGIN_LOG_LOGSTASH) DEFAULT_LOG_LEVEL="info" if test "x$enable_debug" = "xyes" @@@ -5546,13 -5443,11 +5603,13 @@@ Configuration libesmtp . . . . . . $with_libesmtp libganglia . . . . . $with_libganglia libgcrypt . . . . . . $with_libgcrypt + libi2c-dev . . . . . $with_libi2c libiokit . . . . . . $with_libiokit libiptc . . . . . . . $with_libiptc libjvm . . . . . . . $with_java libkstat . . . . . . $with_kstat libkvm . . . . . . . $with_libkvm + liblvm2app . . . . . $with_liblvm2app libmemcached . . . . $with_libmemcached libmnl . . . . . . . $with_libmnl libmodbus . . . . . . $with_libmodbus @@@ -5569,14 -5464,12 +5626,14 @@@ libpq . . . . . . . . $with_libpq libpthread . . . . . $with_libpthread librabbitmq . . . . . $with_librabbitmq + librdkafka . . . . . $with_librdkafka librouteros . . . . . $with_librouteros librrd . . . . . . . $with_librrd libsensors . . . . . $with_libsensors libsigrok . . . . . $with_libsigrok libstatgrab . . . . . $with_libstatgrab libtokyotyrant . . . $with_libtokyotyrant + libudev . . . . . . . $with_libudev libupsclient . . . . $with_libupsclient libvarnish . . . . . $with_libvarnish libvirt . . . . . . . $with_libvirt @@@ -5603,7 -5496,6 +5660,7 @@@ aquaero . . . . . . . $enable_aquaero apple_sensors . . . . $enable_apple_sensors ascent . . . . . . . $enable_ascent + barometer . . . . . . $enable_barometer battery . . . . . . . $enable_battery bind . . . . . . . . $enable_bind conntrack . . . . . . $enable_conntrack @@@ -5619,7 -5511,6 +5676,7 @@@ df . . . . . . . . . $enable_df disk . . . . . . . . $enable_disk dns . . . . . . . . . $enable_dns + drbd . . . . . . . . $enable_drbd email . . . . . . . . $enable_email entropy . . . . . . . $enable_entropy ethstat . . . . . . . $enable_ethstat @@@ -5638,7 -5529,6 +5695,7 @@@ load . . . . . . . . $enable_load logfile . . . . . . . $enable_logfile lpar . . . . . . . . $enable_lpar + log_logstash . . . . $enable_log_logstash lvm . . . . . . . . . $enable_lvm madwifi . . . . . . . $enable_madwifi match_empty_counter . $enable_match_empty_counter @@@ -5714,11 -5604,9 +5771,11 @@@ wireless . . . . . . $enable_wireless write_graphite . . . $enable_write_graphite write_http . . . . . $enable_write_http + write_kafka . . . . . $enable_write_kafka write_mongodb . . . . $enable_write_mongodb write_redis . . . . . $enable_write_redis write_riemann . . . . $enable_write_riemann + write_tsdb . . . . . $enable_write_tsdb xmms . . . . . . . . $enable_xmms zfs_arc . . . . . . . $enable_zfs_arc diff --combined contrib/redhat/collectd.spec index 6af91e8a,43704c4f..9facca83 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@@ -45,6 -45,7 +45,7 @@@ %{?el6:%global _has_ip_vs_h 1} %{?el6:%global _has_lvm2app_h 1} %{?el6:%global _has_perl_extutils_embed 1} + %{?el6:%global _has_libmodbus 1} # plugins enabled by default %define with_aggregation 0%{!?_without_aggregation:1} @@@ -92,6 -93,7 +93,7 @@@ %define with_memcached 0%{!?_without_memcached:1} %define with_memory 0%{!?_without_memory:1} %define with_multimeter 0%{!?_without_multimeter:1} + %define with_modbus 0%{!?_without_modbus:0%{?_has_libmodbus}} %define with_mysql 0%{!?_without_mysql:1} %define with_netlink 0%{!?_without_netlink:1} %define with_network 0%{!?_without_network:1} @@@ -422,6 -424,16 +424,16 @@@ The mic plugin collects CPU usage, memo consumption from Intel Many Integrated Core (MIC) CPUs. %endif + %if %{with_modbus} + %package modbus + Summary: modbus plugin for collectd + Group: System Environment/Daemons + Requires: %{name}%{?_isa} = %{version}-%{release} + BuildRequires: libmodbus-devel + %description modbus + The modbus plugin collects values from Modbus/TCP enabled devices + %endif + %if %{with_mysql} %package mysql Summary: MySQL plugin for collectd @@@ -997,6 -1009,12 +1009,12 @@@ Development files for libcollectdclien %define _with_multimeter --disable-multimeter %endif + %if %{with_modbus} + %define _with_modbus --enable-modbus + %else + %define _with_modbus --disable-modbus + %endif + %if %{with_mysql} %define _with_mysql --enable-mysql %else @@@ -2013,6 -2031,9 +2031,9 @@@ f - Enable cgroups, lvm and statsd plugins - Enable (but don't build by default) mic, aquaero and sigrok plugins + * Wed Aug 06 2014 Marc Fournier 5.3.1-2 + - Enabled modbus plugin + * Tue Aug 06 2013 Marc Fournier 5.3.1-1 - New upstream version - Added RHEL5 support: @@@ -2051,7 -2072,7 +2072,7 @@@ * Sat Nov 17 2012 Ruben Kerkhof 5.1.0-2 - Move perl stuff to perl_vendorlib - Replace hardcoded paths with macros -- Remove unneccesary Requires +- Remove unnecessary Requires - Removed .a and .la files - Some other small cleanups @@@ -2059,7 -2080,7 +2080,7 @@@ - New upstream version - Changes to support 5.1.0 - Enabled all buildable plugins based on libraries available on EL6 + EPEL -- All plugins requiring external libraries are now shipped in seperate +- All plugins requiring external libraries are now shipped in separate packages. - No longer treat Java plugin as an exception, correctly set $JAVA_HOME during the build process + ensure build deps are installed. diff --combined src/Makefile.am index d25370a5,36ce028f..d7275665 --- a/src/Makefile.am +++ b/src/Makefile.am @@@ -17,8 -17,6 +17,8 @@@ endi AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"' AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' +AUTOMAKE_OPTIONS = subdir-objects + sbin_PROGRAMS = collectd collectdmon bin_PROGRAMS = collectd-nagios collectdctl collectd-tg @@@ -41,9 -39,7 +41,9 @@@ collectd_SOURCES = collectd.c collectd. utils_subst.c utils_subst.h \ utils_tail.c utils_tail.h \ utils_time.c utils_time.h \ - types_list.c types_list.h + types_list.c types_list.h \ + utils_threshold.c utils_threshold.h + collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) collectd_CFLAGS = $(AM_CFLAGS) @@@ -137,9 -133,9 +137,9 @@@ collectd_tg_LDADD += libcollectdclient/ collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la -pkglib_LTLIBRARIES = +pkglib_LTLIBRARIES = -BUILT_SOURCES = +BUILT_SOURCES = CLEANFILES = if BUILD_PLUGIN_AGGREGATION @@@ -221,15 -217,6 +221,15 @@@ collectd_LDADD += "-dlopen" ascent.l collectd_DEPENDENCIES += ascent.la endif +if BUILD_PLUGIN_BAROMETER +pkglib_LTLIBRARIES += barometer.la +barometer_la_SOURCES = barometer.c +barometer_la_LDFLAGS = -module -avoid-version +barometer_la_LIBADD = -lm +collectd_LDADD += "-dlopen" barometer.la +collectd_DEPENDENCIES += barometer.la +endif + if BUILD_PLUGIN_BATTERY pkglib_LTLIBRARIES += battery.la battery_la_SOURCES = battery.c @@@ -286,7 -273,7 +286,7 @@@ pkglib_LTLIBRARIES += cpu.l cpu_la_SOURCES = cpu.c cpu_la_CFLAGS = $(AM_CFLAGS) cpu_la_LDFLAGS = -module -avoid-version -cpu_la_LIBADD = +cpu_la_LIBADD = if BUILD_WITH_LIBKSTAT cpu_la_LIBADD += -lkstat endif @@@ -384,7 -371,7 +384,7 @@@ pkglib_LTLIBRARIES += disk.l disk_la_SOURCES = disk.c disk_la_CFLAGS = $(AM_CFLAGS) disk_la_LDFLAGS = -module -avoid-version -disk_la_LIBADD = +disk_la_LIBADD = if BUILD_WITH_LIBKSTAT disk_la_LIBADD += -lkstat endif @@@ -395,12 -382,9 +395,12 @@@ if BUILD_WITH_LIBIOKI disk_la_LDFLAGS += -framework IOKit endif if BUILD_WITH_LIBSTATGRAB -disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) endif +if BUILD_WITH_LIBUDEV +disk_la_LIBADD += -ludev +endif if BUILD_WITH_PERFSTAT disk_la_LIBADD += -lperfstat endif @@@ -417,15 -401,6 +417,15 @@@ collectd_LDADD += "-dlopen" dns.l collectd_DEPENDENCIES += dns.la endif +if BUILD_PLUGIN_DRBD +pkglib_LTLIBRARIES += drbd.la +drbd_la_SOURCES = drbd.c +drbd_la_LDFLAGS = -module -avoid-version +drbd_la_LIBADD = -lpthread +collectd_LDADD += "-dlopen" drbd.la +collectd_DEPENDENCIES += drbd.la +endif + if BUILD_PLUGIN_EMAIL pkglib_LTLIBRARIES += email.la email_la_SOURCES = email.c @@@ -520,8 -495,8 +520,8 @@@ if BUILD_PLUGIN_IPTABLE pkglib_LTLIBRARIES += iptables.la iptables_la_SOURCES = iptables.c iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS) - iptables_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBIPTC_LDFLAGS) - iptables_la_LIBADD = -liptc + iptables_la_LDFLAGS = -module -avoid-version + iptables_la_LIBADD = $(BUILD_WITH_LIBIPTC_LDFLAGS) collectd_LDADD += "-dlopen" iptables.la collectd_DEPENDENCIES += iptables.la endif @@@ -602,17 -577,6 +602,17 @@@ collectd_LDADD += "-dlopen" logfile.l collectd_DEPENDENCIES += logfile.la endif +if BUILD_PLUGIN_LOG_LOGSTASH +pkglib_LTLIBRARIES += log_logstash.la +log_logstash_la_SOURCES = log_logstash.c +log_logstash_la_CFLAGS = $(AM_CFLAGS) +log_logstash_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBYAJL_LDFLAGS) +log_logstash_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +log_logstash_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +collectd_LDADD += "-dlopen" log_logstash.la +collectd_DEPENDENCIES += log_logstash.la +endif + if BUILD_PLUGIN_LPAR pkglib_LTLIBRARIES += lpar.la lpar_la_SOURCES = lpar.c @@@ -898,7 -862,7 +898,7 @@@ if BUILD_PLUGIN_OLSR pkglib_LTLIBRARIES += olsrd.la olsrd_la_SOURCES = olsrd.c olsrd_la_LDFLAGS = -module -avoid-version -olsrd_la_LIBADD = +olsrd_la_LIBADD = if BUILD_WITH_LIBSOCKET olsrd_la_LIBADD += -lsocket endif @@@ -1305,7 -1269,6 +1305,7 @@@ pkglib_LTLIBRARIES += unixsock.l unixsock_la_SOURCES = unixsock.c \ utils_cmd_flush.h utils_cmd_flush.c \ utils_cmd_getval.h utils_cmd_getval.c \ + utils_cmd_getthreshold.h utils_cmd_getthreshold.c \ utils_cmd_listval.h utils_cmd_listval.c \ utils_cmd_putval.h utils_cmd_putval.c \ utils_cmd_putnotif.h utils_cmd_putnotif.c @@@ -1424,19 -1387,6 +1424,19 @@@ endi collectd_DEPENDENCIES += write_http.la endif +if BUILD_PLUGIN_WRITE_KAFKA +pkglib_LTLIBRARIES += write_kafka.la +write_kafka_la_SOURCES = write_kafka.c \ + utils_format_graphite.c utils_format_graphite.h \ + utils_format_json.c utils_format_json.h \ + utils_cmd_putval.c utils_cmd_putval.h \ + utils_crc32.c utils_crc32.h +write_kafka_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBRDKAFKA_LDFLAGS) +write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) +collectd_LDADD += "-dlopen" write_kafka.la +collectd_DEPENDENCIES += write_kafka.la +endif + if BUILD_PLUGIN_WRITE_MONGODB pkglib_LTLIBRARIES += write_mongodb.la write_mongodb_la_SOURCES = write_mongodb.c @@@ -1459,7 -1409,7 +1459,7 @@@ endi if BUILD_PLUGIN_WRITE_RIEMANN pkglib_LTLIBRARIES += write_riemann.la -write_riemann_la_SOURCES = write_riemann.c +write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c nodist_write_riemann_la_SOURCES = riemann.pb-c.c riemann.pb-c.h write_riemann_la_LDFLAGS = -module -avoid-version write_riemann_la_LIBADD = -lprotobuf-c @@@ -1467,14 -1417,6 +1467,14 @@@ collectd_LDADD += "-dlopen" write_riema collectd_DEPENDENCIES += write_riemann.la endif +if BUILD_PLUGIN_WRITE_TSDB +pkglib_LTLIBRARIES += write_tsdb.la +write_tsdb_la_SOURCES = write_tsdb.c +write_tsdb_la_LDFLAGS = -module -avoid-version +collectd_LDADD += "-dlopen" write_tsdb.la +collectd_DEPENDENCIES += write_tsdb.la +endif + if BUILD_PLUGIN_XMMS pkglib_LTLIBRARIES += xmms.la xmms_la_SOURCES = xmms.c @@@ -1593,48 -1535,15 +1593,48 @@@ uninstall-hook rm -f $(DESTDIR)$(sysconfdir)/collectd.conf rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; -if BUILD_FEATURE_DEBUG -bin_PROGRAMS += utils_vl_lookup_test -utils_vl_lookup_test_SOURCES = utils_vl_lookup_test.c \ +check_PROGRAMS = test_common test_utils_avltree test_utils_heap test_utils_mount test_utils_vl_lookup + +test_common_SOURCES = tests/test_common.c \ + common.h common.c \ + tests/mock/plugin.c \ + tests/mock/utils_cache.c \ + tests/mock/utils_time.c +test_common_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) +test_common_LDFLAGS = -export-dynamic +test_common_LDADD = + +test_utils_avltree_SOURCES = tests/test_utils_avltree.c \ + utils_avltree.c utils_avltree.h +test_utils_avltree_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) +test_utils_avltree_LDFLAGS = -export-dynamic +test_utils_avltree_LDADD = + +test_utils_heap_SOURCES = tests/test_utils_heap.c \ + utils_heap.c utils_heap.h +test_utils_heap_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) +test_utils_heap_LDFLAGS = -export-dynamic +test_utils_heap_LDADD = + +test_utils_mount_SOURCES = tests/test_utils_mount.c \ + utils_mount.c utils_mount.h \ + common.c common.h \ + tests/mock/plugin.c \ + tests/mock/utils_cache.c \ + tests/mock/utils_time.c +test_utils_mount_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) +test_utils_mount_LDFLAGS = -export-dynamic +test_utils_mount_LDADD = + +test_utils_vl_lookup_SOURCES = tests/test_utils_vl_lookup.c \ utils_vl_lookup.h utils_vl_lookup.c \ utils_avltree.c utils_avltree.h \ - common.h - -utils_vl_lookup_test_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -DBUILD_TEST=1 -utils_vl_lookup_test_CFLAGS = $(AM_CFLAGS) -utils_vl_lookup_test_LDFLAGS = -export-dynamic -utils_vl_lookup_test_LDADD = -endif + common.c common.h \ + tests/mock/plugin.c \ + tests/mock/utils_cache.c \ + tests/mock/utils_time.c +test_utils_vl_lookup_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) +test_utils_vl_lookup_LDFLAGS = -export-dynamic +test_utils_vl_lookup_LDADD = + +TESTS = test_common test_utils_avltree test_utils_heap test_utils_mount test_utils_vl_lookup diff --combined src/amqp.c index 56718f07,ab920a6a..1764129f --- a/src/amqp.c +++ b/src/amqp.c @@@ -23,7 -23,7 +23,7 @@@ * * Authors: * Sebastien Pahl - * Florian Forster + * Florian Forster **/ #include "collectd.h" @@@ -38,6 -38,20 +38,20 @@@ #include #include + #ifdef HAVE_AMQP_TCP_SOCKET_H + # include + #endif + #ifdef HAVE_AMQP_SOCKET_H + # include + #endif + #ifdef HAVE_AMQP_TCP_SOCKET + #if defined HAVE_DECL_AMQP_SOCKET_CLOSE && !HAVE_DECL_AMQP_SOCKET_CLOSE + /* rabbitmq-c does not currently ship amqp_socket.h + * and, thus, does not define this function. */ + int amqp_socket_close(amqp_socket_t *); + #endif + #endif + /* Defines for the delivery mode. I have no idea why they're not defined by the * library.. */ #define CAMQP_DM_VOLATILE 1 @@@ -79,8 -93,6 +93,8 @@@ struct camqp_config_ /* subscribe only */ char *exchange_type; char *queue; + _Bool queue_durable; + _Bool queue_auto_delete; amqp_connection_state_t connection; pthread_mutex_t lock; @@@ -316,9 -328,9 +330,9 @@@ static int camqp_setup_queue (camqp_con ? amqp_cstring_bytes (conf->queue) : AMQP_EMPTY_BYTES, /* passive = */ 0, - /* durable = */ 0, + /* durable = */ conf->queue_durable, /* exclusive = */ 0, - /* auto_delete = */ 1, + /* auto_delete = */ conf->queue_auto_delete, /* arguments = */ AMQP_EMPTY_TABLE); if (qd_ret == NULL) { @@@ -392,8 -404,12 +406,12 @@@ static int camqp_connect (camqp_config_t *conf) /* {{{ */ { amqp_rpc_reply_t reply; - int sockfd; int status; + #ifdef HAVE_AMQP_TCP_SOCKET + amqp_socket_t *socket; + #else + int sockfd; + #endif if (conf->connection != NULL) return (0); @@@ -405,6 -421,33 +423,33 @@@ return (ENOMEM); } + #ifdef HAVE_AMQP_TCP_SOCKET + # define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us */ + /* TODO: add support for SSL using amqp_ssl_socket_new + * and related functions */ + socket = amqp_tcp_socket_new (conf->connection); + if (! socket) + { + ERROR ("amqp plugin: amqp_tcp_socket_new failed."); + amqp_destroy_connection (conf->connection); + conf->connection = NULL; + return (ENOMEM); + } + + status = amqp_socket_open (socket, CONF(conf, host), conf->port); + if (status < 0) + { + char errbuf[1024]; + status *= -1; + ERROR ("amqp plugin: amqp_socket_open failed: %s", + sstrerror (status, errbuf, sizeof (errbuf))); + amqp_destroy_connection (conf->connection); + conf->connection = NULL; + return (status); + } + #else /* HAVE_AMQP_TCP_SOCKET */ + # define CLOSE_SOCKET() close(sockfd) + /* this interface is deprecated as of rabbitmq-c 0.4 */ sockfd = amqp_open_socket (CONF(conf, host), conf->port); if (sockfd < 0) { @@@ -417,6 -460,7 +462,7 @@@ return (status); } amqp_set_sockfd (conf->connection, sockfd); + #endif reply = amqp_login (conf->connection, CONF(conf, vhost), /* channel max = */ 0, @@@ -429,7 -473,7 +475,7 @@@ ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", CONF(conf, vhost), CONF(conf, user)); amqp_destroy_connection (conf->connection); - close (sockfd); + CLOSE_SOCKET (); conf->connection = NULL; return (1); } @@@ -442,7 -486,7 +488,7 @@@ ERROR ("amqp plugin: amqp_channel_open failed."); amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); amqp_destroy_connection (conf->connection); - close(sockfd); + CLOSE_SOCKET (); conf->connection = NULL; return (1); } @@@ -743,7 -787,7 +789,7 @@@ static int camqp_write (const data_set_ { camqp_config_t *conf = user_data->data; char routing_key[6 * DATA_MAX_NAME_LEN]; - char buffer[4096]; + char buffer[8192]; int status; if ((ds == NULL) || (vl == NULL) || (conf == NULL)) @@@ -887,8 -931,6 +933,8 @@@ static int camqp_config_connection (oco /* subscribe only */ conf->exchange_type = NULL; conf->queue = NULL; + conf->queue_durable = 0; + conf->queue_auto_delete = 1; /* general */ conf->connection = NULL; pthread_mutex_init (&conf->lock, /* attr = */ NULL); @@@ -928,10 -970,6 +974,10 @@@ status = cf_util_get_string (child, &conf->exchange_type); else if ((strcasecmp ("Queue", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->queue); + else if ((strcasecmp ("QueueDurable", child->key) == 0) && !publish) + status = cf_util_get_boolean (child, &conf->queue_durable); + else if ((strcasecmp ("QueueAutoDelete", child->key) == 0) && !publish) + status = cf_util_get_boolean (child, &conf->queue_auto_delete); else if (strcasecmp ("RoutingKey", child->key) == 0) status = cf_util_get_string (child, &conf->routing_key); else if ((strcasecmp ("Persistent", child->key) == 0) && publish) diff --combined src/apache.c index 7e4c79bb,f0ab22a8..ad5975c0 --- a/src/apache.c +++ b/src/apache.c @@@ -18,7 -18,7 +18,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Florent EppO Monbillard * - connections/lighttpd extension * Amit Gupta @@@ -402,7 -402,7 +402,7 @@@ static int init_host (apache_t *st) /* curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st); } - curl_easy_setopt (st->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); + curl_easy_setopt (st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); if (st->user != NULL) @@@ -671,9 -671,18 +671,18 @@@ static int apache_read_host (user_data_ return (0); } /* }}} int apache_read_host */ + static int apache_init (void) /* {{{ */ + { + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init (CURL_GLOBAL_SSL); + return (0); + } /* }}} int apache_init */ + void module_register (void) { plugin_register_complex_config ("apache", config); + plugin_register_init ("apache", apache_init); } /* void module_register */ /* vim: set sw=8 noet fdm=marker : */ diff --combined src/collectd-unixsock.pod index eb1d14fc,c572df19..b241a9f3 --- a/src/collectd-unixsock.pod +++ b/src/collectd-unixsock.pod @@@ -13,6 -13,7 +13,7 @@@ collectd-unixsock - Documentation of co SocketFile "/path/to/socket" SocketGroup "collectd" SocketPerms "0770" + DeleteSocket false =head1 DESCRIPTION @@@ -176,24 -177,11 +177,24 @@@ table. All the options are optional, bu or B without B doesn't make much sense and should be avoided. -Please note that this is the same format as used in the B, see -L. +=item BI + +Sets user defined meta information. The B key is a single character +defining the type of the meta information. + +The current supported types are: + +=over 8 + +=item B A string passed as-is. =back +=back + +Please note that this is the same format as used in the B, see +L. + Example: -> | PUTNOTIF type=temperature severity=warning time=1201094702 message=The roof is on fire! <- | 0 Success @@@ -255,6 -243,6 +256,6 @@@ Locto@verplant.orgE +Florian Forster Eocto@collectd.orgE =cut diff --combined src/collectd.conf.in index 18a74c65,678cfb35..4d5abe0d --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@@ -52,7 -52,6 +52,7 @@@ @LOAD_PLUGIN_SYSLOG@LoadPlugin syslog @LOAD_PLUGIN_LOGFILE@LoadPlugin logfile +@LOAD_PLUGIN_LOG_LOGSTASH@LoadPlugin log_logstash # # LogLevel @DEFAULT_LOG_LEVEL@ @@@ -61,11 -60,6 +61,11 @@@ # PrintSeverity false # +# +# LogLevel @DEFAULT_LOG_LEVEL@ +# File "@localstatedir@/log/@PACKAGE_NAME@.json.log" +# + # # LogLevel @DEFAULT_LOG_LEVEL@ # @@@ -87,7 -81,6 +87,7 @@@ #@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors #@BUILD_PLUGIN_AQUAERO_TRUE@LoadPlugin aquaero #@BUILD_PLUGIN_ASCENT_TRUE@LoadPlugin ascent +#@BUILD_PLUGIN_BAROMETER_TRUE@LoadPlugin barometer #@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery #@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind #@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack @@@ -103,7 -96,6 +103,7 @@@ #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns +#@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email #@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy #@BUILD_PLUGIN_ETHSTAT_TRUE@LoadPlugin ethstat @@@ -187,11 -179,9 +187,11 @@@ #@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless #@BUILD_PLUGIN_WRITE_GRAPHITE_TRUE@LoadPlugin write_graphite #@BUILD_PLUGIN_WRITE_HTTP_TRUE@LoadPlugin write_http +#@BUILD_PLUGIN_WRITE_KAFKA_TRUE@LoadPlugin write_kafka #@BUILD_PLUGIN_WRITE_MONGODB_TRUE@LoadPlugin write_mongodb #@BUILD_PLUGIN_WRITE_REDIS_TRUE@LoadPlugin write_redis #@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann +#@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms #@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc @@@ -202,7 -192,7 +202,7 @@@ # ription of those options is available in the collectd.conf(5) manual page. # ############################################################################## -# +# # # #Host "unspecified" # Plugin "cpu" @@@ -222,7 -212,7 +222,7 @@@ # # -# +# # # Host "localhost" # Port "5672" @@@ -262,16 -252,6 +262,16 @@@ # CACert "/etc/ssl/ca.crt" # +# +# Device "/dev/i2c-0"; +# Oversampling 512 +# PressureOffset 0.0 +# TemperatureOffset 0.0 +# Normalization 2 +# Altitude 238.0 +# TemperatureSensor "myserver/onewire-F10FCA000800/temperature" +# + # # URL "http://localhost:8053/" # ParseTime false @@@ -292,17 -272,11 +292,17 @@@ # # - # + # # CGroup "libvirt" # IgnoreSelected false # +# +# ReportActive false +# ReportByCpu true +# ValuesPercentage false +# +# # # DataDir "@localstatedir@/lib/@PACKAGE_NAME@/csv" # StoreRates false @@@ -354,7 -328,7 +354,7 @@@ # # -# +# # # Host "my_host" # Instance "some_instance" @@@ -411,8 -385,6 +411,8 @@@ # # Disk "/^[hs]d[a-f][0-9]?$/" # IgnoreSelected false +# UseBSDName false +# UdevNameAttr "DEVNAME" # # @@@ -451,7 -423,7 +451,7 @@@ # # -# +# # MCReceiveFrom "239.2.11.71" "8649" # # Type "swap" @@@ -495,7 -467,7 +495,7 @@@ # IgnoreSelected true # -# +# # JVMArg "-verbose:jni" # JVMArg "-Djava.class.path=@prefix@/share/collectd/java/collectd-api.jar" # @@@ -514,11 -486,6 +514,11 @@@ # IgnoreSelected false # HostnameFormat name # InterfaceFormat name +# PluginInstanceFormat name +# + +# +# ReportRelative true # # @@@ -568,11 -535,6 +568,11 @@@ # # +# +# ValuesAbsolute true +# ValuesPercentage false +# + # # # RegisterBase 1234 @@@ -600,12 -562,9 +600,12 @@@ # Password "secret" # Database "db_name" # MasterStats true +# ConnectTimeout 10 +# InnodbStats true # # # +# Alias "squeeze" # Host "localhost" # Socket "/var/run/mysql/mysqld.sock" # SlaveStats true @@@ -1010,14 -969,12 +1010,14 @@@ # TimerPercentile 90.0 # -# +# # ReportByDevice false # ReportBytes true +# ValuesAbsolute true +# ValuesPercentage false # -# +# # # Instance "slabinfo" # Separator " " @@@ -1036,10 -993,9 +1036,10 @@@ #
#
-# +# # # Instance "exim" +# Interval 60 # # Regex "S=([1-9][0-9]*)" # DSType "CounterAdd" @@@ -1056,7 -1012,7 +1056,7 @@@ # # -# +# # # Type "percent" # Instance "dropped" @@@ -1194,23 -1150,11 +1194,23 @@@ # VerifyPeer true # VerifyHost true # CACert "/etc/ssl/ca.crt" +# CAPath "/etc/ssl/certs/" +# ClientKey "/etc/ssl/client.pem" +# ClientCert "/etc/ssl/client.crt" +# ClientKeyPass "secret" +# SSLVersion "TLSv1" # Format "Command" # StoreRates false #
#
+# +# Property "metadata.broker.list" "localhost:9092" +# +# Format JSON +# +# + # # # Host "localhost" @@@ -1241,17 -1185,6 +1241,17 @@@ # TTLFactor 2.0 # # Tag "foobar" +# Attribute "foo" "bar" +# + +# +# +# Host "localhost" +# Port "4242" +# HostTags "status=production" +# StoreRates false +# AlwaysAppendDS false +# # ############################################################################## @@@ -1294,7 -1227,7 +1294,7 @@@ ############################################################################## #@BUILD_PLUGIN_THRESHOLD_TRUE@LoadPlugin "threshold" -# +# # # WarningMin 0.00 # WarningMax 1000.00 diff --combined src/collectd.conf.pod index acd0cbbe,81c8f4c6..3a8af849 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@@ -9,14 -9,14 +9,14 @@@ collectd.conf - Configuration for the s BaseDir "/path/to/data/" PIDFile "/path/to/pidfile/collectd.pid" Server "123.123.123.123" 12345 - + LoadPlugin cpu LoadPlugin load - + Interval 3600 - + LoadPlugin ping Host "example.org" @@@ -341,10 -341,10 +341,10 @@@ The full example configuration looks li Plugin "cpu" Type "cpu" - + GroupBy "Host" GroupBy "TypeInstance" - + CalculateSum true CalculateAverage true @@@ -420,13 -420,13 +420,13 @@@ The following example calculates the av Plugin "cpu" PluginInstance "/[0,2,4,6,8]$/" Type "cpu" - + SetPlugin "cpu" SetPluginInstance "even-%{aggregation}" - + GroupBy "Host" GroupBy "TypeInstance" - + CalculateAverage true @@@ -494,8 -494,10 +494,10 @@@ possibly filtering or messages # StoreRates false # GraphitePrefix "collectd." # GraphiteEscapeChar "_" + # GraphiteSeparateInstances false + # GraphiteAlwaysAppendDS false - + # Receive values from an AMQP broker Host "localhost" @@@ -506,8 -508,6 +508,8 @@@ Exchange "amq.fanout" # ExchangeType "fanout" # Queue "queue_name" + # QueueDurable false + # QueueAutoDelete true # RoutingKey "collectd.#" @@@ -560,23 -560,9 +562,23 @@@ be bound to this exchange =item B I (Subscribe only) -Configures the I name to subscribe to. If no queue name was configures +Configures the I name to subscribe to. If no queue name was configured explicitly, a unique queue name will be created by the broker. +=item B B|B (Subscribe only) + +Defines if the I subscribed to is durable (saved to persistent storage) +or transient (will disappear if the AMQP broker is restarted). Defaults to +"false". + +This option should be used in conjunction with the I option on the +publish side. + +=item B B|B (Subscribe only) + +Defines if the I subscribed to will be deleted once the last consumer +unsubscribes. Defaults to "true". + =item B I In I blocks, this configures the routing key to set on all outgoing @@@ -647,6 -633,19 +649,19 @@@ In I metric name, dots are us metric parts (host, plugin, type). Default is "_" (I). + =item B B|B + + If set to B, the plugin instance and type instance will be in their own + path component, for example C. If set to B (the + default), the plugin and plugin instance (and likewise the type and type + instance) are put into one component, for example C. + + =item B B|B + + If set to B, append the name of the I (DS) to the "metric" + identifier. If set to B (the default), this is only done when there is + more than one DS. + =back =head2 Plugin C @@@ -812,131 -811,6 +827,131 @@@ and are checked by default depends on t =back +=head2 Plugin C + +This plugin reads absolute air pressure using digital barometer sensor MPL115A2 +or MPL3115 from Freescale (sensor attached to any I2C bus available in +the computer, for HW details see +I or +I). +The sensor type - one fo these two - is detected automatically by the plugin +and indicated in the plugin_instance (typically you will see subdirectory +"barometer-mpl115" or "barometer-mpl3115"). + +The plugin provides absolute barometric pressure, air pressure reduced to sea +level (several possible approximations) and as an auxiliary value also internal +sensor temperature. It uses (expects/provides) typical metric units - pressure +in [hPa], temperature in [C], altitude in [m]. + +It was developed and tested under Linux only. The only platform dependency is +the standard Linux i2c-dev interface (the particular bus driver has to +support the SM Bus command subset). + +The reduction or normalization to mean sea level pressure requires (depedning on +selected method/approximation) also altitude and reference to temperature sensor(s). +When multiple temperature sensors are configured the minumum of their values is +always used (expecting that the warmer ones are affected by e.g. direct sun light +at that moment). + +Synopsis: + + + Device "/dev/i2c-0"; + Oversampling 512 + PressureOffset 0.0 + TemperatureOffset 0.0 + Normalization 2 + Altitude 238.0 + TemperatureSensor "myserver/onewire-F10FCA000800/temperature" + + +=over 4 + +=item B I + +Device name of the I2C bus to which the sensor is connected. Note that typically +you need to have loaded the i2c-dev module. +Using i2c-tools you can check/list i2c buses available on your system by: + + i2cdetect -l + +Then you can scan for devices on given bus. E.g. to scan the whole bus 0 use: + + i2cdetect -y -a 0 + +This way you should be able to verify that the pressure sensor (either type) is +connected and detected on address 0x60. + +=item B I + +For MPL115 this is the size of the averaging window. To filter out sensor noise +a simple averaging using floating window of configurable size is used. The plugin +will use average of the last C measurements (value of 1 means no averaging). +Minimal size is 1, maximal 1024. + +For MPL3115 this is the oversampling value. The actual oversampling is performed +by the sensor and the higher value the higher accuracy and longer conversion time +(although nothing to worry about in the collectd context). Supported values are: +1, 2, 4, 8, 16, 32, 64 and 128. Any other value is adjusted by the plugin to +the closest supported one. Default is 128. + +=item B I + +You can further calibrate the sensor by supplying pressure and/or temperature offsets. +This is added to the measured/caclulated value (i.e. if the measured value is too high +then use negative offset). +In hPa, default is 0.0. + +=item B I + +You can further calibrate the sensor by supplying pressure and/or temperature offsets. +This is added to the measured/caclulated value (i.e. if the measured value is too high +then use negative offset). +In C, default is 0.0. + +=item B I + +Normalization method - what approximation/model is used to compute mean sea +level pressure from the air absolute pressure. + +Supported values of the C (integer between from 0 to 2) are: + +=over 5 + +=item B<0> - no conversion, absolute pressrure is simply copied over. For this method you + do not need to configure C or C. + +=item B<1> - international formula for conversion , +See I. +For this method you have to configure C but do not need C +(uses fixed global temperature average instead). + +=item B<2> - formula as recommended by the Deutsche Wetterdienst (German +Meteorological Service). +See I +For this method you have to configure both C and C. + +=back + + +=item B I + +The altitude (in meters) of the location where you meassure the pressure. + +=item B I + +Temperature sensor which should be used as a reference when normalizing the pressure. +When specified more sensors a minumum is found and uses each time. +The temperature reading directly from this pressure sensor/plugin +is typically not suitable as the pressure sensor +will be probably inside while we want outside temperature. +The collectd reference name is something like +/-/- +( is usually omitted when there is just single value type). +Or you can figure it out from the path of the output data files. + +=back + =head2 Plugin C Starting with BIND 9.5.0, the most widely used DNS server software provides @@@ -963,17 -837,17 +978,17 @@@ Synopsis ParseTime false OpCodes true QTypes true - + ServerStats true ZoneMaintStats true ResolverStats false MemoryStats true - + QTypes true ResolverStats true CacheRRSets true - + Zone "127.in-addr.arpa/IN" @@@ -1114,44 -988,6 +1129,44 @@@ at all, B cgroups are selected =back +=head2 Plugin C + +This plugin collects IP conntrack statistics. + +=over 4 + +=item B + +Assume the B and B files to be found in +F instead of F. + +=back + +=head2 Plugin C + +The I collects CPU usage metrics. + +The following configuration options are available: + +=over 4 + +=item B B|B + +Reports non-idle CPU usage as the "active" value. Defaults to false. + +=item B B|B + +When true reports usage for all cores. When false, reports cpu usage +aggregated over all cores. +Defaults to true. + +=item B B|B + +When true report percentage usage instead of tick values. Defaults to false. + +=back + + =head2 Plugin C This plugin doesn't have any options. It reads @@@ -1225,10 -1061,6 +1240,10 @@@ Username to use if authorization is req Password to use if authorization is required to read the page. +=item B B|B + +Enable HTTP digest authentication. + =item B B|B Enable or disable peer SSL certificate verification. See @@@ -1339,25 -1171,12 +1354,25 @@@ The following options are valid within Sets the plugin instance to I. +=item B I + +Sets the interval (in seconds) in which the values will be collected from this +URL. By default the global B setting will be used. + =item B I + =item B I + +=item B B|B + =item B B|B + =item B B|B + =item B I + =item B
I
+ =item B I These options behave exactly equivalent to the appropriate options of the @@@ -1446,8 -1265,6 +1461,8 @@@ Examples =item B I +=item B B|B + =item B B|B =item B B|B @@@ -1687,16 -1504,6 +1702,16 @@@ it should be able to handle integer an There must be at least one B option inside each B block. +=item B [I I ...] + +Names the columns whose content is used as metadata for the data sets +that are dispatched to the daemon. + +The actual data type in the columns is not that important. The plugin will +automatically cast the values to the right type if it know how to do that. So +it should be able to handle integer an floating point types, as well as strings +(if they include a number at the beginning). + =back =head3 B blocks @@@ -1811,17 -1618,17 +1826,17 @@@ transfer agents and web caches =item B B|B -Enables or disables reporting of free, used and used disk space in 1K-blocks. -Defaults to true. +Enables or disables reporting of free and used disk space in 1K-blocks. +Defaults to B. -=item B B|B +=item B B|B -Enables or disables reporting of free, used and used disk space in percentage. -Defaults to false. +Enables or disables reporting of free and used disk space in percentage. +Defaults to B. -This is useful for deploying collectd on the cloud, where machines with -different disk size may exist. Then it is more practical to configure thresholds -based on relative disk size. +This is useful for deploying I on the cloud, where machines with +different disk size may exist. Then it is more practical to configure +thresholds based on relative disk size. =back @@@ -1857,20 -1664,6 +1872,20 @@@ collected. If at least one B opti set to B, B matching disks will be collected. If B is set to B, all disks are collected B the ones matched. +=item B B|B + +Whether to use the device's "BSD Name", on MacEOSEX, instead of the +default major/minor numbers. Requires collectd to be built with Apple's +IOKitLib support. + +=item B I + +Attempt to override disk instance name with the value of a specified udev +attribute when built with B. If the attribute is not defined for the +given device, the default name is used. Example: + + UdevNameAttr "DM_NAME" + =back =head2 Plugin C @@@ -2419,35 -2212,8 +2434,35 @@@ 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 + +When the libvirt 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. + +B means use the guest's UUID. + =back +=head2 Plugin C + +The I collects the system load. These numbers give a rough overview +over the utilization of a machine. The system load is defined as the number of +runnable tasks in the run-queue and is provided by many operating systems as a +one, five or fifteen minute average. + +The following configuration options are available: + +=over 4 + +=item B B|B + +When enabled, system load divided by number of available CPU cores is reported +for intervals 1 min, 5 min and 15 min. Defaults to false. + +=back + + =head2 Plugin C =over 4 @@@ -2482,34 -2248,6 +2497,34 @@@ B: There is no need to notify th log file (e.Eg. when rotating the logs). The plugin reopens the file for each line it writes. +=head2 Plugin C + +The I behaves like the logfile plugin but formats +messages as JSON events for logstash to parse and input. + +=over 4 + +=item B B + +Sets the log-level. If, for example, set to B, then all events with +severity B, B, or B will be written to the logfile. + +Please note that B is only available if collectd has been compiled with +debugging support. + +=item B I + +Sets the file to write log messages to. The special strings B and +B can be used to write to the standard output and standard error +channels, respectively. This, of course, only makes much sense when I +is running in foreground- or non-daemon-mode. + +=back + +B: There is no need to notify the daemon after moving or removing the +log file (e.Eg. when rotating the logs). The plugin reopens the file +for each line it writes. + =head2 Plugin C The I reads CPU statistics of I, a @@@ -2683,7 -2421,7 +2698,7 @@@ B The following options are valid inside the Bmic> block: @@@ -2701,7 -2439,7 +2716,7 @@@ =item B B|B -If enabled (the default) a sum of the CPU usage accross all cores is reported. +If enabled (the default) a sum of the CPU usage across all cores is reported. =item B B|B @@@ -2749,7 -2487,7 +2764,7 @@@ Fan I =item fout -Fan Out +Fan Out =item vccp @@@ -2790,11 -2528,11 +2805,11 @@@ Known power names are =item total0 -Total power utilization averaged over Time Window 0 (uWatts). +Total power utilization averaged over Time Window 0 (uWatts). =item total1 -Total power utilization averaged over Time Window 0 (uWatts). +Total power utilization averaged over Time Window 0 (uWatts). =item inst @@@ -2802,55 -2540,34 +2817,55 @@@ Instantaneous power (uWatts) =item imax -Max instantaneous power (uWatts). +Max instantaneous power (uWatts). =item pcie -PCI-E connector power (uWatts). +PCI-E connector power (uWatts). =item c2x3 -2x3 connector power (uWatts). +2x3 connector power (uWatts). =item c2x4 -2x4 connector power (uWatts). +2x4 connector power (uWatts). =item vccp -Core rail (uVolts). +Core rail (uVolts). =item vddg -Uncore rail (uVolts). +Uncore rail (uVolts). =item vddq -Memory subsystem rail (uVolts). +Memory subsystem rail (uVolts). + +=back =back +=head2 Plugin C + +The I provides the following configuration options: + +=over 4 + +=item B B|B + +Enables or disables reporting of physical memory usage in absolute numbers, +i.e. bytes. Defaults to B. + +=item B B|B + +Enables or disables reporting of physical memory usage in percentages, e.g. +percent of physical memory used. Defaults to B. + +This is useful for deploying I in a heterogeneous environment in +which the sizes of physical memory vary. + =back =head2 Plugin C @@@ -2868,19 -2585,19 +2883,19 @@@ B - + RegisterBase 2 RegisterType float Type voltage Instance "input-2" - + Address "192.168.0.42" Port "502" Interval 60 - + Instance "power-supply" Collect "voltage-input-1" @@@ -3011,11 -2728,9 +3026,11 @@@ Synopsis Password "password" Port "3306" MasterStats true + ConnectTimeout 10 + Alias "squeeze" Host "localhost" Socket "/var/run/mysql/mysqld.sock" SlaveStats true @@@ -3030,11 -2745,6 +3045,11 @@@ section "mysql_real_connect()" in the B =over 4 +=item B I + +Alias to use as sender instead of hostname when reporting. This may be useful +when having cryptic hostnames. + =item B I Hostname of the database server. Defaults to B. @@@ -3073,11 -2783,6 +3088,11 @@@ only has any effect, if B is set Otherwise, use the B option above. See the documentation for the C function for details. +=item B I + +If enabled, metrics about the InnoDB storage engine are collected. +Disabled by default. + =item B I =item B I @@@ -3091,10 -2796,6 +3106,10 @@@ privileges. See the B documentati If enabled, the plugin sends a notification if the replication slave I/O and / or SQL threads are not running. +=item B I + +Sets the connect timeout for the MySQL client. + =back =head2 Plugin C @@@ -3129,7 -2830,7 +3144,7 @@@ Required capabilities are documented be User "username" Password "aef4Aebe" Interval 30 - + Interval 30 GetNameCache true @@@ -3137,12 -2838,12 +3152,12 @@@ GetBufferCache true GetInodeCache true - + Interval 30 GetBusy true - + Interval 30 GetIO "volume0" @@@ -3152,7 -2853,7 +3167,7 @@@ GetLatency "volume0" IgnoreSelectedLatency false - + Interval 30 GetCapacity "vol0" @@@ -3162,15 -2863,15 +3177,15 @@@ GetSnapshot "vol3" IgnoreSelectedSnapshot false - + Interval 60 - + Interval 30 - + Interval 30 GetCPULoad true @@@ -3731,7 -3432,7 +3746,7 @@@ signature) # Export to an internal server # (demonstrates usage without additional options) Server "collectd.internal.tld" - + # Export to an external server # (demonstrates usage with signature options) @@@ -4120,36 -3821,13 +4135,36 @@@ B See notes below The C plugin uses the B library from the B project L to read sensors connected via the onewire bus. -Currently only temperature sensors (sensors with the family code C<10>, -e.Eg. DS1820, DS18S20, DS1920) can be read. If you have other sensors you -would like to have included, please send a sort request to the mailing list. +It can be used in two possible modes - standard or advanced. + +In the standard mode only temperature sensors (sensors with the family code +C<10>, C<22> and C<28> - e.g. DS1820, DS18S20, DS1920) can be read. If you have +other sensors you would like to have included, please send a sort request to +the mailing list. You can select sensors to be read or to be ignored depending +on the option B). When no list is provided the whole bus is +walked and all sensors are read. Hubs (the DS2409 chips) are working, but read the note, why this plugin is experimental, below. +In the advanced mode you can configure any sensor to be read (only numerical +value) using full OWFS path (e.g. "/uncached/10.F10FCA000800/temperature"). +In this mode you have to list all the sensors. Neither default bus walk nor +B are used here. Address and type (file) is extracted from +the path automatically and should produce compatible structure with the "standard" +mode (basically the path is expected as for example +"/uncached/10.F10FCA000800/temperature" where it would extract address part +"F10FCA000800" and the rest after the slash is considered the type - here +"temperature"). +There are two advantages to this mode - you can access virtually any sensor +(not just temperature), select whether to use cached or directly read values +and it is slighlty faster. The downside is more complex configuration. + +The two modes are distinguished automatically by the format of the address. +It is not possible to mix the two modes. Once a full path is detected in any +B then the whole addressing (all sensors) is considered to be this way +(and as standard addresses will fail parsing they will be ignored). + =over 4 =item B I @@@ -4170,23 -3848,14 +4185,23 @@@ This directive is B and does =item B I -Selects sensors to collect or to ignore, depending on B, see -below. Sensors are specified without the family byte at the beginning, to you'd -use C, and B include the leading C<10.> family byte and -point. +In the standard mode selects sensors to collect or to ignore +(depending on B, see below). Sensors are specified without +the family byte at the beginning, so you have to use for example C, +and B include the leading C<10.> family byte and point. +When no B is configured the whole Onewire bus is walked and all supported +sensors (see above) are read. + +In the advanced mode the B specifies full OWFS path - e.g. +C (or when cached values are OK +C). B is not used. + +As there can be multiple devices on the bus you can list multiple sensor (use +multiple B elements). =item B I|I -If no configuration if given, the B plugin will collect data from all +If no configuration is given, the B plugin will collect data from all sensors found. This may not be practical, especially if sensors are added and removed regularly. Sometimes, however, it's easier/preferred to collect only specific sensors or all sensors I a few specified ones. This option @@@ -4194,8 -3863,6 +4209,8 @@@ enables you to do that: By setting B is inverted: All selected interfaces are ignored and all other interfaces are collected. +Used only in the standard mode - see above. + =item B I Sets the interval in which all sensors should be read. If not specified, the @@@ -4872,6 -4539,13 +4887,6 @@@ Specify the password to be used when co Specify whether to use an SSL connection when contacting the server. The following modes are supported: -=item B I - -Specify the plugin instance name that should be used instead of the database -name (which is the default, if this option has not been specified). This -allows to query multiple databases of the same name on the same host (e.g. -when running multiple database server versions in parallel). - =over 4 =item I @@@ -4892,13 -4566,6 +4907,13 @@@ Use SSL only =back +=item B I + +Specify the plugin instance name that should be used instead of the database +name (which is the default, if this option has not been specified). This +allows to query multiple databases of the same name on the same host (e.g. +when running multiple database server versions in parallel). + =item B I Specify the Kerberos service name to use when authenticating with Kerberos 5 @@@ -5685,19 -5352,6 +5700,19 @@@ This option is only available if the I< When enabled, the I is reported in bytes. When disabled, the default, I is reported in pages. This option is available under Linux only. +=item B B|B + +Enables or disables reporting of absolute swap metrics, i.e. number of I +available and used. Defaults to B. + +=item B B|B + +Enables or disables reporting of relative swap metrics, i.e. I +available and free. Defaults to B. + +This is useful for deploying I in a heterogeneous environment, where +swap sizes differ and you want to specify generic thresholds or similar. + =back =head2 Plugin C @@@ -5833,7 -5487,6 +5848,7 @@@ user using (extended) regular expressio Instance "exim" + Interval 60 Regex "S=([1-9][0-9]*)" DSType "CounterAdd" @@@ -5860,9 -5513,6 +5875,9 @@@ This plugin instance is for all B option. This way you can extract several plugin instances from one logfile, handy when parsing syslog and the like. +The B option allows you to define the length of time between reads. If +this is not set, the default Interval will be used. + Each B block has the following options to describe how the match should be performed: @@@ -6512,65 -6162,12 +6527,65 @@@ instance) are put into one component, f =item B B|B - If set the B, append the name of the I (DS) to the "metric" + If set to B, append the name of the I (DS) to the "metric" identifier. If set to B (the default), this is only done when there is more than one DS. =back +=head2 Plugin C + +The C plugin writes data to I, a scalable open-source +time series database. The plugin connects to a I, a masterless, no shared +state daemon that ingests metrics and stores them in HBase. The plugin uses +I over the "line based" protocol with a default port 4242. The data will +be sent in blocks of at most 1428 bytes to minimize the number of network +packets. + +Synopsis: + + + + Host "tsd-1.my.domain" + Port "4242" + HostTags "status=production" + + + +The configuration consists of one or more EBEIE +blocks. Inside the B blocks, the following options are recognized: + +=over 4 + +=item B I
+ +Hostname or address to connect to. Defaults to C. + +=item B I + +Service name or port number to connect to. Defaults to C<4242>. + + +=item B I + +When set, I is added to the end of the metric. It is intended to be +used for name=value pairs that the TSD will tag the metric with. Dots and +whitespace are I escaped in this string. + +=item B B|B + +If set to B, convert counter values to rates. If set to B +(the default) counter values are stored as is, as an increasing +integer number. + +=item B B|B + +If set the B, append the name of the I (DS) to the "metric" +identifier. If set to B (the default), this is only done when there is +more than one DS. + +=back + =head2 Plugin C The I will send values to I, a schema-less @@@ -6672,33 -6269,6 +6687,33 @@@ File that holds one or more SSL certifi possibly need this option. What CA certificates come bundled with C and are checked by default depends on the distribution you use. +=item B I + +Directory holding one or more CA certificate files. You can use this if for +some reason all the needed CA certificates aren't in the same file and can't be +pointed to using the B option. Requires C to be built against +OpenSSL. + +=item B I + +File that holds the private key in PEM format to be used for certificate-based +authentication. + +=item B I + +File that holds the SSL certificate to be used for certificate-based +authentication. + +=item B I + +Password required to load the private key in B. + +=item B B|B|B|B|B|B + +Define which SSL protocol version must be used. By default C will +attempt to figure out the remote SSL protocol version. See +L for more details. + =item B B|B Format of the output to generate. If set to B, will create output that @@@ -6715,114 -6285,9 +6730,114 @@@ number =back +=head2 Plugin C + +The I will send values to a I topic, a distributed +queue. +Synopsis: + + + Property "metadata.broker.list" "broker1:9092,broker2:9092" + + Format JSON + + + +The following options are understood by the I: + +=over 4 + +=item EB IE + +The plugin's configuration consists of one or more B blocks. Each block +is given a unique I and specifies one kafka producer. +Inside the B block, the following per-topic options are +understood: + +=over 4 + +=item B I I + +Configure the named property for the current topic. Properties are +forwarded to the kafka producer library B. + +=item B I + +Use the specified string as a partioning key for the topic. Kafka breaks +topic into partitions and guarantees that for a given topology, the same +consumer will be used for a specific key. The special (case insensitive) +string B can be used to specify that an arbitrary partition should +be used. + +=item B B|B|B + +Selects the format in which messages are sent to the broker. If set to +B (the default), values are sent as C commands which are +identical to the syntax used by the I and I. + +If set to B, the values are encoded in the I, +an easy and straight forward exchange format. + +If set to B, values are encoded in the I format, which is +" \n". + +=item B B|B + +Determines whether or not C, C and C data sources +are converted to a I (i.e. a C value). If set to B (the +default), no conversion is performed. Otherwise the conversion is performed +using the internal value cache. + +Please note that currently this option is only used if the B option has +been set to B. + +=item B (B=I only) + +A prefix can be added in the metric name when outputting in the I format. +It's added before the I name. +Metric name will be "" + +=item B (B=I only) + +A postfix can be added in the metric name when outputting in the I format. +It's added after the I name. +Metric name will be "" + +=item B (B=I only) + +Specify a character to replace dots (.) in the host part of the metric name. +In I metric name, dots are used as separators between different +metric parts (host, plugin, type). +Default is "_" (I). + +=item B B|B + +If set to B, the plugin instance and type instance will be in their own +path component, for example C. If set to B (the +default), the plugin and plugin instance (and likewise the type and type +instance) are put into one component, for example C. + +=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. + +This will be reflected in the C tag: If B is enabled, +converted values will have "rate" appended to the data source type, e.g. +C. + +=back + +=item B I I + +Configure the kafka producer through properties, you almost always will +want to set B to your Kafka broker list. + +=back + =head2 Plugin C -The I will send values to I, a powerfull stream +The I will send values to I, a powerful stream aggregation and monitoring system. The plugin sends I encoded data to I using UDP packets. @@@ -6838,7 -6303,6 +6853,7 @@@ Synopsis TTLFactor 2.0 Tag "foobar" + Attribute "foo" "bar" The following options are understood by the I: @@@ -6892,17 -6356,6 +6907,17 @@@ interval is multiplied to set the TTL. know exactly what you're doing, you should only increase this setting from its default value. +=item B B|B + +If set to B, create riemann events for notifications. This is B +by default. When processing thresholds from write_riemann, it might prove +useful to avoid getting notification events. + +=item B B|B + +If set to B, attach state to events based on thresholds defined +in the B plugin. Defaults to B. + =back =item B I @@@ -6910,11 -6363,6 +6925,11 @@@ Add the given string as an additional tag to the metric being sent to I. +=item B I I + +Consider the two given strings to be the key and value of an additional +attribute for each metric being sent out to I. + =back =head1 THRESHOLD CONFIGURATION @@@ -7387,19 -6835,36 +7402,36 @@@ Available options =item B I Name of the write plugin to which the data should be sent. This option may be - given multiple times to send the data to more than one write plugin. + given multiple times to send the data to more than one write plugin. If the + plugin supports multiple instances, the plugin's instance(s) must also be + specified. =back If no plugin is explicitly specified, the values will be sent to all available write plugins. - Example: + Single-instance plugin example: Plugin "rrdtool" + Multi-instance plugin example: + + + + ... + + + ... + + + ... + + Plugin "write_graphite/foo" + + =item B Starts processing the rules of another chain, see L<"Flow control"> above. If @@@ -7569,7 -7034,7 +7601,7 @@@ Example Max 100 Satisfy "All" - + # Match if the value of any data source is outside the range of 0 - 100. Min 0 @@@ -7751,7 -7216,7 +7783,7 @@@ Example # Replace "example.net" with "example.com" Host "\\" "example.com" - + # Strip "www." from hostnames Host "\\ @@@ -7834,6 -7299,6 +7866,6 @@@ Locto@verplant.orgE +Florian Forster Eocto@collectd.orgE =cut diff --combined src/common.c index 93c1ca17,dc77e02f..8691d3eb --- a/src/common.c +++ b/src/common.c @@@ -1,24 -1,19 +1,24 @@@ /** * collectd - src/common.c - * Copyright (C) 2005-2010 Florian octo Forster + * Copyright (C) 2005-2014 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * 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 @@@ -382,10 -377,8 +382,10 @@@ int strunescape (char *buf, size_t buf_ if (buf[i] != '\\') continue; - if ((i >= buf_len) || (buf[i + 1] == '\0')) { + if (((i + 1) >= buf_len) || (buf[i + 1] == 0)) { ERROR ("string unescape: backslash found at end of string."); + /* Ensure null-byte at the end of the buffer. */ + buf[i] = 0; return (-1); } @@@ -404,10 -397,7 +404,10 @@@ break; } + /* Move everything after the position one position to the left. + * Add a null-byte as last character in the buffer. */ memmove (buf + i + 1, buf + i + 2, buf_len - i - 2); + buf[buf_len - 1] = 0; } return (0); } /* int strunescape */ @@@ -428,36 -418,34 +428,36 @@@ size_t strstripnewline (char *buffer return (buffer_len); } /* size_t strstripnewline */ -int escape_slashes (char *buf, int buf_len) +int escape_slashes (char *buffer, size_t buffer_size) { int i; + size_t buffer_len; - if (strcmp (buf, "/") == 0) - { - if (buf_len < 5) - return (-1); + buffer_len = strlen (buffer); - strncpy (buf, "root", buf_len); + if (buffer_len <= 1) + { + if (strcmp ("/", buffer) == 0) + { + if (buffer_size < 5) + return (-1); + sstrncpy (buffer, "root", buffer_size); + } return (0); } - if (buf_len <= 1) - return (0); - /* Move one to the left */ - if (buf[0] == '/') - memmove (buf, buf + 1, buf_len - 1); + if (buffer[0] == '/') + { + memmove (buffer, buffer + 1, buffer_len); + buffer_len--; + } - for (i = 0; i < buf_len - 1; i++) + for (i = 0; i < buffer_len - 1; i++) { - if (buf[i] == '\0') - break; - else if (buf[i] == '/') - buf[i] = '_'; + if (buffer[i] == '/') + buffer[i] = '_'; } - buf[i] = '\0'; return (0); } /* int escape_slashes */ @@@ -660,7 -648,7 +660,7 @@@ int get_kstat (kstat_t **ksp_ptr, char char ident[128]; *ksp_ptr = NULL; - + if (kc == NULL) return (-1); @@@ -1073,9 -1061,9 +1073,9 @@@ int parse_value (const char *value_orig } if (value == endptr) { - sfree (value); ERROR ("parse_value: Failed to parse string as %s: %s.", DS_TYPE_TO_STRING (ds_type), value); + sfree (value); return -1; } else if ((NULL != endptr) && ('\0' != *endptr)) @@@ -1246,7 -1234,7 +1246,7 @@@ int walk_directory (const char *dir, di while ((ent = readdir (dh)) != NULL) { int status; - + if (include_hidden) { if ((strcmp (".", ent->d_name) == 0) @@@ -1409,69 -1397,6 +1409,69 @@@ int rate_to_value (value_t *ret_value, return (0); } /* }}} value_t rate_to_value */ +int value_to_rate (value_t *ret_rate, derive_t value, /* {{{ */ + value_to_rate_state_t *state, + int ds_type, cdtime_t t) +{ + double interval; + + /* Another invalid state: The time is not increasing. */ + if (t <= state->last_time) + { + memset (state, 0, sizeof (*state)); + return (EINVAL); + } + + interval = CDTIME_T_TO_DOUBLE(t - state->last_time); + + /* Previous value is invalid. */ + if (state->last_time == 0) /* {{{ */ + { + if (ds_type == DS_TYPE_DERIVE) + { + state->last_value.derive = value; + } + else if (ds_type == DS_TYPE_COUNTER) + { + state->last_value.counter = (counter_t) value; + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + state->last_value.absolute = (absolute_t) value; + } + else + { + assert (23 == 42); + } + + state->last_time = t; + return (EAGAIN); + } /* }}} */ + + if (ds_type == DS_TYPE_DERIVE) + { + ret_rate->gauge = (value - state->last_value.derive) / interval; + state->last_value.derive = value; + } + else if (ds_type == DS_TYPE_COUNTER) + { + ret_rate->gauge = (((counter_t)value) - state->last_value.counter) / interval; + state->last_value.counter = (counter_t) value; + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + ret_rate->gauge = (((absolute_t)value) - state->last_value.absolute) / interval; + state->last_value.absolute = (absolute_t) value; + } + else + { + assert (23 == 42); + } + + state->last_time = t; + return (0); +} /* }}} value_t rate_to_value */ + int service_name_to_port_number (const char *service_name) { struct addrinfo *ai_list; diff --combined src/configfile.c index 855681b5,ec39b760..d2a307d9 --- a/src/configfile.c +++ b/src/configfile.c @@@ -2,23 -2,19 +2,23 @@@ * collectd - src/configfile.c * Copyright (C) 2005-2011 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * 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 @@@ -481,6 -477,12 +481,12 @@@ static int cf_ci_replace_child (oconfig /* Resize the memory containing the children to be big enough to hold * all children. */ + if (dst->children_num + src->children_num - 1 == 0) + { + dst->children_num = 0; + return (0); + } + temp = (oconfig_item_t *) realloc (dst->children, sizeof (oconfig_item_t) * (dst->children_num + src->children_num - 1)); @@@ -595,7 -597,8 +601,8 @@@ static int cf_include_all (oconfig_item return (-1); /* Now replace the i'th child in `root' with `new'. */ - cf_ci_replace_child (root, new, i); + if (cf_ci_replace_child (root, new, i) < 0) + return (-1); /* ... and go back to the new i'th child. */ --i; @@@ -895,13 -898,6 +902,13 @@@ int global_option_set (const char *opti if (i >= cf_global_options_num) return (-1); + if (strcasecmp (option, "PIDFile") == 0 && pidfile_from_cli == 1) + { + DEBUG ("Configfile: Ignoring `PIDFILE' option because " + "command-line option `-P' take precedence."); + return (0); + } + sfree (cf_global_options[i].value); if (value != NULL) diff --combined src/curl.c index 3e7c5a5d,1f78f821..f605c078 --- a/src/curl.c +++ b/src/curl.c @@@ -17,7 -17,7 +17,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Aman Gupta **/ @@@ -58,7 -58,6 +58,7 @@@ struct web_page_s /* {{{ * char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; @@@ -365,7 -364,8 +365,7 @@@ static int cc_page_init_curl (web_page_ curl_easy_setopt (wp->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback); curl_easy_setopt (wp->curl, CURLOPT_WRITEDATA, wp); - curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, - PACKAGE_NAME"/"PACKAGE_VERSION); + curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf); curl_easy_setopt (wp->curl, CURLOPT_URL, wp->url); curl_easy_setopt (wp->curl, CURLOPT_FOLLOWLOCATION, 1L); @@@ -389,13 -389,6 +389,13 @@@ ssnprintf (wp->credentials, credentials_size, "%s:%s", wp->user, (wp->pass == NULL) ? "" : wp->pass); curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials); + + if (wp->digest) + { + curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user); + curl_easy_setopt (wp->curl, CURLOPT_PASSWORD, wp->pass); + } } curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer); @@@ -433,7 -426,6 +433,7 @@@ static int cc_config_add_page (oconfig_ page->url = NULL; page->user = NULL; page->pass = NULL; + page->digest = 0; page->verify_peer = 1; page->verify_host = 1; page->response_time = 0; @@@ -459,8 -451,6 +459,8 @@@ status = cf_util_get_string (child, &page->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &page->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &page->digest); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &page->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) @@@ -579,6 -569,7 +579,7 @@@ static int cc_init (void) /* {{{ * INFO ("curl plugin: No pages have been defined."); return (-1); } + curl_global_init (CURL_GLOBAL_SSL); return (0); } /* }}} int cc_init */ diff --combined src/curl_json.c index 6a015902,9e0f6723..a84cba04 --- a/src/curl_json.c +++ b/src/curl_json.c @@@ -71,13 -71,11 +71,13 @@@ struct cj_s /* {{{ * char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; struct curl_slist *headers; char *post_body; + cdtime_t interval; CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; @@@ -589,7 -587,8 +589,7 @@@ static int cj_init_curl (cj_t *db) /* { curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cj_curl_callback); curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); - curl_easy_setopt (db->curl, CURLOPT_USERAGENT, - PACKAGE_NAME"/"PACKAGE_VERSION); + curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); @@@ -611,13 -610,6 +611,13 @@@ ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + + if (db->digest) + { + curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass); + } } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer); @@@ -684,8 -676,6 +684,8 @@@ static int cj_config_add_url (oconfig_i status = cf_util_get_string (child, &db->user); else if (db->url && strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &db->digest); else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (db->url && strcasecmp ("VerifyHost", child->key) == 0) @@@ -698,8 -688,6 +698,8 @@@ status = cf_util_get_string (child, &db->post_body); else if (strcasecmp ("Key", child->key) == 0) status = cj_config_add_key (db, child); + else if (strcasecmp ("Interval", child->key) == 0) + status = cf_util_get_cdtime(child, &db->interval); else { WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key); @@@ -726,10 -714,7 +726,10 @@@ if (status == 0) { user_data_t ud; - char cb_name[DATA_MAX_NAME_LEN]; + char *cb_name; + struct timespec interval = { 0, 0 }; + + CDTIME_T_TO_TIMESPEC (db->interval, &interval); if (db->instance == NULL) db->instance = strdup("default"); @@@ -741,12 -726,12 +741,13 @@@ ud.data = (void *) db; ud.free_func = cj_free; - ssnprintf (cb_name, sizeof (cb_name), "curl_json-%s-%s", + cb_name = ssnprintf_alloc ("curl_json-%s-%s", db->instance, db->url ? db->url : db->sock); - plugin_register_complex_read (/* group = */ "curl_json", cb_name, cj_read, - /* interval = */ NULL, &ud); + plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read, + /* interval = */ (db->interval > 0) ? &interval : NULL, + &ud); + sfree (cb_name); } else { @@@ -816,10 -801,11 +817,10 @@@ static void cj_submit (cj_t *db, cj_key if (key->instance == NULL) { - if ((db->depth == 0) || (strcmp ("", db->state[db->depth-1].name) == 0)) - sstrncpy (vl.type_instance, db->state[db->depth].name, sizeof (vl.type_instance)); - else - ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", - db->state[db->depth-1].name, db->state[db->depth].name); + int i, len = 0; + for (i = 0; i < db->depth; i++) + len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len, + i ? "-%s" : "%s", db->state[i+1].name); } else sstrncpy (vl.type_instance, key->instance, sizeof (vl.type_instance)); @@@ -829,9 -815,6 +830,9 @@@ sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, key->type, sizeof (vl.type)); + if (db->interval > 0) + vl.interval = db->interval; + plugin_dispatch_values (&vl); } /* }}} int cj_submit */ @@@ -975,9 -958,18 +976,18 @@@ static int cj_read (user_data_t *ud) / return cj_perform (db); } /* }}} int cj_read */ + static int cj_init (void) /* {{{ */ + { + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init (CURL_GLOBAL_SSL); + return (0); + } /* }}} int cj_init */ + void module_register (void) { plugin_register_complex_config ("curl_json", cj_config); + plugin_register_init ("curl_json", cj_init); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --combined src/curl_xml.c index 6d36d29d,7432edf3..a743753e --- a/src/curl_xml.c +++ b/src/curl_xml.c @@@ -76,7 -76,6 +76,7 @@@ struct cx_s /* {{{ * char *user; char *pass; char *credentials; + _Bool digest; _Bool verify_peer; _Bool verify_host; char *cacert; @@@ -386,7 -385,7 +386,7 @@@ static int cx_handle_instance_xpath (xm /* If the base xpath returns more than one block, the result is assumed to be * a table. The `Instance' option is not optional in this case. Check for the * condition and inform the user. */ - if (is_table && (vl->type_instance == NULL)) + if (is_table) { WARNING ("curl_xml plugin: " "Base-XPath %s is a table (more than one result was returned), " @@@ -839,7 -838,8 +839,7 @@@ static int cx_init_curl (cx_t *db) /* { curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); - curl_easy_setopt (db->curl, CURLOPT_USERAGENT, - PACKAGE_NAME"/"PACKAGE_VERSION); + curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); @@@ -861,13 -861,6 +861,13 @@@ ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); + + if (db->digest) + { + curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); + curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass); + } } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); @@@ -934,8 -927,6 +934,8 @@@ static int cx_config_add_url (oconfig_i status = cf_util_get_string (child, &db->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); + else if (strcasecmp ("Digest", child->key) == 0) + status = cf_util_get_boolean (child, &db->digest); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) @@@ -1042,9 -1033,18 +1042,18 @@@ static int cx_config (oconfig_item_t *c return (0); } /* }}} int cx_config */ + static int cx_init (void) /* {{{ */ + { + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init (CURL_GLOBAL_SSL); + return (0); + } /* }}} int cx_init */ + void module_register (void) { plugin_register_complex_config ("curl_xml", cx_config); + plugin_register_init ("curl_xml", cx_init); } /* void module_register */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --combined src/exec.c index d56c07fa,b9a7365e..cb6844b8 --- a/src/exec.c +++ b/src/exec.c @@@ -18,7 -18,7 +18,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Sebastian Harl * Peter Holik **/ @@@ -744,8 -744,8 +744,8 @@@ static void *exec_notification_one (voi fprintf (fh, "Severity: %s\n" - "Time: %.3f\n", - severity, CDTIME_T_TO_DOUBLE (n->time)); + "Time: %u\n", + severity, (unsigned int)CDTIME_T_TO_TIME_T(n->time)); /* Print the optional fields */ if (strlen (n->host) > 0) diff --combined src/lvm.c index 9e245423,12c621d0..82d7f6fe --- a/src/lvm.c +++ b/src/lvm.c @@@ -1,7 -1,6 +1,7 @@@ /** * collectd - src/lvm.c * Copyright (C) 2013 Chad Malfait + * Copyright (C) 2014 Carnegie Mellon University * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@@ -18,7 -17,6 +18,7 @@@ * * Authors: * Chad Malfait + * Benjamin Gilbert **/ #include @@@ -27,30 -25,6 +27,30 @@@ #include "common.h" #include "plugin.h" +#define NO_VALUE UINT64_MAX +#define PERCENT_SCALE_FACTOR 1e-8 + +static uint64_t get_lv_property_int(lv_t lv, char const *property) +{ + lvm_property_value_t v; + + v = lvm_lv_get_property(lv, property); + if (!v.is_valid || !v.is_integer) + return NO_VALUE; + /* May be NO_VALUE if @property does not apply to this LV */ + return v.value.integer; +} + +static char const *get_lv_property_string(lv_t lv, char const *property) +{ + lvm_property_value_t v; + + v = lvm_lv_get_property(lv, property); + if (!v.is_valid || !v.is_string) + return NULL; + return v.value.string; +} + static void lvm_submit (char const *plugin_instance, char const *type_instance, uint64_t ivalue) { @@@ -71,91 -45,24 +71,95 @@@ plugin_dispatch_values (&vl); } -static int vg_read(vg_t vg, char const *vg_name) +static void report_lv_utilization(lv_t lv, char const *vg_name, + char const *lv_name, uint64_t lv_size, + char const *used_percent_property) +{ + uint64_t used_percent_unscaled; + uint64_t used_bytes; + char plugin_instance[DATA_MAX_NAME_LEN]; + + used_percent_unscaled = get_lv_property_int(lv, used_percent_property); + if (used_percent_unscaled == NO_VALUE) + return; + used_bytes = lv_size * (used_percent_unscaled * PERCENT_SCALE_FACTOR); + + ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", + vg_name, lv_name); + lvm_submit(plugin_instance, "used", used_bytes); + lvm_submit(plugin_instance, "free", lv_size - used_bytes); +} + +static void report_thin_pool_utilization(lv_t lv, char const *vg_name, + uint64_t lv_size) +{ + char const *data_lv; + char const *metadata_lv; + uint64_t metadata_size; + + data_lv = get_lv_property_string(lv, "data_lv"); + metadata_lv = get_lv_property_string(lv, "metadata_lv"); + metadata_size = get_lv_property_int(lv, "lv_metadata_size"); + if (data_lv == NULL || metadata_lv == NULL || metadata_size == NO_VALUE) + return; + + report_lv_utilization(lv, vg_name, data_lv, lv_size, "data_percent"); + report_lv_utilization(lv, vg_name, metadata_lv, metadata_size, + "metadata_percent"); +} + +static void vg_read(vg_t vg, char const *vg_name) { struct dm_list *lvs; struct lvm_lv_list *lvl; + char const *name; + char const *attrs; + uint64_t size; lvm_submit (vg_name, "free", lvm_vg_get_free_size(vg)); lvs = lvm_vg_list_lvs(vg); if (!lvs) { /* no VGs are defined, which is not an error per se */ - return (0); + return; } dm_list_iterate_items(lvl, lvs) { + lvm_submit(vg_name, lvm_lv_get_name(lvl->lv), lvm_lv_get_size(lvl->lv)); + } + - return (0); ++ dm_list_iterate_items(lvl, lvs) { + name = lvm_lv_get_name(lvl->lv); + attrs = get_lv_property_string(lvl->lv, "lv_attr"); + size = lvm_lv_get_size(lvl->lv); + if (name == NULL || attrs == NULL || size == NO_VALUE) + continue; + + /* Condition on volume type. We want the reported sizes in the + volume group to sum to the size of the volume group, so we ignore + virtual volumes. */ + switch (attrs[0]) { + case 's': + case 'S': + /* Snapshot. Also report used/free space. */ + report_lv_utilization(lvl->lv, vg_name, name, size, + "data_percent"); + break; + case 't': + /* Thin pool virtual volume. We report the underlying data + and metadata volumes, not this one. Report used/free + space, then ignore. */ + report_thin_pool_utilization(lvl->lv, vg_name, size); + continue; + case 'v': + /* Virtual volume. Ignore. */ + continue; + case 'V': + /* Thin volume or thin snapshot. Ignore. */ + continue; + } + lvm_submit(vg_name, name, size); + } } static int lvm_read(void) diff --combined src/network.c index 5769da79,1b6cf1ea..b1919833 --- a/src/network.c +++ b/src/network.c @@@ -501,8 -501,15 +501,15 @@@ static void network_init_gcrypt (void) if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P)) return; - gcry_check_version (NULL); /* before calling any other functions */ + /* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html + * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS + * *before* initalizing Libgcrypt with gcry_check_version(), which itself must + * be called before any other gcry_* function. GCRYCTL_ANY_INITIALIZATION_P + * above doesn't count, as it doesn't implicitly initalize Libgcrypt. + * + * tl;dr: keep all these gry_* statements in this exact order please. */ gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); + gcry_check_version (NULL); gcry_control (GCRYCTL_INIT_SECMEM, 32768); gcry_control (GCRYCTL_INITIALIZATION_FINISHED); } /* }}} void network_init_gcrypt */ @@@ -2897,10 -2904,6 +2904,10 @@@ static int network_config_set_ttl (cons tmp = (int) ci->values[0].value.number; if ((tmp > 0) && (tmp <= 255)) network_config_ttl = tmp; + else { + WARNING ("network plugin: The `TimeToLive' must be between 1 and 255."); + return (-1); + } return (0); } /* }}} int network_config_set_ttl */ @@@ -3163,14 -3166,6 +3170,14 @@@ static int network_config (oconfig_item { int i; + /* The options need to be applied first */ + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + if (strcasecmp ("TimeToLive", child->key) == 0) + network_config_set_ttl (child); + } + for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@@ -3179,9 -3174,8 +3186,9 @@@ network_config_add_listen (child); else if (strcasecmp ("Server", child->key) == 0) network_config_add_server (child); - else if (strcasecmp ("TimeToLive", child->key) == 0) - network_config_set_ttl (child); + else if (strcasecmp ("TimeToLive", child->key) == 0) { + /* Handled earlier */ + } else if (strcasecmp ("MaxPacketSize", child->key) == 0) network_config_set_buffer_size (child); else if (strcasecmp ("Forward", child->key) == 0) diff --combined src/processes.c index 210e6f15,c8e7b826..5601d290 --- a/src/processes.c +++ b/src/processes.c @@@ -25,7 -25,7 +25,7 @@@ * * Authors: * Lyonel Vincent - * Florian octo Forster + * Florian octo Forster * Oleg King * Sebastian Harl * Andrés J. Díaz @@@ -223,7 -223,7 +223,7 @@@ static int pagesize int getprocs64 (void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); int getthrds64( pid_t, void *, int, tid64_t *, int ); #endif - int getargs (struct procentry64 *processBuffer, int bufferLen, char *argsBuffer, int argsLen); + int getargs (void *processBuffer, int bufferLen, char *argsBuffer, int argsLen); #endif /* HAVE_PROCINFO_H */ /* put name of process from config to list_head_g tree diff --combined src/snmp.c index 3be2ae26,3e6cb911..7d6e0a10 --- a/src/snmp.c +++ b/src/snmp.c @@@ -2,23 -2,18 +2,23 @@@ * collectd - src/snmp.c * Copyright (C) 2007-2012 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * 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 @@@ -34,8 -29,6 +34,8 @@@ #include #include +#include + /* * Private data structes */ @@@ -57,7 -50,7 +57,7 @@@ struct data_definition_ { char *name; /* used to reference this from the `Collect' option */ char *type; /* used to find the data_set */ - int is_table; + _Bool is_table; instance_t instance; char *instance_prefix; oid_t *values; @@@ -65,9 -58,6 +65,9 @@@ double scale; double shift; struct data_definition_s *next; + char **ignores; + size_t ignores_len; + int invert_match; }; typedef struct data_definition_s data_definition_t; @@@ -75,22 -65,8 +75,22 @@@ struct host_definition_ { char *name; char *address; - char *community; int version; + + /* snmpv1/2 options */ + char *community; + + /* snmpv3 security options */ + char *username; + oid *auth_protocol; + size_t auth_protocol_len; + char *auth_passphrase; + oid *priv_protocol; + size_t priv_protocol_len; + char *priv_passphrase; + int security_level; + char *context; + void *sess_handle; c_complain_t complaint; cdtime_t interval; @@@ -207,10 -183,6 +207,10 @@@ static void csnmp_host_definition_destr sfree (hd->name); sfree (hd->address); sfree (hd->community); + sfree (hd->username); + sfree (hd->auth_passphrase); + sfree (hd->priv_passphrase); + sfree (hd->context); sfree (hd->data_list); sfree (hd); @@@ -225,15 -197,16 +225,15 @@@ * csnmp_config * +-> call_snmp_init_once * +-> csnmp_config_add_data - * ! +-> csnmp_config_add_data_type - * ! +-> csnmp_config_add_data_table * ! +-> csnmp_config_add_data_instance * ! +-> csnmp_config_add_data_instance_prefix * ! +-> csnmp_config_add_data_values * +-> csnmp_config_add_host - * +-> csnmp_config_add_host_address - * +-> csnmp_config_add_host_community * +-> csnmp_config_add_host_version * +-> csnmp_config_add_host_collect + * +-> csnmp_config_add_host_auth_protocol + * +-> csnmp_config_add_host_priv_protocol + * +-> csnmp_config_add_host_security_level */ static void call_snmp_init_once (void) { @@@ -244,31 -217,60 +244,31 @@@ have_init = 1; } /* void call_snmp_init_once */ -static int csnmp_config_add_data_type (data_definition_t *dd, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: `Type' needs exactly one string argument."); - return (-1); - } - - sfree (dd->type); - dd->type = strdup (ci->values[0].value.string); - if (dd->type == NULL) - return (-1); - - return (0); -} /* int csnmp_config_add_data_type */ - -static int csnmp_config_add_data_table (data_definition_t *dd, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("snmp plugin: `Table' needs exactly one boolean argument."); - return (-1); - } - - dd->is_table = ci->values[0].value.boolean ? 1 : 0; - - return (0); -} /* int csnmp_config_add_data_table */ - static int csnmp_config_add_data_instance (data_definition_t *dd, oconfig_item_t *ci) { - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: `Instance' needs exactly one string argument."); - return (-1); - } + char buffer[DATA_MAX_NAME_LEN]; + int status; + + status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer)); + if (status != 0) + return status; if (dd->is_table) { /* Instance is an OID */ dd->instance.oid.oid_len = MAX_OID_LEN; - if (!read_objid (ci->values[0].value.string, + if (!read_objid (buffer, dd->instance.oid.oid, &dd->instance.oid.oid_len)) { - ERROR ("snmp plugin: read_objid (%s) failed.", - ci->values[0].value.string); + ERROR ("snmp plugin: read_objid (%s) failed.", buffer); return (-1); } } else { /* Instance is a simple string */ - sstrncpy (dd->instance.string, ci->values[0].value.string, + sstrncpy (dd->instance.string, buffer, sizeof (dd->instance.string)); } @@@ -278,7 -280,11 +278,7 @@@ static int csnmp_config_add_data_instance_prefix (data_definition_t *dd, oconfig_item_t *ci) { - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: `InstancePrefix' needs exactly one string argument."); - return (-1); - } + int status; if (!dd->is_table) { @@@ -287,8 -293,12 +287,8 @@@ return (-1); } - sfree (dd->instance_prefix); - dd->instance_prefix = strdup (ci->values[0].value.string); - if (dd->instance_prefix == NULL) - return (-1); - - return (0); + status = cf_util_get_string(ci, &dd->instance_prefix); + return status; } /* int csnmp_config_add_data_instance_prefix */ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci) @@@ -334,49 -344,33 +334,49 @@@ return (0); } /* int csnmp_config_add_data_instance */ -static int csnmp_config_add_data_shift (data_definition_t *dd, oconfig_item_t *ci) +static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t *ci) { - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) + int i; + + if (ci->values_num < 1) + return (0); + + for (i = 0; i < ci->values_num; i++) { - WARNING ("snmp plugin: The `Shift' config option needs exactly one number argument."); - return (-1); + if (ci->values[i].type != OCONFIG_TYPE_STRING) + { + WARNING ("snmp plugin: `Ignore' needs only string argument."); + return (-1); + } } - dd->shift = ci->values[0].value.number; + dd->ignores_len = 0; + dd->ignores = NULL; - return (0); -} /* int csnmp_config_add_data_shift */ + for (i = 0; i < ci->values_num; ++i) + { + if (strarray_add(&(dd->ignores), &(dd->ignores_len), ci->values[i].value.string) != 0) + { + ERROR("snmp plugin: Can't allocate memory"); + strarray_free(dd->ignores, dd->ignores_len); + return (ENOMEM); + } + } + return 0; +} /* int csnmp_config_add_data_blacklist */ -static int csnmp_config_add_data_scale (data_definition_t *dd, oconfig_item_t *ci) +static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd, oconfig_item_t *ci) { - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) { - WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument."); + WARNING ("snmp plugin: `InvertMatch' needs exactly one boolean argument."); return (-1); } - dd->scale = ci->values[0].value.number; + dd->invert_match = ci->values[0].value.boolean ? 1 : 0; return (0); -} /* int csnmp_config_add_data_scale */ +} /* int csnmp_config_add_data_blacklist_match_inverted */ static int csnmp_config_add_data (oconfig_item_t *ci) { @@@ -384,18 -378,24 +384,18 @@@ int status = 0; int i; - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: The `Data' config option needs exactly one string argument."); - return (-1); - } - dd = (data_definition_t *) malloc (sizeof (data_definition_t)); if (dd == NULL) return (-1); memset (dd, '\0', sizeof (data_definition_t)); - dd->name = strdup (ci->values[0].value.string); - if (dd->name == NULL) + status = cf_util_get_string(ci, &dd->name); + if (status != 0) { free (dd); return (-1); } + dd->scale = 1.0; dd->shift = 0.0; @@@ -405,9 -405,9 +405,9 @@@ status = 0; if (strcasecmp ("Type", option->key) == 0) - status = csnmp_config_add_data_type (dd, option); + status = cf_util_get_string(option, &dd->type); else if (strcasecmp ("Table", option->key) == 0) - status = csnmp_config_add_data_table (dd, option); + status = cf_util_get_boolean(option, &dd->is_table); else if (strcasecmp ("Instance", option->key) == 0) status = csnmp_config_add_data_instance (dd, option); else if (strcasecmp ("InstancePrefix", option->key) == 0) @@@ -415,13 -415,9 +415,13 @@@ else if (strcasecmp ("Values", option->key) == 0) status = csnmp_config_add_data_values (dd, option); else if (strcasecmp ("Shift", option->key) == 0) - status = csnmp_config_add_data_shift (dd, option); + status = cf_util_get_double(option, &dd->shift); else if (strcasecmp ("Scale", option->key) == 0) - status = csnmp_config_add_data_scale (dd, option); + status = cf_util_get_double(option, &dd->scale); + else if (strcasecmp ("Ignore", option->key) == 0) + status = csnmp_config_add_data_blacklist(dd, option); + else if (strcasecmp ("InvertMatch", option->key) == 0) + status = csnmp_config_add_data_blacklist_match_inverted(dd, option); else { WARNING ("snmp plugin: Option `%s' not allowed here.", option->key); @@@ -455,7 -451,6 +455,7 @@@ sfree (dd->name); sfree (dd->instance_prefix); sfree (dd->values); + sfree (dd->ignores); sfree (dd); return (-1); } @@@ -477,6 -472,50 +477,6 @@@ return (0); } /* int csnmp_config_add_data */ -static int csnmp_config_add_host_address (host_definition_t *hd, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: The `Address' config option needs exactly one string argument."); - return (-1); - } - - if (hd->address == NULL) - free (hd->address); - - hd->address = strdup (ci->values[0].value.string); - if (hd->address == NULL) - return (-1); - - DEBUG ("snmp plugin: host = %s; host->address = %s;", - hd->name, hd->address); - - return (0); -} /* int csnmp_config_add_host_address */ - -static int csnmp_config_add_host_community (host_definition_t *hd, oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: The `Community' config option needs exactly one string argument."); - return (-1); - } - - if (hd->community == NULL) - free (hd->community); - - hd->community = strdup (ci->values[0].value.string); - if (hd->community == NULL) - return (-1); - - DEBUG ("snmp plugin: host = %s; host->community = %s;", - hd->name, hd->community); - - return (0); -} /* int csnmp_config_add_host_community */ - static int csnmp_config_add_host_version (host_definition_t *hd, oconfig_item_t *ci) { int version; @@@ -489,9 -528,9 +489,9 @@@ } version = (int) ci->values[0].value.number; - if ((version != 1) && (version != 2)) + if ((version < 1) || (version > 3)) { - WARNING ("snmp plugin: `Version' must either be `1' or `2'."); + WARNING ("snmp plugin: `Version' must either be `1', `2', or `3'."); return (-1); } @@@ -551,92 -590,6 +551,92 @@@ static int csnmp_config_add_host_collec return (0); } /* int csnmp_config_add_host_collect */ +static int csnmp_config_add_host_auth_protocol (host_definition_t *hd, oconfig_item_t *ci) +{ + char buffer[4]; + int status; + + status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer)); + if (status != 0) + return status; + + if (strcasecmp("MD5", buffer) == 0) { + hd->auth_protocol = usmHMACMD5AuthProtocol; + hd->auth_protocol_len = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid); + } + else if (strcasecmp("SHA", buffer) == 0) { + hd->auth_protocol = usmHMACSHA1AuthProtocol; + hd->auth_protocol_len = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid); + } + else + { + WARNING ("snmp plugin: The `AuthProtocol' config option must be `MD5' or `SHA'."); + return (-1); + } + + DEBUG ("snmp plugin: host = %s; host->auth_protocol = %s;", + hd->name, hd->auth_protocol == usmHMACMD5AuthProtocol ? "MD5" : "SHA"); + + return (0); +} /* int csnmp_config_add_host_auth_protocol */ + +static int csnmp_config_add_host_priv_protocol (host_definition_t *hd, oconfig_item_t *ci) +{ + char buffer[4]; + int status; + + status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer)); + if (status != 0) + return status; + + if (strcasecmp("AES", buffer) == 0) + { + hd->priv_protocol = usmAESPrivProtocol; + hd->priv_protocol_len = sizeof(usmAESPrivProtocol)/sizeof(oid); + } + else if (strcasecmp("DES", buffer) == 0) { + hd->priv_protocol = usmDESPrivProtocol; + hd->priv_protocol_len = sizeof(usmDESPrivProtocol)/sizeof(oid); + } + else + { + WARNING ("snmp plugin: The `PrivProtocol' config option must be `AES' or `DES'."); + return (-1); + } + + DEBUG ("snmp plugin: host = %s; host->priv_protocol = %s;", + hd->name, hd->priv_protocol == usmAESPrivProtocol ? "AES" : "DES"); + + return (0); +} /* int csnmp_config_add_host_priv_protocol */ + +static int csnmp_config_add_host_security_level (host_definition_t *hd, oconfig_item_t *ci) +{ + char buffer[16]; + int status; + + status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer)); + if (status != 0) + return status; + + if (strcasecmp("noAuthNoPriv", buffer) == 0) + hd->security_level = SNMP_SEC_LEVEL_NOAUTH; + else if (strcasecmp("authNoPriv", buffer) == 0) + hd->security_level = SNMP_SEC_LEVEL_AUTHNOPRIV; + else if (strcasecmp("authPriv", buffer) == 0) + hd->security_level = SNMP_SEC_LEVEL_AUTHPRIV; + else + { + WARNING ("snmp plugin: The `SecurityLevel' config option must be `noAuthNoPriv', `authNoPriv', or `authPriv'."); + return (-1); + } + + DEBUG ("snmp plugin: host = %s; host->security_level = %d;", + hd->name, hd->security_level); + + return (0); +} /* int csnmp_config_add_host_security_level */ + static int csnmp_config_add_host (oconfig_item_t *ci) { host_definition_t *hd; @@@ -648,6 -601,12 +648,6 @@@ user_data_t cb_data; struct timespec cb_interval; - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("snmp plugin: `Host' needs exactly one string argument."); - return (-1); - } - hd = (host_definition_t *) malloc (sizeof (host_definition_t)); if (hd == NULL) return (-1); @@@ -655,9 -614,12 +655,9 @@@ hd->version = 2; C_COMPLAIN_INIT (&hd->complaint); - hd->name = strdup (ci->values[0].value.string); - if (hd->name == NULL) - { - free (hd); - return (-1); - } + status = cf_util_get_string(ci, &hd->name); + if (status != 0) + return status; hd->sess_handle = NULL; hd->interval = 0; @@@ -668,29 -630,15 +668,29 @@@ status = 0; if (strcasecmp ("Address", option->key) == 0) - status = csnmp_config_add_host_address (hd, option); + status = cf_util_get_string(option, &hd->address); else if (strcasecmp ("Community", option->key) == 0) - status = csnmp_config_add_host_community (hd, option); + status = cf_util_get_string(option, &hd->community); else if (strcasecmp ("Version", option->key) == 0) status = csnmp_config_add_host_version (hd, option); else if (strcasecmp ("Collect", option->key) == 0) csnmp_config_add_host_collect (hd, option); else if (strcasecmp ("Interval", option->key) == 0) cf_util_get_cdtime (option, &hd->interval); + else if (strcasecmp ("Username", option->key) == 0) + status = cf_util_get_string(option, &hd->username); + else if (strcasecmp ("AuthProtocol", option->key) == 0) + status = csnmp_config_add_host_auth_protocol (hd, option); + else if (strcasecmp ("PrivacyProtocol", option->key) == 0) + status = csnmp_config_add_host_priv_protocol (hd, option); + else if (strcasecmp ("AuthPassphrase", option->key) == 0) + status = cf_util_get_string(option, &hd->auth_passphrase); + else if (strcasecmp ("PrivacyPassphrase", option->key) == 0) + status = cf_util_get_string(option, &hd->priv_passphrase); + else if (strcasecmp ("SecurityLevel", option->key) == 0) + status = csnmp_config_add_host_security_level (hd, option); + else if (strcasecmp ("Context", option->key) == 0) + status = cf_util_get_string(option, &hd->context); else { WARNING ("snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", option->key); @@@ -709,57 -657,12 +709,57 @@@ status = -1; break; } - if (hd->community == NULL) + if (hd->community == NULL && hd->version < 3) { WARNING ("snmp plugin: `Community' not given for host `%s'", hd->name); status = -1; break; } + if (hd->version == 3) + { + if (hd->username == NULL) + { + WARNING ("snmp plugin: `Username' not given for host `%s'", hd->name); + status = -1; + break; + } + if (hd->security_level == 0) + { + WARNING ("snmp plugin: `SecurityLevel' not given for host `%s'", hd->name); + status = -1; + break; + } + if (hd->security_level == SNMP_SEC_LEVEL_AUTHNOPRIV || hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) + { + if (hd->auth_protocol == NULL) + { + WARNING ("snmp plugin: `AuthProtocol' not given for host `%s'", hd->name); + status = -1; + break; + } + if (hd->auth_passphrase == NULL) + { + WARNING ("snmp plugin: `AuthPassphrase' not given for host `%s'", hd->name); + status = -1; + break; + } + } + if (hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV) + { + if (hd->priv_protocol == NULL) + { + WARNING ("snmp plugin: `PrivacyProtocol' not given for host `%s'", hd->name); + status = -1; + break; + } + if (hd->priv_passphrase == NULL) + { + WARNING ("snmp plugin: `PrivacyPassphrase' not given for host `%s'", hd->name); + status = -1; + break; + } + } + } break; } /* while (status == 0) */ @@@ -821,75 -724,15 +821,75 @@@ static int csnmp_config (oconfig_item_ static void csnmp_host_open_session (host_definition_t *host) { struct snmp_session sess; + int error; if (host->sess_handle != NULL) csnmp_host_close_session (host); snmp_sess_init (&sess); sess.peername = host->address; - sess.community = (u_char *) host->community; - sess.community_len = strlen (host->community); - sess.version = (host->version == 1) ? SNMP_VERSION_1 : SNMP_VERSION_2c; + switch (host->version) + { + case 1: + sess.version = SNMP_VERSION_1; + break; + case 3: + sess.version = SNMP_VERSION_3; + break; + default: + sess.version = SNMP_VERSION_2c; + break; + } + + if (host->version == 3) + { + sess.securityName = host->username; + sess.securityNameLen = strlen (host->username); + sess.securityLevel = host->security_level; + + if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) + { + sess.securityAuthProto = host->auth_protocol; + sess.securityAuthProtoLen = host->auth_protocol_len; + sess.securityAuthKeyLen = USM_AUTH_KU_LEN; + error = generate_Ku (sess.securityAuthProto, + sess.securityAuthProtoLen, + (u_char *) host->auth_passphrase, + strlen(host->auth_passphrase), + sess.securityAuthKey, + &sess.securityAuthKeyLen); + if (error != SNMPERR_SUCCESS) { + ERROR ("snmp plugin: host %s: Error generating Ku from auth_passphrase. (Error %d)", host->name, error); + } + } + + if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) + { + sess.securityPrivProto = host->priv_protocol; + sess.securityPrivProtoLen = host->priv_protocol_len; + sess.securityPrivKeyLen = USM_PRIV_KU_LEN; + error = generate_Ku (sess.securityAuthProto, + sess.securityAuthProtoLen, + (u_char *) host->priv_passphrase, + strlen(host->priv_passphrase), + sess.securityPrivKey, + &sess.securityPrivKeyLen); + if (error != SNMPERR_SUCCESS) { + ERROR ("snmp plugin: host %s: Error generating Ku from priv_passphrase. (Error %d)", host->name, error); + } + } + + if (host->context != NULL) + { + sess.contextName = host->context; + sess.contextNameLen = strlen (host->context); + } + } + else /* SNMPv1/2 "authenticates" with community string */ + { + sess.community = (u_char *) host->community; + sess.community_len = strlen (host->community); + } /* snmp_sess_open will copy the `struct snmp_session *'. */ host->sess_handle = snmp_sess_open (&sess); @@@ -1128,8 -971,6 +1128,8 @@@ static int csnmp_instance_list_add (csn struct variable_list *vb; oid_t vb_name; int status; + uint32_t i; + uint32_t is_matched; /* Set vb on the last variable */ for (vb = res->variables; @@@ -1163,29 -1004,7 +1163,29 @@@ char *ptr; csnmp_strvbcopy (il->instance, vb, sizeof (il->instance)); - + is_matched = 0; + for (i = 0; i < dd->ignores_len; i++) + { + status = fnmatch(dd->ignores[i], il->instance, 0); + if (status == 0) + { + if (dd->invert_match == 0) + { + sfree(il); + return 0; + } + else + { + is_matched = 1; + break; + } + } + } + if (dd->invert_match != 0 && is_matched == 0) + { + sfree(il); + return 0; + } for (ptr = il->instance; *ptr != '\0'; ptr++) { if ((*ptr > 0) && (*ptr < 32)) @@@ -1618,6 -1437,10 +1618,10 @@@ static int csnmp_read_table (host_defin snmp_free_pdu (res); res = NULL; + if (req != NULL) + snmp_free_pdu (req); + req = NULL; + if (status == 0) csnmp_dispatch_table (host, data, instance_list_head, value_list_head); @@@ -1836,7 -1659,6 +1840,7 @@@ static int csnmp_shutdown (void sfree (data_this->name); sfree (data_this->type); sfree (data_this->values); + sfree (data_this->ignores); sfree (data_this); data_this = data_next; diff --combined src/tcpconns.c index 80435dbe,6351c7b6..5a042314 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@@ -17,7 -17,7 +17,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: - * Florian octo Forster + * Florian octo Forster * Michael Stapelberg **/ @@@ -74,7 -74,9 +74,9 @@@ /* 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 */ @@@ -137,10 -139,12 +139,12 @@@ #endif /* KERNEL_AIX */ #if KERNEL_LINUX + #if HAVE_STRUCT_LINUX_INET_DIAG_REQ struct nlreq { struct nlmsghdr nlh; struct inet_diag_req r; }; + #endif static const char *tcp_state[] = { @@@ -215,13 -219,13 +219,13 @@@ static const char *tcp_state[] "CLOSED", "LISTEN", "SYN_SENT", - "SYN_RCVD", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", - "FIN_WAIT_1", + "FIN_WAIT1", "CLOSING", "LAST_ACK", - "FIN_WAIT_2", + "FIN_WAIT2", "TIME_WAIT" }; @@@ -276,7 -280,12 +280,12 @@@ static int port_collect_listening = 0 static port_entry_t *port_list_head = NULL; #if KERNEL_LINUX + #if HAVE_STRUCT_LINUX_INET_DIAG_REQ + /* This depends on linux inet_diag_req because if this structure is missing, + * sequence_number is useless and we get a compilation warning. + */ static uint32_t sequence_number = 0; + #endif enum { @@@ -446,6 -455,7 +455,7 @@@ static int conn_handle_ports (uint16_t * zero on other errors. */ static int conn_read_netlink (void) { + #if HAVE_STRUCT_LINUX_INET_DIAG_REQ int fd; struct sockaddr_nl nladdr; struct nlreq req; @@@ -574,6 -584,9 +584,9 @@@ /* Not reached because the while() loop above handles the exit condition. */ return (0); + #else + return (1); + #endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */ } /* int conn_read_netlink */ static int conn_handle_line (char *buffer) diff --combined src/utils_vl_lookup.c index 01d33ffe,8180d0d9..75c02061 --- a/src/utils_vl_lookup.c +++ b/src/utils_vl_lookup.c @@@ -1,6 -1,6 +1,6 @@@ /** * collectd - src/utils_vl_lookup.c - * Copyright (C) 2012 Florian Forster + * Copyright (C) 2012 Florian Forster * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@@ -26,6 -26,7 +26,7 @@@ #include "collectd.h" + #include #include #include "common.h" @@@ -86,6 -87,7 +87,7 @@@ struct user_obj_ struct user_class_s { + pthread_mutex_t lock; void *user_class; identifier_match_t match; user_obj_t *user_obj_list; /* list of user_obj */ @@@ -191,6 -193,7 +193,7 @@@ static int lu_copy_ident_to_match (iden return (0); } /* }}} int lu_copy_ident_to_match */ + /* user_class->lock must be held when calling this function */ static void *lu_create_user_obj (lookup_t *obj, /* {{{ */ data_set_t const *ds, value_list_t const *vl, user_class_t *user_class) @@@ -245,6 -248,7 +248,7 @@@ return (user_obj); } /* }}} void *lu_create_user_obj */ + /* user_class->lock must be held when calling this function */ static user_obj_t *lu_find_user_obj (user_class_t *user_class, /* {{{ */ value_list_t const *vl) { @@@ -294,14 -298,17 +298,17 @@@ static int lu_handle_user_class (lookup || !lu_part_matches (&user_class->match.host, vl->host)) return (1); + pthread_mutex_lock (&user_class->lock); user_obj = lu_find_user_obj (user_class, vl); if (user_obj == NULL) { /* 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) return (-1); } + pthread_mutex_unlock (&user_class->lock); status = obj->cb_user_obj (ds, vl, user_class->user_class, user_obj->user_obj); @@@ -402,7 -409,7 +409,7 @@@ static int lu_add_by_plugin (by_type_en identifier_match_t const *match = &user_class_list->entry.match; /* Lookup user_class_list from the per-plugin structure. If this is the first - * user_class to be added, the blocks return immediately. Otherwise they will + * user_class to be added, the block returns immediately. Otherwise they will * set "ptr" to non-NULL. */ if (match->plugin.is_regex) { @@@ -487,6 -494,7 +494,7 @@@ static void lu_destroy_user_class_list lu_destroy_user_obj (obj, user_class_list->entry.user_obj_list); user_class_list->entry.user_obj_list = NULL; + pthread_mutex_destroy (&user_class_list->entry.lock); sfree (user_class_list); user_class_list = next; @@@ -599,6 -607,7 +607,7 @@@ int lookup_add (lookup_t *obj, /* {{{ * return (ENOMEM); } memset (user_class_obj, 0, sizeof (*user_class_obj)); + pthread_mutex_init (&user_class_obj->entry.lock, /* attr = */ NULL); user_class_obj->entry.user_class = user_class; lu_copy_ident_to_match (&user_class_obj->entry.match, ident, group_by); user_class_obj->entry.user_obj_list = NULL; diff --combined src/write_http.c index aabca3e9,34ea46d9..eee5a1c6 --- a/src/write_http.c +++ b/src/write_http.c @@@ -18,7 -18,7 +18,7 @@@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Doug MacEachern * Paul Sadauskas **/ @@@ -46,15 -46,10 +46,15 @@@ struct wh_callback_ char *user; char *pass; char *credentials; - int verify_peer; - int verify_host; + _Bool verify_peer; + _Bool verify_host; char *cacert; - int store_rates; + char *capath; + char *clientkey; + char *clientcert; + char *clientkeypass; + long sslversion; + _Bool store_rates; #define WH_FORMAT_COMMAND 0 #define WH_FORMAT_JSON 1 @@@ -117,7 -112,7 +117,7 @@@ static int wh_callback_init (wh_callbac } curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); + curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); headers = NULL; headers = curl_slist_append (headers, "Accept: */*"); @@@ -155,20 -150,8 +155,20 @@@ curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYPEER, (long) cb->verify_peer); curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYHOST, cb->verify_host ? 2L : 0L); + curl_easy_setopt (cb->curl, CURLOPT_SSLVERSION, cb->sslversion); if (cb->cacert != NULL) curl_easy_setopt (cb->curl, CURLOPT_CAINFO, cb->cacert); + if (cb->capath != NULL) + curl_easy_setopt (cb->curl, CURLOPT_CAPATH, cb->capath); + + if (cb->clientkey != NULL && cb->clientcert != NULL) + { + curl_easy_setopt (cb->curl, CURLOPT_SSLKEY, cb->clientkey); + curl_easy_setopt (cb->curl, CURLOPT_SSLCERT, cb->clientcert); + + if (cb->clientkeypass != NULL) + curl_easy_setopt (cb->curl, CURLOPT_SSLKEYPASSWD, cb->clientkeypass); + } wh_reset_buffer (cb); @@@ -286,10 -269,6 +286,10 @@@ static void wh_callback_free (void *dat sfree (cb->pass); sfree (cb->credentials); sfree (cb->cacert); + sfree (cb->capath); + sfree (cb->clientkey); + sfree (cb->clientcert); + sfree (cb->clientkeypass); sfree (cb); } /* }}} void wh_callback_free */ @@@ -454,6 -433,47 +454,6 @@@ static int wh_write (const data_set_t * return (status); } /* }}} int wh_write */ -static int config_set_string (char **ret_string, /* {{{ */ - oconfig_item_t *ci) -{ - char *string; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("write_http plugin: The `%s' config option " - "needs exactly one string argument.", ci->key); - return (-1); - } - - string = strdup (ci->values[0].value.string); - if (string == NULL) - { - ERROR ("write_http plugin: strdup failed."); - return (-1); - } - - if (*ret_string != NULL) - free (*ret_string); - *ret_string = string; - - return (0); -} /* }}} int config_set_string */ - -static int config_set_boolean (int *dest, oconfig_item_t *ci) /* {{{ */ -{ - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("write_http plugin: The `%s' config option " - "needs exactly one boolean argument.", ci->key); - return (-1); - } - - *dest = ci->values[0].value.boolean ? 1 : 0; - - return (0); -} /* }}} int config_set_boolean */ - static int config_set_format (wh_callback_t *cb, /* {{{ */ oconfig_item_t *ci) { @@@ -480,7 -500,7 +480,7 @@@ } return (0); -} /* }}} int config_set_string */ +} /* }}} int config_set_format */ static int wh_config_url (oconfig_item_t *ci) /* {{{ */ { @@@ -495,14 -515,19 +495,14 @@@ return (-1); } memset (cb, 0, sizeof (*cb)); - cb->location = NULL; - cb->user = NULL; - cb->pass = NULL; - cb->credentials = NULL; cb->verify_peer = 1; cb->verify_host = 1; - cb->cacert = NULL; cb->format = WH_FORMAT_COMMAND; - cb->curl = NULL; + cb->sslversion = CURL_SSLVERSION_DEFAULT; pthread_mutex_init (&cb->send_lock, /* attr = */ NULL); - config_set_string (&cb->location, ci); + cf_util_get_string (ci, &cb->location); if (cb->location == NULL) return (-1); @@@ -511,55 -536,19 +511,55 @@@ oconfig_item_t *child = ci->children + i; if (strcasecmp ("User", child->key) == 0) - config_set_string (&cb->user, child); + cf_util_get_string (child, &cb->user); else if (strcasecmp ("Password", child->key) == 0) - config_set_string (&cb->pass, child); + cf_util_get_string (child, &cb->pass); else if (strcasecmp ("VerifyPeer", child->key) == 0) - config_set_boolean (&cb->verify_peer, child); + cf_util_get_boolean (child, &cb->verify_peer); else if (strcasecmp ("VerifyHost", child->key) == 0) - config_set_boolean (&cb->verify_host, child); + cf_util_get_boolean (child, &cb->verify_host); else if (strcasecmp ("CACert", child->key) == 0) - config_set_string (&cb->cacert, child); + cf_util_get_string (child, &cb->cacert); + else if (strcasecmp ("CAPath", child->key) == 0) + cf_util_get_string (child, &cb->capath); + else if (strcasecmp ("ClientKey", child->key) == 0) + cf_util_get_string (child, &cb->clientkey); + else if (strcasecmp ("ClientCert", child->key) == 0) + cf_util_get_string (child, &cb->clientcert); + else if (strcasecmp ("ClientKeyPass", child->key) == 0) + cf_util_get_string (child, &cb->clientkeypass); + else if (strcasecmp ("SSLVersion", child->key) == 0) + { + char *value = NULL; + + cf_util_get_string (child, &value); + + if (value == NULL || strcasecmp ("default", value) == 0) + cb->sslversion = CURL_SSLVERSION_DEFAULT; + else if (strcasecmp ("SSLv2", value) == 0) + cb->sslversion = CURL_SSLVERSION_SSLv2; + else if (strcasecmp ("SSLv3", value) == 0) + cb->sslversion = CURL_SSLVERSION_SSLv3; + else if (strcasecmp ("TLSv1", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1; +#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 34) + else if (strcasecmp ("TLSv1_0", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_0; + else if (strcasecmp ("TLSv1_1", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_1; + else if (strcasecmp ("TLSv1_2", value) == 0) + cb->sslversion = CURL_SSLVERSION_TLSv1_2; +#endif + else + ERROR ("write_http plugin: Invalid SSLVersion " + "option: %s.", value); + + sfree(value); + } else if (strcasecmp ("Format", child->key) == 0) config_set_format (cb, child); else if (strcasecmp ("StoreRates", child->key) == 0) - config_set_boolean (&cb->store_rates, child); + cf_util_get_boolean (child, &cb->store_rates); else { ERROR ("write_http plugin: Invalid configuration " @@@ -601,9 -590,18 +601,18 @@@ static int wh_config (oconfig_item_t *c return (0); } /* }}} int wh_config */ + static int wh_init (void) /* {{{ */ + { + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init (CURL_GLOBAL_SSL); + return (0); + } /* }}} int wh_init */ + void module_register (void) /* {{{ */ { plugin_register_complex_config ("write_http", wh_config); + plugin_register_init ("write_http", wh_init); } /* }}} void module_register */ /* vim: set fdm=marker sw=8 ts=8 tw=78 et : */ diff --combined src/write_riemann.c index 78f01c05,a404ff6e..b59c3e35 --- a/src/write_riemann.c +++ b/src/write_riemann.c @@@ -1,25 -1,20 +1,25 @@@ /** * collectd - src/write_riemann.c - * * Copyright (C) 2012,2013 Pierre-Yves Ritschard * Copyright (C) 2013 Florian octo Forster * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * 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" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 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: * Pierre-Yves Ritschard @@@ -44,15 -39,11 +44,15 @@@ #define RIEMANN_PORT "5555" #define RIEMANN_TTL_FACTOR 2.0 +int write_riemann_threshold_check(const data_set_t *, const value_list_t *, int *); + struct riemann_host { char *name; #define F_CONNECT 0x01 uint8_t flags; pthread_mutex_t lock; - _Bool notifications; - _Bool check_thresholds; ++ _Bool notifications; ++ _Bool check_thresholds; _Bool store_rates; _Bool always_append_ds; char *node; @@@ -66,8 -57,6 +66,8 @@@ static char **riemann_tags; static size_t riemann_tags_num; +static char **riemann_attrs; +static size_t riemann_attrs_num; static void riemann_event_protobuf_free (Event *event) /* {{{ */ { @@@ -97,7 -86,7 +97,7 @@@ sfree (event); } /* }}} void riemann_event_protobuf_free */ - static void riemann_msg_protobuf_free (Msg *msg) /* {{{ */ + static void riemann_msg_protobuf_free(Msg *msg) /* {{{ */ { size_t i; @@@ -159,7 -148,7 +159,7 @@@ static int riemann_connect(struct riema } host->flags |= F_CONNECT; - DEBUG("write_riemann plugin: got a succesful connection for: %s:%s", + DEBUG("write_riemann plugin: got a successful connection for: %s:%s", node, service); break; } @@@ -319,7 -308,7 +319,7 @@@ static int riemann_event_add_tag (Even return (strarray_add (&event->tags, &event->n_tags, tag)); } /* }}} int riemann_event_add_tag */ - static int riemann_event_add_attribute (Event *event, /* {{{ */ + static int riemann_event_add_attribute(Event *event, /* {{{ */ char const *key, char const *value) { Attribute **new_attributes; @@@ -352,7 -341,7 +352,7 @@@ return (0); } /* }}} int riemann_event_add_attribute */ - static Msg *riemann_notification_to_protobuf (struct riemann_host *host, /* {{{ */ + static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ */ notification_t const *n) { Msg *msg; @@@ -421,11 -410,6 +421,11 @@@ riemann_event_add_attribute (event, "type_instance", n->type_instance); + for (i = 0; i < riemann_attrs_num; i += 2) + riemann_event_add_attribute(event, + riemann_attrs[i], + riemann_attrs[i +1]); + for (i = 0; i < riemann_tags_num; i++) riemann_event_add_tag (event, riemann_tags[i]); @@@ -434,23 -418,15 +434,23 @@@ n->type, n->type_instance); event->service = strdup (&service_buffer[1]); - /* Pull in values from threshold */ + if (n->message[0] != 0) + riemann_event_add_attribute (event, "description", n->message); + + /* Pull in values from threshold and add extra attributes */ for (meta = n->meta; meta != NULL; meta = meta->next) { - if (strcasecmp ("CurrentValue", meta->name) != 0) + if (strcasecmp ("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) + { + event->metric_d = meta->nm_value.nm_double; + event->has_metric_d = 1; continue; + } - event->metric_d = meta->nm_value.nm_double; - event->has_metric_d = 1; - break; + if (meta->type == NM_TYPE_STRING) { + riemann_event_add_attribute (event, meta->name, meta->nm_value.nm_string); + continue; + } } DEBUG ("write_riemann plugin: Successfully created protobuf for notification: " @@@ -459,11 -435,10 +459,11 @@@ return (msg); } /* }}} Msg *riemann_notification_to_protobuf */ - static Event *riemann_value_to_protobuf (struct riemann_host const *host, /* {{{ */ + static Event *riemann_value_to_protobuf(struct riemann_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, size_t index, - gauge_t const *rates) + gauge_t const *rates, + int status) { Event *event; char name_buffer[5 * DATA_MAX_NAME_LEN]; @@@ -484,23 -459,6 +484,23 @@@ event->time = CDTIME_T_TO_TIME_T (vl->time); event->has_time = 1; - if (host->check_thresholds) { - switch (status) { - case STATE_OKAY: - event->state = strdup("ok"); - break; - case STATE_ERROR: - event->state = strdup("critical"); - break; - case STATE_WARNING: - event->state = strdup("warning"); - break; - case STATE_MISSING: - event->state = strdup("unknown"); - break; - } - } ++ if (host->check_thresholds) { ++ switch (status) { ++ case STATE_OKAY: ++ event->state = strdup("ok"); ++ break; ++ case STATE_ERROR: ++ event->state = strdup("critical"); ++ break; ++ case STATE_WARNING: ++ event->state = strdup("warning"); ++ break; ++ case STATE_MISSING: ++ event->state = strdup("unknown"); ++ break; ++ } ++ } + ttl = CDTIME_T_TO_DOUBLE (vl->interval) * host->ttl_factor; event->ttl = (float) ttl; event->has_ttl = 1; @@@ -536,11 -494,6 +536,11 @@@ riemann_event_add_attribute (event, "ds_index", ds_index); } + for (i = 0; i < riemann_attrs_num; i += 2) + riemann_event_add_attribute(event, + riemann_attrs[i], + riemann_attrs[i +1]); + for (i = 0; i < riemann_tags_num; i++) riemann_event_add_tag (event, riemann_tags[i]); @@@ -583,10 -536,9 +583,10 @@@ return (event); } /* }}} Event *riemann_value_to_protobuf */ -static Msg *riemann_value_list_to_protobuf(struct riemann_host const *host, /* {{{ */ - data_set_t const *ds, - value_list_t const *vl) +static Msg *riemann_value_list_to_protobuf (struct riemann_host const *host, /* {{{ */ + data_set_t const *ds, + value_list_t const *vl, + int *statuses) { Msg *msg; size_t i; @@@ -626,7 -578,7 +626,7 @@@ for (i = 0; i < msg->n_events; i++) { msg->events[i] = riemann_value_to_protobuf (host, ds, vl, - (int) i, rates); + (int) i, rates, statuses[i]); if (msg->events[i] == NULL) { riemann_msg_protobuf_free (msg); @@@ -645,9 -597,6 +645,9 @@@ static int riemann_notification(const n struct riemann_host *host = ud->data; Msg *msg; - if (!host->notifications) - return 0; ++ if (!host->notifications) ++ return 0; + msg = riemann_notification_to_protobuf (host, n); if (msg == NULL) return (-1); @@@ -666,13 -615,10 +666,13 @@@ static int riemann_write(const data_set user_data_t *ud) { int status; + int statuses[vl->values_len]; struct riemann_host *host = ud->data; Msg *msg; - if (host->check_thresholds) - write_riemann_threshold_check(ds, vl, statuses); - msg = riemann_value_list_to_protobuf (host, ds, vl); ++ if (host->check_thresholds) ++ write_riemann_threshold_check(ds, vl, statuses); + msg = riemann_value_list_to_protobuf (host, ds, vl, statuses); if (msg == NULL) return (-1); @@@ -725,8 -671,6 +725,8 @@@ static int riemann_config_node(oconfig_ host->reference_count = 1; host->node = NULL; host->service = NULL; - host->notifications = 1; - host->check_thresholds = 0; ++ host->notifications = 1; ++ host->check_thresholds = 0; host->store_rates = 1; host->always_append_ds = 0; host->use_tcp = 0; @@@ -751,14 -695,6 +751,14 @@@ status = cf_util_get_string (child, &host->node); if (status != 0) break; - } else if (strcasecmp ("Notifications", child->key) == 0) { - status = cf_util_get_boolean(child, &host->notifications); - if (status != 0) - break; - } else if (strcasecmp ("CheckThresholds", child->key) == 0) { - status = cf_util_get_boolean(child, &host->check_thresholds); - if (status != 0) - break; ++ } else if (strcasecmp ("Notifications", child->key) == 0) { ++ status = cf_util_get_boolean(child, &host->notifications); ++ if (status != 0) ++ break; ++ } else if (strcasecmp ("CheckThresholds", child->key) == 0) { ++ status = cf_util_get_boolean(child, &host->check_thresholds); ++ if (status != 0) ++ break; } else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_service (child, &host->service); if (status != 0) { @@@ -887,32 -823,6 +887,32 @@@ static int riemann_config(oconfig_item_ if (strcasecmp("Node", child->key) == 0) { riemann_config_node (child); + } else if (strcasecmp(child->key, "attribute") == 0) { + char *key = NULL; + char *val = NULL; + + if (child->values_num != 2) { + WARNING("riemann attributes need both a key and a value."); + return (-1); + } + if (child->values[0].type != OCONFIG_TYPE_STRING || + child->values[1].type != OCONFIG_TYPE_STRING) { + WARNING("riemann attribute needs string arguments."); + return (-1); + } + if ((key = strdup(child->values[0].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute key."); + return (-1); + } + if ((val = strdup(child->values[1].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute value."); + return (-1); + } + strarray_add(&riemann_attrs, &riemann_attrs_num, key); + strarray_add(&riemann_attrs, &riemann_attrs_num, val); + DEBUG("write_riemann: got attr: %s => %s", key, val); + sfree(key); + sfree(val); } else if (strcasecmp(child->key, "tag") == 0) { char *tmp = NULL; status = cf_util_get_string(child, &tmp); @@@ -928,7 -838,7 +928,7 @@@ child->key); } } - return 0; + return (0); } /* }}} int riemann_config */ void module_register(void) diff --combined version-gen.sh index 7fbc8671,95b15d8a..6b5e40e5 --- a/version-gen.sh +++ b/version-gen.sh @@@ -1,8 -1,8 +1,8 @@@ #!/usr/bin/env bash - DEFAULT_VERSION="5.4.0.git" + DEFAULT_VERSION="5.4.1.git" -VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`" +VERSION="`git describe 2> /dev/null | grep collectd | sed -e 's/^collectd-//'`" if test -z "$VERSION"; then VERSION="$DEFAULT_VERSION"