+2010-05-01, Version 4.10.0
+ * collectd: JSON output now includes the "dstypes" and "dsnames"
+ fields. This makes it easier for external applications to interpret
+ the data. Thanks to Chris Buben for his work.
+ * collectd: The new "Timeout" option can be used to specify a
+ "timeout" for missing values. This is used in the threshold checking
+ code to detect missing values. Thanks to Andrés J. Díaz for the
+ patch.
+ * apache plugin: Support for "IdleWorkers" (Apache 1.*: "IdleServers")
+ has been added.
+ * curl plugin: The new "ExcludeRegex" allows to easily exclude certain
+ lines from the match.
+ * curl_xml plugin: This new plugin allows to read XML files using cURL
+ and extract metrics included in the files. Thanks to Amit Gupta for
+ his work.
+ * filecount plugin: The new "IncludeHidden" option allows to include
+ "hidden" files and directories in the statistics. Thanks to Vaclav
+ Malek for the patch.
+ * logfile plugin: The new "PrintSeverity" option allows to include the
+ severity of a message in the output. Thanks to Clément Stenac for
+ his patch.
+ * memcachec plugin: The new "ExcludeRegex" allows to easily exclude
+ certain lines from the match.
+ * modbus plugin: This new plugin allows to read registers from
+ Modbus-TCP enabled devices.
+ * network plugin: The new "Interface" option allows to set the
+ interface to be used for multicast and, if supported, unicast
+ traffic. Thanks to Max Henkel for his work.
+ * openvpn plugin: The "CollectUserCount" and "CollectIndividualUsers"
+ options allow more detailed control over how to report sessions of
+ multiple users. Thanks to Fabian Schuh for his work.
+ * pinba plugin: This new plugin receives timing information from the
+ Pinba PHP extension, which can be used for profiling PHP code and
+ webserver performance. Thanks to Phoenix Kayo for his work.
+ * ping plugin: The new "MaxMissed" allows to re-resolve a hosts
+ address when it doesn't reply to a number of ping requests. Thanks
+ to Stefan Völkel for the patch.
+ * postgresql plugin: The "Interval" config option has been added. The
+ plugin has been relicensed under the 2-clause BSD license. Thanks to
+ Sebastian Harl for his work.
+ * processes plugin: Support for "code" and "data" virtual memory sizes
+ has been added. Thanks to Clément Stenac for his patch.
+ * python plugin: Support for Python 3 has been implemented. Thanks to
+ Sven Trenkel for his work.
+ * routeros plugin: Support for collecting CPU load, memory usage, used
+ and free disk space, sectors written and number of bad blocks from
+ MikroTik devices has been added.
+ * swap plugin: Support for Linux < 2.6 has been added. Thanks to Lorin
+ Scraba for his patch.
+ * tail plugin: The new "ExcludeRegex" allows to easily exclude certain
+ lines from the match. Thanks to Peter Warasin for his patch.
+ * write_http plugin: The "StoreRates" option has been added. Thanks to
+ Paul Sadauskas for his patch.
+ * regex match: The "Invert" option has been added. Thanks to Julien
+ Ammous for his patch.
+
+ 2010-07-09, Version 4.9.3
+ * Build system: Checking for "strtok_r" under Solaris has been fixed.
+ * Portability: Fixes for Solaris 8 have been applied. Thanks to
+ Aurélien Reynaud and Alexander Wuerstlein for their patches.
+ * collectd: The shutdown speed when terminating the read threads has
+ been improved.
+ * collectd-nagios: The format of the performance data has been fixed.
+ * libcollectdclient: A format error in the PUTVAL command has been
+ removed. Thanks to Johan Van den Brande for fixing this.
+ * df plugin: An error message shown when "cu_mount_getlist" fails has
+ been added.
+ * processes plugin: Missing initialization code for IO members of a
+ struct has been added. Thanks to Aurélien Reynaud for fixing this.
+ * python plugin: Memory leaks in the write and notification callbacks
+ have been fixed. A possible crash when the plugin was loaded but not
+ configured has been fixed. Thanks to Sven Trenkel for his patches.
+ * rrdcached plugin: A build issue has been resolved. Thanks to
+ Thorsten von Eicken for the patch.
+ * snmp plugin: Verbosity with regard to unknown ASN types has been
+ increased. A build problem on PowerPC and ARM processors has been
+ fixed by Aurélien Reynaud; thanks!
+ * powerdns plugin: Compatibility changes for PowerDNS 2.9.22 and above
+ have been applied. Thanks to Luke Heberling for his changes.
+
2010-04-22, Version 4.9.2
* Build system, various plugins: Fixes for AIX compatibility have been
added. Thanks to Manuel Sanmartin for his patches.
AC_PROG_YACC
PKG_PROG_PKG_CONFIG
+AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no])
+AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes")
+
AC_MSG_CHECKING([for kernel type ($host_os)])
case $host_os in
*linux*)
# Checks for library functions.
#
AC_PROG_GCC_TRADITIONAL
-AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv)
+AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname)
AC_FUNC_STRERROR_R
#include <linux/netdevice.h>
])
+AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [],
+ [],
+ [
+ #include <netinet/in.h>
+ #include <net/if.h>
+ ])
+
AC_CHECK_MEMBERS([struct kinfo_proc.ki_pid, struct kinfo_proc.ki_rssize, struct kinfo_proc.ki_rusage],
[
AC_DEFINE(HAVE_STRUCT_KINFO_PROC_FREEBSD, 1,
AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes")
# }}}
+# --with-libmodbus {{{
+with_libmodbus_config=""
+with_libmodbus_cflags=""
+with_libmodbus_libs=""
+AC_ARG_WITH(libmodbus, [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path to the modbus library.])],
+[
+ if test "x$withval" = "xno"
+ then
+ with_libmodbus="no"
+ else if test "x$withval" = "xyes"
+ then
+ with_libmodbus="use_pkgconfig"
+ else if test -d "$with_libmodbus/lib"
+ then
+ AC_MSG_NOTICE([Not checking for libmodbus: Manually configured])
+ with_libmodbus_cflags="-I$withval/include"
+ with_libmodbus_libs="-L$withval/lib -lmodbus"
+ with_libmodbus="yes"
+ fi; fi; fi
+],
+[with_libmodbus="use_pkgconfig"])
+
+# configure using pkg-config
+if test "x$with_libmodbus" = "xuse_pkgconfig"
+then
+ if test "x$PKG_CONFIG" = "x"
+ then
+ with_libmodbus="no (Don't have pkg-config)"
+ fi
+fi
+if test "x$with_libmodbus" = "xuse_pkgconfig"
+then
+ AC_MSG_NOTICE([Checking for modbus using $PKG_CONFIG])
+ $PKG_CONFIG --exists 'modbus' 2>/dev/null
+ if test $? -ne 0
+ then
+ with_libmodbus="no (pkg-config doesn't know library)"
+ fi
+fi
+if test "x$with_libmodbus" = "xuse_pkgconfig"
+then
+ with_libmodbus_cflags="`$PKG_CONFIG --cflags 'modbus'`"
+ if test $? -ne 0
+ then
+ with_libmodbus="no ($PKG_CONFIG failed)"
+ fi
+ with_libmodbus_libs="`$PKG_CONFIG --libs 'modbus'`"
+ if test $? -ne 0
+ then
+ with_libmodbus="no ($PKG_CONFIG failed)"
+ fi
+fi
+if test "x$with_libmodbus" = "xuse_pkgconfig"
+then
+ with_libmodbus="yes"
+fi
+
+# with_libmodbus_cflags and with_libmodbus_libs are set up now, let's do
+# the actual checks.
+if test "x$with_libmodbus" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
+
+ AC_CHECK_HEADERS(modbus/modbus.h, [], [with_libmodbus="no (modbus/modbus.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmodbus" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+
+ CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
+ LDFLAGS="$LDFLAGS $with_libmodbus_libs"
+
+ AC_CHECK_LIB(modbus, modbus_init_tcp,
+ [with_libmodbus="yes"],
+ [with_libmodbus="no (symbol modbus_init_tcp not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libmodbus" = "xyes"
+then
+ BUILD_WITH_LIBMODBUS_CFLAGS="$with_libmodbus_cflags"
+ BUILD_WITH_LIBMODBUS_LIBS="$with_libmodbus_libs"
+ AC_SUBST(BUILD_WITH_LIBMODBUS_CFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMODBUS_LIBS)
+fi
+# }}}
+
# --with-libmysql {{{
with_mysql_config="mysql_config"
with_mysql_cflags=""
if test "x$with_python" = "xyes"
then
AC_MSG_CHECKING([for Python CPPFLAGS])
- python_include_path=`echo "import distutils.sysconfig;print distutils.sysconfig.get_python_inc()" | "$with_python_prog" 2>&1`
+ python_include_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_python_inc())" | "$with_python_prog" 2>&1`
python_config_status=$?
if test "$python_config_status" -ne 0 || test "x$python_include_path" = "x"
if test "x$with_python" = "xyes"
then
AC_MSG_CHECKING([for Python LDFLAGS])
- python_library_path=`echo "import distutils.sysconfig;print distutils.sysconfig.get_config_vars(\"LIBDIR\").__getitem__(0)" | "$with_python_prog" 2>&1`
+ python_library_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"LIBDIR\").__getitem__(0))" | "$with_python_prog" 2>&1`
python_config_status=$?
if test "$python_config_status" -ne 0 || test "x$python_library_path" = "x"
if test "x$with_python" = "xyes"
then
AC_MSG_CHECKING([for Python LIBS])
- python_library_flags=`echo "import distutils.sysconfig;print distutils.sysconfig.get_config_vars(\"BLDLIBRARY\").__getitem__(0)" | "$with_python_prog" 2>&1`
+ python_library_flags=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"BLDLIBRARY\").__getitem__(0))" | "$with_python_prog" 2>&1`
python_config_status=$?
if test "$python_config_status" -ne 0 || test "x$python_library_flags" = "x"
enable_plugin="yes"
force="yes"
else
- enable_plugin="no"
+ enable_plugin="no (disabled on command line)"
fi; fi
],
[
plugin_cpu="no"
plugin_cpufreq="no"
plugin_curl_json="no"
+plugin_curl_xml="no"
plugin_df="no"
plugin_disk="no"
plugin_entropy="no"
plugin_vserver="yes"
plugin_wireless="yes"
- if test "x$have_net_ip_vs_h" = "xyes" -o "x$have_ip_vs_h" = "xyes"
+ if test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"
then
plugin_ipvs="yes"
fi
plugin_curl_json="yes"
fi
+if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
+then
+ plugin_curl_xml="yes"
+fi
+
if test "x$have_processor_info" = "xyes"
then
plugin_cpu="yes"
AC_PLUGIN([csv], [yes], [CSV output plugin])
AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics])
AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics])
+AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics])
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([memcachec], [$with_libmemcached], [memcachec statistics])
AC_PLUGIN([memcached], [yes], [memcached statistics])
AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
+AC_PLUGIN([modbus], [$with_libmodbus], [Modbus plugin])
AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values])
AC_PLUGIN([mysql], [$with_libmysql], [MySQL statistics])
AC_PLUGIN([netapp], [$with_libnetapp], [NetApp plugin])
AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
+# FIXME: Check for libevent, too.
+AC_PLUGIN([pinba], [$have_protoc_c], [Pinba statistics])
AC_PLUGIN([ping], [$with_liboping], [Network latency statistics])
AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
with_librrd="yes (warning: librrd is not thread-safe)"
fi
- if test "x$with_libiptc" = "xyes" -a "x$with_own_libiptc" = "xyes"
+ if test "x$with_libiptc" = "xyes" && test "x$with_own_libiptc" = "xyes"
then
with_libiptc="yes (shipped version)"
fi
libkstat . . . . . . $with_kstat
libkvm . . . . . . . $with_libkvm
libmemcached . . . . $with_libmemcached
+ libmodbus . . . . . . $with_libmodbus
libmysql . . . . . . $with_libmysql
libnetapp . . . . . . $with_libnetapp
libnetlink . . . . . $with_libnetlink
libxml2 . . . . . . . $with_libxml2
libxmms . . . . . . . $with_libxmms
libyajl . . . . . . . $with_libyajl
+ libevent . . . . . . $with_libevent
+ protobuf-c . . . . . $have_protoc_c
oracle . . . . . . . $with_oracle
python . . . . . . . $with_python
csv . . . . . . . . . $enable_csv
curl . . . . . . . . $enable_curl
curl_json . . . . . . $enable_curl_json
+ curl_xml . . . . . . $enable_curl_xml
dbi . . . . . . . . . $enable_dbi
df . . . . . . . . . $enable_df
disk . . . . . . . . $enable_disk
memcachec . . . . . . $enable_memcachec
memcached . . . . . . $enable_memcached
memory . . . . . . . $enable_memory
+ modbus . . . . . . . $enable_modbus
multimeter . . . . . $enable_multimeter
mysql . . . . . . . . $enable_mysql
netapp . . . . . . . $enable_netapp
openvpn . . . . . . . $enable_openvpn
oracle . . . . . . . $enable_oracle
perl . . . . . . . . $enable_perl
+ pinba . . . . . . . . $enable_pinba
ping . . . . . . . . $enable_ping
postgresql . . . . . $enable_postgresql
powerdns . . . . . . $enable_powerdns
#define rf_callback rf_super.cf_callback
#define rf_udata rf_super.cf_udata
callback_func_t rf_super;
+ char rf_group[DATA_MAX_NAME_LEN];
char rf_name[DATA_MAX_NAME_LEN];
int rf_type;
struct timespec rf_interval;
* we need to re-evaluate the condition every time
* pthread_cond_timedwait returns. */
rc = 0;
- while (!timeout_reached(rf->rf_next_read) && rc == 0) {
+ while ((read_loop != 0)
+ && !timeout_reached(rf->rf_next_read)
+ && rc == 0)
+ {
rc = pthread_cond_timedwait (&read_cond, &read_lock,
&rf->rf_next_read);
}
- /* Must hold `real_lock' when accessing `rf->rf_type'. */
+ /* Must hold `read_lock' when accessing `rf->rf_type'. */
rf_type = rf->rf_type;
pthread_mutex_unlock (&read_lock);
rf->rf_callback = (void *) callback;
rf->rf_udata.data = NULL;
rf->rf_udata.free_func = NULL;
+ rf->rf_group[0] = '\0';
sstrncpy (rf->rf_name, name, sizeof (rf->rf_name));
rf->rf_type = RF_SIMPLE;
rf->rf_interval.tv_sec = 0;
return (plugin_insert_read (rf));
} /* int plugin_register_read */
-int plugin_register_complex_read (const char *name,
+int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
const struct timespec *interval,
user_data_t *user_data)
memset (rf, 0, sizeof (read_func_t));
rf->rf_callback = (void *) callback;
+ if (group != NULL)
+ sstrncpy (rf->rf_group, group, sizeof (rf->rf_group));
+ else
+ rf->rf_group[0] = '\0';
sstrncpy (rf->rf_name, name, sizeof (rf->rf_name));
rf->rf_type = RF_COMPLEX;
if (interval != NULL)
return (0);
} /* }}} int plugin_unregister_read */
+static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */
+{
+ read_func_t *rf = e->value;
+ char *group = ud;
+
+ return strcmp (rf->rf_group, (const char *)group);
+} /* }}} int compare_read_func_group */
+
+int plugin_unregister_read_group (const char *group) /* {{{ */
+{
+ llentry_t *le;
+ read_func_t *rf;
+
+ int found = 0;
+
+ if (group == NULL)
+ return (-ENOENT);
+
+ pthread_mutex_lock (&read_lock);
+
+ if (read_list == NULL)
+ {
+ pthread_mutex_unlock (&read_lock);
+ return (-ENOENT);
+ }
+
+ while (42)
+ {
+ le = llist_search_custom (read_list,
+ compare_read_func_group, (void *)group);
+
+ if (le == NULL)
+ break;
+
+ ++found;
+
+ llist_remove (read_list, le);
+
+ rf = le->value;
+ assert (rf != NULL);
+ rf->rf_type = RF_REMOVE;
+
+ llentry_destroy (le);
+
+ DEBUG ("plugin_unregister_read_group: "
+ "Marked `%s' (group `%s') for removal.",
+ rf->rf_name, group);
+ }
+
+ pthread_mutex_unlock (&read_lock);
+
+ if (found == 0)
+ {
+ WARNING ("plugin_unregister_read_group: No such "
+ "group of read function: %s", group);
+ return (-ENOENT);
+ }
+
+ return (0);
+} /* }}} int plugin_unregister_read_group */
+
int plugin_unregister_write (const char *name)
{
return (plugin_unregister (list_write, name));