+ 2012-04-01, Version 5.0.4
+ * Build system: Fix the use of a libltdl macro. Thanks to Clemens Lang
+ for fixing this. Adresses some issues with building the iptables
+ plugin under Gentoo.
+ * libcollectdclient: A memory leak in the lcc_getval() function has
+ been fixed. Thanks to Jason Schmidlapp for finding and fixing this
+ issue.
+ * bind plugin: The use of 'QType" types has been fixed.
+ * df plugin: Fixed compiler issue under Mac OS X 10.7.
+ * conntrack plugin: Support zero as legitimate value. Thanks to Louis
+ Opter for his patch.
+ * memcached plugin: Increased the size of a static buffer, which was
+ truncating status messages form memcached. Thanks to Timon for the
+ patch.
+ * network plugin: Forwarding of notifications has been disabled. This
+ was a contition not checked for before, which may retult in an
+ endless loop.
+ * processes plugin: Support for process names with spaces has been
+ added to the Linux implementation. Thanks to Darrell Bishop for his
+ patch.
+ * perl plugin: A race condition in several callbacks, including log and
+ write callbacks, has been fixed. Thanks to "Rrpv" for reporting this
+ bug.
+ * snmp plugin: A bug when casting unsigned integers to gauge values has
+ been fixed: Unsigned integers would be cast to a signed integer and
+ then to a gauge, possibly resulting in a negative value.
+ * tcpconns plugin: Compilation with newer versions of the FreeBSD
+ runtime has been fixed.
+
2012-02-19, Version 5.0.3
* Build system: Fix problems when building the ipvs and iptables
plugins. Thanks to Sebastian Harl for his patch. A bashism in the
technique of POWER CPUs. Thanks to Aurélien Reynaud for his code and
patience.
* modbus plugin: Support for libmodbus 2.9.2 has been added and the
- license has been changes to LGPLv2.1.
+ license has been changed to LGPLv2.1.
* mysql plugin: Backwards compatibility code has been removed. The
data sets used have been improved.
* network plugin: The default buffer size has been increased to
* v5upgrade target: Target for converting v4 data sets to the v5
schema.
+ 2012-04-01, Version 4.10.7
+ * Build system: Fix the use of a libltdl macro. Thanks to Clemens Lang
+ for fixing this. Adresses some issues with building the iptables
+ plugin under Gentoo.
+ * libcollectdclient: A memory leak in the lcc_getval() function has
+ been fixed. Thanks to Jason Schmidlapp for finding and fixing this
+ issue.
+ * bind plugin: The use of 'QType" types has been fixed.
+ * df plugin: Fixed compiler issue under Mac OS X 10.7.
+ * conntrack plugin: Support zero as legitimate value. Thanks to Louis
+ Opter for his patch.
+ * memcached plugin: Increased the size of a static buffer, which was
+ truncating status messages form memcached. Thanks to Timon for the
+ patch.
+ * network plugin: Forwarding of notifications has been disabled. This
+ was a contition not checked for before, which may retult in an
+ endless loop.
+ * processes plugin: Support for process names with spaces has been
+ added to the Linux implementation. Thanks to Darrell Bishop for his
+ patch.
+ * perl plugin: A race condition in several callbacks, including log and
+ write callbacks, has been fixed. Thanks to "Rrpv" for reporting this
+ bug.
+ * snmp plugin: A bug when casting unsigned integers to gauge values has
+ been fixed: Unsigned integers would be cast to a signed integer and
+ then to a gauge, possibly resulting in a negative value.
+ * tcpconns plugin: Compilation with newer versions of the FreeBSD
+ runtime has been fixed.
+
2012-02-19, Version 4.10.6
* Build system: Fix problems when building the ipvs and iptables
plugins. Thanks to Sebastian Harl for his patch. A bashism in the
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(collectd, m4_esyscmd(./version-gen.sh))
+AC_INIT(collectd, [m4_esyscmd(./version-gen.sh)])
AC_CONFIG_SRCDIR(src/collectd.c)
AC_CONFIG_HEADERS(src/config.h)
AC_CONFIG_AUX_DIR([libltdl/config])
# For hddtemp module
AC_CHECK_HEADERS(linux/major.h libgen.h)
+# For md module (Linux only)
+if test "x$ac_system" = "xLinux"
+then
+ AC_CHECK_HEADERS(linux/raid/md_u.h,
+ [have_linux_raid_md_u_h="yes"],
+ [have_linux_raid_md_u_h="no"],
+[
+#include <sys/ioctl.h>
+#include <linux/major.h>
+#include <linux/types.h>
+])
+else
+ have_linux_raid_md_u_h="no"
+fi
+
# For the battery plugin
AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
[
#endif
])
+# For ethstat module
+AC_CHECK_HEADERS(linux/sockios.h,
+ [have_linux_sockios_h="yes"],
+ [have_linux_sockios_h="no"],
+ [
+#if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#if HAVE_NET_IF_H
+# include <net/if.h>
+#endif
+ ])
+AC_CHECK_HEADERS(linux/ethtool.h,
+ [have_linux_ethtool_h="yes"],
+ [have_linux_ethtool_h="no"],
+ [
+#if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#if HAVE_NET_IF_H
+# include <net/if.h>
+#endif
+#if HAVE_LINUX_SOCKIOS_H
+# include <linux/sockios.h>
+#endif
+ ])
+
# For ipvs module
have_linux_ip_vs_h="no"
have_net_ip_vs_h="no"
#
# Checks for libraries begin here
#
+
with_libresolv="yes"
AC_CHECK_LIB(resolv, res_search,
[
AC_CHECK_LIB(kvm, kvm_nlist, [with_kvm_nlist="yes"], [with_kvm_nlist="no"])
if test "x$with_kvm_nlist" = "xyes"
then
+ AC_CHECK_HEADERS(bsd/nlist.h nlist.h)
AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
[Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)])
with_libkvm="yes"
AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], [])
fi
# Check for the iptc_init symbol in the library.
+ # This could be in iptc or ip4tc
if test "x$with_libiptc" = "xpkgconfig"
then
- AC_CHECK_LIB(iptc, iptc_init,
+ AC_SEARCH_LIBS(iptc_init, [iptc ip4tc],
[with_libiptc="pkgconfig"],
[with_libiptc="no"],
[$with_libiptc_libs])
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
+ AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
+ $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
if test $? -ne 0
then
- with_libmodbus="no (pkg-config doesn't know modbus)"
+ with_libmodbus="no (pkg-config doesn't know libmodbus)"
fi
fi
if test "x$with_libmodbus" = "xuse_pkgconfig"
then
- with_libmodbus_cflags="`$PKG_CONFIG --cflags 'modbus'`"
+ with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`"
if test $? -ne 0
then
with_libmodbus="no ($PKG_CONFIG failed)"
fi
- with_libmodbus_libs="`$PKG_CONFIG --libs 'modbus'`"
+ with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
if test $? -ne 0
then
with_libmodbus="no ($PKG_CONFIG failed)"
fi
# }}}
+# --with-libmongoc {{{
+AC_ARG_WITH(libmongoc, [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
+[
+ if test "x$withval" = "xyes"
+ then
+ with_libmongoc="yes"
+ else if test "x$withval" = "xno"
+ then
+ with_libmongoc="no"
+ else
+ with_libmongoc="yes"
+ LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS -I$withval/include"
+ LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS -L$withval/lib"
+ fi; fi
+],
+[with_libmongoc="yes"])
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+
+CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS"
+LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
+
+if test "x$with_libmongoc" = "xyes"
+then
+ if test "x$LIBMONGOC_CPPFLAGS" != "x"
+ then
+ AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
+ fi
+ AC_CHECK_HEADERS(mongo.h,
+ [with_libmongoc="yes"],
+ [with_libmongoc="no ('mongo.h' not found)"],
+[#if HAVE_STDINT_H
+# define MONGO_HAVE_STDINT 1
+#else
+# define MONGO_USE_LONG_LONG_INT 1
+#endif
+])
+fi
+if test "x$with_libmongoc" = "xyes"
+then
+ if test "x$LIBMONGOC_LDFLAGS" != "x"
+ then
+ AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
+ fi
+ AC_CHECK_LIB(mongoc, mongo_run_command,
+ [with_libmongoc="yes"],
+ [with_libmongoc="no (symbol 'mongo_run_command' not found)"])
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+if test "x$with_libmongoc" = "xyes"
+then
+ BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
+ BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
+ AC_SUBST(BUILD_WITH_LIBMONGOC_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMONGOC_LDFLAGS)
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
+# }}}
+
# --with-libmysql {{{
with_mysql_config="mysql_config"
with_mysql_cflags=""
[
with_librabbitmq="yes"
])
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
+ LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
if test "x$with_librabbitmq" = "xyes"
then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
-
AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
-
- CPPFLAGS="$SAVE_CPPFLAGS"
fi
if test "x$with_librabbitmq" = "xyes"
then
- SAVE_CPPFLAGS="$CPPFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
- LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
-
+ # librabbitmq up to version 0.9.1 provides "library_errno", later
+ # versions use "library_error". The library does not provide a version
+ # macro :( Use "AC_CHECK_MEMBERS" (plural) for automatic defines.
+ AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],,,
+ [
+ #if HAVE_STDLIB_H
+ # include <stdlib.h>
+ #endif
+ #if HAVE_STDIO_H
+ # include <stdio.h>
+ #endif
+ #if HAVE_STDINT_H
+ # include <stdint.h>
+ #endif
+ #if HAVE_INTTYPES_H
+ # include <inttypes.h>
+ #endif
+ #include <amqp.h>
+ ])
+ fi
+ if test "x$with_librabbitmq" = "xyes"
+ then
AC_CHECK_LIB(rabbitmq, amqp_basic_publish, [with_librabbitmq="yes"], [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"])
-
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
fi
if test "x$with_librabbitmq" = "xyes"
then
AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
AC_DEFINE(HAVE_LIBRABBITMQ, 1, [Define if librabbitmq is present and usable.])
fi
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes")
# }}}
CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
#LDFLAGS="$LDFLAGS $with_libvarnish_libs"
- AC_CHECK_LIB(varnishapi, VSL_OpenStats,
- [with_libvarnish="yes"],
- [with_libvarnish="no (symbol VSL_OpenStats not found)"],
- [$with_libvarnish_libs])
+ AC_CHECK_HEADERS(varnish/vsc.h,
+ [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])],
+ [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])])
CPPFLAGS="$SAVE_CPPFLAGS"
#LDFLAGS="$SAVE_LDFLAGS"
plugin_df="no"
plugin_disk="no"
plugin_entropy="no"
+plugin_ethstat="no"
+plugin_fscache="no"
plugin_interface="no"
plugin_ipmi="no"
plugin_ipvs="no"
plugin_memory="no"
plugin_multimeter="no"
plugin_nfs="no"
-plugin_fscache="no"
+plugin_numa="no"
plugin_perl="no"
plugin_processes="no"
plugin_protocols="no"
plugin_cpufreq="yes"
plugin_disk="yes"
plugin_entropy="yes"
+ plugin_fscache="yes"
plugin_interface="yes"
plugin_irq="yes"
plugin_load="yes"
plugin_memory="yes"
plugin_nfs="yes"
- plugin_fscache="yes"
+ plugin_numa="yes"
plugin_processes="yes"
plugin_protocols="yes"
plugin_serial="yes"
fi
# AIX
+
+if test "x$ac_system" = "xAIX"
+then
+ plugin_tcpconns="yes"
+fi
+
if test "x$with_perfstat" = "xyes"
then
plugin_cpu="yes"
# Solaris
if test "x$with_kstat" = "xyes"
then
+ plugin_nfs="yes"
plugin_uptime="yes"
plugin_zfs_arc="yes"
fi
fi
fi
+if test "x$have_linux_sockios_h$have_linux_ethtool_h" = "xyesyes"
+then
+ plugin_ethstat="yes"
+fi
+
if test "x$have_getifaddrs" = "xyes"
then
plugin_interface="yes"
AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
AC_PLUGIN([email], [yes], [EMail statistics])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
+AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver])
AC_PLUGIN([exec], [yes], [Execution of external programs])
AC_PLUGIN([filecount], [yes], [Count files in directories])
AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
AC_PLUGIN([match_timediff], [yes], [The timediff match])
AC_PLUGIN([match_value], [yes], [The value match])
AC_PLUGIN([mbmon], [yes], [Query mbmond])
+AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
AC_PLUGIN([memcached], [yes], [memcached statistics])
AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
AC_PLUGIN([ntpd], [yes], [NTPd statistics])
+AC_PLUGIN([numa], [$plugin_numa], [NUMA virtual memory statistics])
AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
AC_PLUGIN([olsrd], [yes], [olsrd statistics])
AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
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_redis], [$with_libcredis], [Redis output plugin])
+AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics])
AC_CONFIG_FILES(src/libcollectdclient/lcc_features.h)
-AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/owniptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile)
+AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile)
if test "x$with_librrd" = "xyes" \
&& test "x$librrd_threadsafe" != "xyes"
dns . . . . . . . . . $enable_dns
email . . . . . . . . $enable_email
entropy . . . . . . . $enable_entropy
+ ethstat . . . . . . . $enable_ethstat
exec . . . . . . . . $enable_exec
filecount . . . . . . $enable_filecount
fscache . . . . . . . $enable_fscache
match_timediff . . . $enable_match_timediff
match_value . . . . . $enable_match_value
mbmon . . . . . . . . $enable_mbmon
+ md . . . . . . . . . $enable_md
memcachec . . . . . . $enable_memcachec
memcached . . . . . . $enable_memcached
memory . . . . . . . $enable_memory
notify_desktop . . . $enable_notify_desktop
notify_email . . . . $enable_notify_email
ntpd . . . . . . . . $enable_ntpd
+ numa . . . . . . . . $enable_numa
nut . . . . . . . . . $enable_nut
olsrd . . . . . . . . $enable_olsrd
onewire . . . . . . . $enable_onewire
vmem . . . . . . . . $enable_vmem
vserver . . . . . . . $enable_vserver
wireless . . . . . . $enable_wireless
+ write_graphite . . . $enable_write_graphite
write_http . . . . . $enable_write_http
write_redis . . . . . $enable_write_redis
+ write_mongodb . . . . $enable_write_mongodb
xmms . . . . . . . . $enable_xmms
zfs_arc . . . . . . . $enable_zfs_arc
SUBDIRS = libcollectdclient
-if BUILD_WITH_OWN_LIBIPTC
-SUBDIRS += owniptc
-endif
if BUILD_WITH_OWN_LIBOCONFIG
SUBDIRS += liboconfig
endif
if BUILD_WITH_OWN_LIBOCONFIG
collectd_LDADD += $(LIBLTDL) liboconfig/liboconfig.la
- collectd_DEPENDENCIES += $(LIBLTDL) liboconfig/liboconfig.la
+ collectd_DEPENDENCIES += liboconfig/liboconfig.la
else
collectd_LDADD += -loconfig
endif
collectd_DEPENDENCIES += exec.la
endif
+if BUILD_PLUGIN_ETHSTAT
+pkglib_LTLIBRARIES += ethstat.la
+ethstat_la_SOURCES = ethstat.c
+ethstat_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" ethstat.la
+collectd_DEPENDENCIES += ethstat.la
+endif
+
if BUILD_PLUGIN_FILECOUNT
pkglib_LTLIBRARIES += filecount.la
filecount_la_SOURCES = filecount.c
iptables_la_SOURCES = iptables.c
iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS)
iptables_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBIPTC_LDFLAGS)
-if BUILD_WITH_OWN_LIBIPTC
-iptables_la_LIBADD = owniptc/libiptc.la
-iptables_la_DEPENDENCIES = owniptc/libiptc.la
-else
iptables_la_LIBADD = -liptc
-endif
collectd_LDADD += "-dlopen" iptables.la
collectd_DEPENDENCIES += iptables.la
endif
collectd_DEPENDENCIES += mbmon.la
endif
+if BUILD_PLUGIN_MD
+pkglib_LTLIBRARIES += md.la
+md_la_SOURCES = md.c
+md_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" md.la
+collectd_DEPENDENCIES += md.la
+endif
+
if BUILD_PLUGIN_MEMCACHEC
pkglib_LTLIBRARIES += memcachec.la
memcachec_la_SOURCES = memcachec.c
collectd_DEPENDENCIES += ntpd.la
endif
+if BUILD_PLUGIN_NUMA
+pkglib_LTLIBRARIES += numa.la
+numa_la_SOURCES = numa.c
+numa_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" numa.la
+collectd_DEPENDENCIES += numa.la
+endif
+
if BUILD_PLUGIN_NUT
pkglib_LTLIBRARIES += nut.la
nut_la_SOURCES = nut.c
collectd_DEPENDENCIES += wireless.la
endif
+if BUILD_PLUGIN_WRITE_GRAPHITE
+pkglib_LTLIBRARIES += write_graphite.la
+write_graphite_la_SOURCES = write_graphite.c \
+ utils_format_json.c utils_format_json.h
+write_graphite_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" write_graphite.la
+collectd_DEPENDENCIES += write_graphite.la
+endif
+
if BUILD_PLUGIN_WRITE_HTTP
pkglib_LTLIBRARIES += write_http.la
write_http_la_SOURCES = write_http.c \
collectd_DEPENDENCIES += write_http.la
endif
+if BUILD_PLUGIN_WRITE_MONGODB
+pkglib_LTLIBRARIES += write_mongodb.la
+write_mongodb_la_SOURCES = write_mongodb.c
+write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
+write_mongodb_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMONGOC_LDFLAGS)
+write_mongodb_la_LIBADD = -lmongoc
+collectd_LDADD += "-dlopen" write_mongodb.la
+collectd_DEPENDENCIES += write_mongodb.la
+endif
+
if BUILD_PLUGIN_WRITE_REDIS
pkglib_LTLIBRARIES += write_redis.la
write_redis_la_SOURCES = write_redis.c
<Plugin "bind">
URL "http://localhost:8053/"
+ ParseTime false
OpCodes true
QTypes true
URL from which to retrieve the XML data. If not specified,
C<http://localhost:8053/> will be used.
-=item B<OpCodes> I<true>|I<false>
+=item B<ParseTime> B<true>|B<false>
+
+When set to B<true>, the time provided by BIND will be parsed and used to
+dispatch the values. When set to B<false>, the local time source is queried.
+
+This setting is set to B<true> by default for backwards compatibility; setting
+this to B<false> is I<recommended> to avoid problems with timezones and
+localization.
+
+=item B<OpCodes> B<true>|B<false>
When enabled, statistics about the I<"OpCodes">, for example the number of
C<QUERY> packets, are collected.
Default: Enabled.
-=item B<QTypes> I<true>|I<false>
+=item B<QTypes> B<true>|B<false>
When enabled, the number of I<incoming> queries by query types (for example
C<A>, C<MX>, C<AAAA>) is collected.
Default: Enabled.
-=item B<ServerStats> I<true>|I<false>
+=item B<ServerStats> B<true>|B<false>
Collect global server statistics, such as requests received over IPv4 and IPv6,
successful queries, and failed updates.
Default: Enabled.
-=item B<ZoneMaintStats> I<true>|I<false>
+=item B<ZoneMaintStats> B<true>|B<false>
Collect zone maintenance statistics, mostly information about notifications
(zone updates) and zone transfers.
Default: Enabled.
-=item B<ResolverStats> I<true>|I<false>
+=item B<ResolverStats> B<true>|B<false>
Collect resolver statistics, i.E<nbsp>e. statistics about outgoing requests
(e.E<nbsp>g. queries over IPv4, lame servers). Since the global resolver
=over 4
-=item B<QTypes> I<true>|I<false>
+=item B<QTypes> B<true>|B<false>
If enabled, the number of I<outgoing> queries by query type (e.E<nbsp>g. C<A>,
C<MX>) is collected.
Default: Enabled.
-=item B<ResolverStats> I<true>|I<false>
+=item B<ResolverStats> B<true>|B<false>
Collect resolver statistics, i.E<nbsp>e. statistics about outgoing requests
(e.E<nbsp>g. queries over IPv4, lame servers).
Default: Enabled.
-=item B<CacheRRSets> I<true>|I<false>
+=item B<CacheRRSets> B<true>|B<false>
If enabled, the number of entries (I<"RR sets">) in the view's cache by query
type is collected. Negative entries (queries which resulted in an error, for
=back
+=head2 Plugin C<ethstat>
+
+The I<ethstat plugin> collects information about network interface cards (NICs)
+by talking directly with the underlying kernel driver using L<ioctl(2)>.
+
+B<Synopsis:>
+
+ <Plugin "ethstat">
+ Interface "eth0"
+ Map "rx_csum_offload_errors" "if_rx_errors" "checksum_offload"
+ Map "multicast" "if_multicast"
+ </Plugin>
+
+B<Options:>
+
+=over 4
+
+=item B<Interface> I<Name>
+
+Collect statistical information about interface I<Name>.
+
+=item B<Map> I<Name> I<Type> [I<TypeInstance>]
+
+By default, the plugin will submit values as type C<derive> and I<type
+instance> set to I<Name>, the name of the metric as reported by the driver. If
+an appropriate B<Map> option exists, the given I<Type> and, optionally,
+I<TypeInstance> will be used.
+
+=item B<MappedOnly> B<true>|B<false>
+
+When set to B<true>, only metrics that can be mapped to to a I<type> will be
+collected, all other metrics will be ignored. Defaults to B<false>.
+
+=back
+
=head2 Plugin C<exec>
Please make sure to read L<collectd-exec(5)> before using this plugin. It
=back
+=head2 Plugin C<md>
+
+The C<md plugin> collects information from Linux Software-RAID devices (md).
+
+All reported values are of the type C<md_disks>. Reported type instances are
+I<active>, I<failed> (present but not operational), I<spare> (hot stand-by) and
+I<missing> (physically absent) disks.
+
+=over 4
+
+=item B<Device> I<Device>
+
+Select md devices based on device name. The I<device name> is the basename of
+the device, i.e. the name of the block device without the leading C</dev/>.
+See B<IgnoreSelected> for more details.
+
+=item B<IgnoreSelected> B<true>|B<false>
+
+Invert device selection: If set to B<true>, all md devices B<except> those
+listed using B<Device> are collected. If B<false> (the default), only those
+listed are collected. If no configuration is given, the B<md> plugin will
+collect data from all md devices.
+
+=back
+
=head2 Plugin C<memcachec>
The C<memcachec plugin> connects to a memcached server, queries one or more
B<RegisterType> has been set to B<Uint32> or B<Float>, this and the next
register will be read (the register number is increased by one).
-=item B<RegisterType> B<Uint16>|B<Uint32>|B<Float>
+=item B<RegisterType> B<Int16>|B<Int32>|B<Uint16>|B<Uint32>|B<Float>
-Specifies what kind of data is returned by the device. If the type is B<Uint32>
-or B<Float>, two 16E<nbsp>bit registers will be read and the data is combined
-into one value. Defaults to B<Uint16>.
+Specifies what kind of data is returned by the device. If the type is B<Int32>,
+B<Uint32> or B<Float>, two 16E<nbsp>bit registers will be read and the data is
+combined into one value. Defaults to B<Uint16>.
=item B<Type> I<Type>
multicast group is C<239.192.74.66>. The default I<UDP> port is B<25826>.
Both, B<Server> and B<Listen> can be used as single option or as block. When
- used as block, given options are valid for this socket only. For example:
+ used as block, given options are valid for this socket only. The following
+ example will export the metrics twice: Once to an "internal" server (without
+ encryption and signing) and one to an external server (with cryptographic
+ signature):
<Plugin "network">
+ # Export to an internal server
+ # (demonstrates usage without additional options)
Server "collectd.internal.tld"
+
+ # Export to an external server
+ # (demonstrates usage with signature options)
<Server "collectd.external.tld">
SecurityLevel "sign"
Username "myhostname"
=over 4
+=item B<SensorConfigFile> I<File>
+
+Read the I<lm_sensors> configuration from I<File>. When unset (recommended),
+the library's default will be used.
+
=item B<Sensor> I<chip-bus-address/type-feature>
Selects the name of the sensor which you want to collect or ignore, depending
=head2 Plugin C<swap>
The I<Swap plugin> collects information about used and available swap space. On
-I<Solaris>, the following options are available:
+I<Linux> and I<Solaris>, the following options are available:
=over 4
=item B<ReportByDevice> B<false>|B<true>
-Configures how to report physical swap devices. If set to B<false> is used (the
+Configures how to report physical swap devices. If set to B<false> (the
default), the summary over all swap devices is reported only, i.e. the globally
used and available space over all devices. If B<true> is configured, the used
and available space of each device will be reported separately.
-This option is only available if the I<Swap plugin> can use the L<swapctl(2)>
-mechanism under I<Solaris>.
+This option is only available if the I<Swap plugin> can read C</proc/swaps>
+(under Linux) or use the L<swapctl(2)> mechanism (under I<Solaris>).
=back
Please note that B<debug> is only available if collectd has been compiled with
debugging support.
+=item B<NotifyLevel> B<OKAY>|B<WARNING>|B<FAILURE>
+
+Controls which notifications should be sent to syslog. The default behaviour is
+not to send any. Less severe notifications always imply logging more severe
+notifications: Setting this to B<OKAY> means all notifications will be sent to
+syslog, setting this to B<WARNING> will send B<WARNING> and B<FAILURE>
+notifications but will dismiss B<OKAY> notifications. Setting this option to
+B<FAILURE> will only send failures to syslog.
+
=back
=head2 Plugin C<table>
collect on-wire traffic you could, for example, use the logging facilities of
iptables to feed data for the guest IPs into the iptables plugin.
+=head2 Plugin C<write_graphite>
+
+The C<write_graphite> plugin writes data to I<Graphite>, an open-source metrics
+storage and graphing project. The plugin connects to I<Carbon>, the data layer
+of I<Graphite>, and sends data via the "line based" protocol (per default using
+portE<nbsp>2003). The data will be sent in blocks of at most 1428 bytes to
+minimize the number of network packets.
+
+Synopsis:
+
+ <Plugin write_graphite>
+ <Carbon>
+ Host "localhost"
+ Port "2003"
+ Prefix "collectd"
+ </Carbon>
+ </Plugin>
+
+=over 4
+
+=item B<Host> I<Address>
+
+Hostname or address to connect to. Defaults to C<localhost>.
+
+=item B<Port> I<Service>
+
+Service name or port number to connect to. Defaults to C<2003>.
+
+=item B<Prefix> I<String>
+
+When set, I<String> is added in front of the host name. Dots and whitespace are
+I<not> escaped in this string (see B<EscapeCharacter> below).
+
+=item B<Postfix> I<String>
+
+When set, I<String> is appended to the host name. Dots and whitespace are
+I<not> escaped in this string (see B<EscapeCharacter> below).
+
+=item B<EscapeCharacter> I<Char>
+
+I<Carbon> uses the dot (C<.>) as escape character and doesn't allow whitespace
+in the identifier. The B<EscapeCharacter> option determines which character
+dots, whitespace and control characters are replaced with. Defaults to
+underscore (C<_>).
+
+=item B<StoreRates> B<false>|B<true>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.E<nbsp>e. as an increasing integer
+number.
+
+=item B<SeparateInstances> B<false>|B<true>
+
+If set to B<true>, the plugin instance and type instance will be in their own
+path component, for example C<host.cpu.0.cpu.idle>. If set to B<false> (the
+default), the plugin and plugin instance (and likewise the type and type
+instance) are put into once component, for example C<host.cpu-0.cpu-idle>.
+
+=item B<AlwaysAppendDS> B<false>|B<true>
+
+If set the B<true>, append the name of the I<Data Source> (DS) to the "metric"
+identifier. If set to B<false> (the default), this is only done when there is
+more than one DS.
+
+=back
+
+=head2 Plugin C<write_mongodb>
+
+The I<write_mongodb plugin> will send values to I<MongoDB>, a schema-less
+NoSQL database.
+
+B<Synopsis:>
+
+ <Plugin "write_mongodb">
+ <Node "default">
+ Host "localhost"
+ Port "27017"
+ Timeout 1000
+ StoreRates true
+ </Node>
+ </Plugin>
+
+The plugin can send values to multiple instances of I<MongoDB> by specifying
+one B<Node> block for each instance. Within the B<Node> blocks, the following
+options are available:
+
+=over 4
+
+=item B<Host> I<Address>
+
+Hostname or address to connect to. Defaults to C<localhost>.
+
+=item B<Port> I<Service>
+
+Service name or port number to connect to. Defaults to C<27017>.
+
+=item B<Timeout> I<Timeout>
+
+Set the timeout for each operation on I<MongoDB> to I<Timeout> milliseconds.
+Setting this option to zero means no timeout, which is the default.
+
+=item B<StoreRates> B<false>|B<true>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.e. as an increasing integer
+number.
+
+=back
+
=head2 Plugin C<write_http>
This output plugin submits values to an http server by POST them using the
=back
+ =head1 THRESHOLD CONFIGURATION
+
+ Starting with version C<4.3.0> collectd has support for B<monitoring>. By that
+ we mean that the values are not only stored or sent somewhere, but that they
+ are judged and, if a problem is recognized, acted upon. The only action
+ collectd takes itself is to generate and dispatch a "notification". Plugins can
+ register to receive notifications and perform appropriate further actions.
+
+ Since systems and what you expect them to do differ a lot, you can configure
+ B<thresholds> for your values freely. This gives you a lot of flexibility but
+ also a lot of responsibility.
+
+ Every time a value is out of range a notification is dispatched. This means
+ that the idle percentage of your CPU needs to be less then the configured
+ threshold only once for a notification to be generated. There's no such thing
+ as a moving average or similar - at least not now.
+
+ Also, all values that match a threshold are considered to be relevant or
+ "interesting". As a consequence collectd will issue a notification if they are
+ not received for B<Timeout> iterations. The B<Timeout> configuration option is
+ explained in section L<"GLOBAL OPTIONS">. If, for example, B<Timeout> is set to
+ "2" (the default) and some hosts sends it's CPU statistics to the server every
+ 60 seconds, a notification will be dispatched after about 120 seconds. It may
+ take a little longer because the timeout is checked only once each B<Interval>
+ on the server.
+
+ When a value comes within range again or is received after it was missing, an
+ "OKAY-notification" is dispatched.
+
+ Here is a configuration example to get you started. Read below for more
+ information.
+
+ <Threshold>
+ <Type "foo">
+ WarningMin 0.00
+ WarningMax 1000.00
+ FailureMin 0.00
+ FailureMax 1200.00
+ Invert false
+ Instance "bar"
+ </Type>
+
+ <Plugin "interface">
+ Instance "eth0"
+ <Type "if_octets">
+ FailureMax 10000000
+ DataSource "rx"
+ </Type>
+ </Plugin>
+
+ <Host "hostname">
+ <Type "cpu">
+ Instance "idle"
+ FailureMin 10
+ </Type>
+
+ <Plugin "memory">
+ <Type "memory">
+ Instance "cached"
+ WarningMin 100000000
+ </Type>
+ </Plugin>
+ </Host>
+ </Threshold>
+
+ There are basically two types of configuration statements: The C<Host>,
+ C<Plugin>, and C<Type> blocks select the value for which a threshold should be
+ configured. The C<Plugin> and C<Type> blocks may be specified further using the
+ C<Instance> option. You can combine the block by nesting the blocks, though
+ they must be nested in the above order, i.E<nbsp>e. C<Host> may contain either
+ C<Plugin> and C<Type> blocks, C<Plugin> may only contain C<Type> blocks and
+ C<Type> may not contain other blocks. If multiple blocks apply to the same
+ value the most specific block is used.
+
+ The other statements specify the threshold to configure. They B<must> be
+ included in a C<Type> block. Currently the following statements are recognized:
+
+ =over 4
+
+ =item B<FailureMax> I<Value>
+
+ =item B<WarningMax> I<Value>
+
+ Sets the upper bound of acceptable values. If unset defaults to positive
+ infinity. If a value is greater than B<FailureMax> a B<FAILURE> notification
+ will be created. If the value is greater than B<WarningMax> but less than (or
+ equal to) B<FailureMax> a B<WARNING> notification will be created.
+
+ =item B<FailureMin> I<Value>
+
+ =item B<WarningMin> I<Value>
+
+ Sets the lower bound of acceptable values. If unset defaults to negative
+ infinity. If a value is less than B<FailureMin> a B<FAILURE> notification will
+ be created. If the value is less than B<WarningMin> but greater than (or equal
+ to) B<FailureMin> a B<WARNING> notification will be created.
+
+ =item B<DataSource> I<DSName>
+
+ Some data sets have more than one "data source". Interesting examples are the
+ C<if_octets> data set, which has received (C<rx>) and sent (C<tx>) bytes and
+ the C<disk_ops> data set, which holds C<read> and C<write> operations. The
+ system load data set, C<load>, even has three data sources: C<shortterm>,
+ C<midterm>, and C<longterm>.
+
+ Normally, all data sources are checked against a configured threshold. If this
+ is undesirable, or if you want to specify different limits for each data
+ source, you can use the B<DataSource> option to have a threshold apply only to
+ one data source.
+
+ =item B<Invert> B<true>|B<false>
+
+ If set to B<true> the range of acceptable values is inverted, i.E<nbsp>e.
+ values between B<FailureMin> and B<FailureMax> (B<WarningMin> and
+ B<WarningMax>) are not okay. Defaults to B<false>.
+
+ =item B<Persist> B<true>|B<false>
+
+ Sets how often notifications are generated. If set to B<true> one notification
+ will be generated for each value that is out of the acceptable range. If set to
+ B<false> (the default) then a notification is only generated if a value is out
+ of range but the previous value was okay.
+
+ This applies to missing values, too: If set to B<true> a notification about a
+ missing value is generated once every B<Interval> seconds. If set to B<false>
+ only one such notification is generated until the value appears again.
+
+ =item B<Percentage> B<true>|B<false>
+
+ If set to B<true>, the minimum and maximum values given are interpreted as
+ percentage value, relative to the other data sources. This is helpful for
+ example for the "df" type, where you may want to issue a warning when less than
+ 5E<nbsp>% of the total space is available. Defaults to B<false>.
+
+ =item B<Hits> I<Number>
+
+ Delay creating the notification until the threshold has been passed I<Number>
+ times. When a notification has been generated, or when a subsequent value is
+ inside the threshold, the counter is reset. If, for example, a value is
+ collected once every 10E<nbsp>seconds and B<Hits> is set to 3, a notification
+ will be dispatched at most once every 30E<nbsp>seconds.
+
+ This is useful when short bursts are not a problem. If, for example, 100% CPU
+ usage for up to a minute is normal (and data is collected every
+ 10E<nbsp>seconds), you could set B<Hits> to B<6> to account for this.
+
+ =item B<Hysteresis> I<Number>
+
+ When set to non-zero, a hysteresis value is applied when checking minimum and
+ maximum bounds. This is useful for values that increase slowly and fluctuate a
+ bit while doing so. When these values come close to the threshold, they may
+ "flap", i.e. switch between failure / warning case and okay case repeatedly.
+
+ If, for example, the threshold is configures as
+
+ WarningMax 100.0
+ Hysteresis 1.0
+
+ then a I<Warning> notification is created when the value exceeds I<101> and the
+ corresponding I<Okay> notification is only created once the value falls below
+ I<99>, thus avoiding the "flapping".
+
+ =back
+
=head1 FILTER CONFIGURATION
Starting with collectd 4.6 there is a powerful filtering infrastructure
Please note that these placeholders are B<case sensitive>!
-=item B<Severity> B<"FATAL">|B<"WARNING">|B<"OKAY">
+=item B<Severity> B<"FAILURE">|B<"WARNING">|B<"OKAY">
Sets the severity of the message. If omitted, the severity B<"WARNING"> is
used.
}
} /* }}} void lcc_chomp */
+static int lcc_identifier_cmp (const void *a, const void *b)
+{
+ const lcc_identifier_t *ident_a, *ident_b;
+
+ int status;
+
+ ident_a = a;
+ ident_b = b;
+
+ status = strcasecmp (ident_a->host, ident_b->host);
+ if (status != 0)
+ return (status);
+
+ status = strcmp (ident_a->plugin, ident_b->plugin);
+ if (status != 0)
+ return (status);
+
+ if ((*ident_a->plugin_instance != '\0') || (*ident_b->plugin_instance != '\0'))
+ {
+ if (*ident_a->plugin_instance == '\0')
+ return (-1);
+ else if (*ident_b->plugin_instance == '\0')
+ return (1);
+
+ status = strcmp (ident_a->plugin_instance, ident_b->plugin_instance);
+ if (status != 0)
+ return (status);
+ }
+
+ status = strcmp (ident_a->type, ident_b->type);
+ if (status != 0)
+ return (status);
+
+ if ((*ident_a->type_instance != '\0') || (*ident_b->type_instance != '\0'))
+ {
+ if (*ident_a->type_instance == '\0')
+ return (-1);
+ else if (*ident_b->type_instance == '\0')
+ return (1);
+
+ status = strcmp (ident_a->type_instance, ident_b->type_instance);
+ if (status != 0)
+ return (status);
+ }
+ return (0);
+} /* }}} int lcc_identifier_cmp */
+
static void lcc_response_free (lcc_response_t *res) /* {{{ */
{
size_t i;
if (ret_values_names != NULL)
*ret_values_names = values_names;
+ lcc_response_free (&res);
+
return (0);
} /* }}} int lcc_getval */
return (0);
} /* }}} int lcc_string_to_identifier */
+int lcc_sort_identifiers (lcc_connection_t *c, /* {{{ */
+ lcc_identifier_t *idents, size_t idents_num)
+{
+ if (idents == NULL)
+ {
+ lcc_set_errno (c, EINVAL);
+ return (-1);
+ }
+
+ qsort (idents, idents_num, sizeof (*idents), lcc_identifier_cmp);
+ return (0);
+} /* }}} int lcc_sort_identifiers */
+
/* vim: set sw=2 sts=2 et fdm=marker : */
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
-/* no global variables */
+static int pagesize;
/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
#elif HAVE_PROCINFO_H
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
-/* no initialization */
+ pagesize = getpagesize();
/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
#elif HAVE_PROCINFO_H
tmp = strtoll (fields[1], &endptr, /* base = */ 10);
if ((errno == 0) && (endptr != fields[1]))
{
- if (strncmp (buffer, "VmData", 6) == 0)
+ if (strncmp (buffer, "VmData", 6) == 0)
{
data = tmp;
}
char *fields[64];
char fields_len;
- int i;
+ int buffer_len;
- int name_len;
+ char *buffer_ptr;
+ size_t name_start_pos;
+ size_t name_end_pos;
+ size_t name_len;
derive_t cpu_user_counter;
derive_t cpu_system_counter;
ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
- i = read_file_contents (filename, buffer, sizeof(buffer) - 1);
- if (i <= 0)
+ buffer_len = read_file_contents (filename,
+ buffer, sizeof(buffer) - 1);
+ if (buffer_len <= 0)
return (-1);
- buffer[i] = 0;
-
- fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
- if (fields_len < 24)
+ buffer[buffer_len] = 0;
+
+ /* The name of the process is enclosed in parens. Since the name can
+ * contain parens itself, spaces, numbers and pretty much everything
+ * else, use these to determine the process name. We don't use
+ * strchr(3) and strrchr(3) to avoid pointer arithmetic which would
+ * otherwise be required to determine name_len. */
+ name_start_pos = 0;
+ while ((buffer[name_start_pos] != '(')
+ && (name_start_pos < buffer_len))
+ name_start_pos++;
+
+ name_end_pos = buffer_len;
+ while ((buffer[name_end_pos] != ')')
+ && (name_end_pos > 0))
+ name_end_pos--;
+
+ /* Either '(' or ')' is not found or they are in the wrong order.
+ * Anyway, something weird that shouldn't happen ever. */
+ if (name_start_pos >= name_end_pos)
{
- DEBUG ("processes plugin: ps_read_process (pid = %i):"
- " `%s' has only %i fields..",
- (int) pid, filename, fields_len);
+ ERROR ("processes plugin: name_start_pos = %zu >= name_end_pos = %zu",
+ name_start_pos, name_end_pos);
return (-1);
}
- /* copy the name, strip brackets in the process */
- name_len = strlen (fields[1]) - 2;
- if ((fields[1][0] != '(') || (fields[1][name_len + 1] != ')'))
+ name_len = (name_end_pos - name_start_pos) - 1;
+ if (name_len >= sizeof (ps->name))
+ name_len = sizeof (ps->name) - 1;
+
+ sstrncpy (ps->name, &buffer[name_start_pos + 1], name_len + 1);
+
+ if ((buffer_len - name_end_pos) < 2)
+ return (-1);
+ buffer_ptr = &buffer[name_end_pos + 2];
+
+ fields_len = strsplit (buffer_ptr, fields, STATIC_ARRAY_SIZE (fields));
+ if (fields_len < 22)
{
- DEBUG ("No brackets found in process name: `%s'", fields[1]);
+ DEBUG ("processes plugin: ps_read_process (pid = %i):"
+ " `%s' has only %i fields..",
+ (int) pid, filename, fields_len);
return (-1);
}
- fields[1] = fields[1] + 1;
- fields[1][name_len] = '\0';
- strncpy (ps->name, fields[1], PROCSTAT_NAME_LEN);
-
- *state = fields[2][0];
+ *state = fields[0][0];
if (*state == 'Z')
{
return (0);
}
- cpu_user_counter = atoll (fields[13]);
- cpu_system_counter = atoll (fields[14]);
- vmem_size = atoll (fields[22]);
- vmem_rss = atoll (fields[23]);
- ps->vmem_minflt_counter = atoll (fields[9]);
- ps->vmem_majflt_counter = atoll (fields[11]);
+ cpu_user_counter = atoll (fields[11]);
+ cpu_system_counter = atoll (fields[12]);
+ vmem_size = atoll (fields[20]);
+ vmem_rss = atoll (fields[21]);
+ ps->vmem_minflt_counter = atol (fields[7]);
+ ps->vmem_majflt_counter = atol (fields[9]);
{
- unsigned long long stack_start = atoll (fields[27]);
- unsigned long long stack_ptr = atoll (fields[28]);
+ unsigned long long stack_start = atoll (fields[25]);
+ unsigned long long stack_ptr = atoll (fields[26]);
stack_size = (stack_start > stack_ptr)
? stack_start - stack_ptr
kvm_t *kd;
char errbuf[1024];
- char cmdline[ARG_MAX];
- char *cmdline_ptr;
struct kinfo_proc *procs; /* array of processes */
- char **argv;
+ struct kinfo_proc *proc_ptr = NULL;
int count; /* returns number of processes */
int i;
/* Iterate through the processes in kinfo_proc */
for (i = 0; i < count; i++)
{
- /* retrieve the arguments */
- cmdline[0] = 0;
- cmdline_ptr = NULL;
-
- argv = kvm_getargv (kd, (const struct kinfo_proc *) &(procs[i]), 0);
- if (argv != NULL)
+ /* Create only one process list entry per _process_, i.e.
+ * filter out threads (duplicate PID entries). */
+ if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid))
{
- int status;
- int argc;
-
- argc = 0;
- while (argv[argc] != NULL)
- argc++;
-
- status = strjoin (cmdline, sizeof (cmdline),
- argv, argc, " ");
+ char cmdline[ARG_MAX] = "";
+ _Bool have_cmdline = 0;
- if (status < 0)
+ proc_ptr = &(procs[i]);
+ /* Don't probe system processes and processes without arguments */
+ if (((procs[i].ki_flag & P_SYSTEM) == 0)
+ && (procs[i].ki_args != NULL))
{
- WARNING ("processes plugin: Command line did "
- "not fit into buffer.");
- }
- else
+ char **argv;
+ int argc;
+ int status;
+
+ /* retrieve the arguments */
+ argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0);
+ argc = 0;
+ if ((argv != NULL) && (argv[0] != NULL))
+ {
+ while (argv[argc] != NULL)
+ argc++;
+
+ status = strjoin (cmdline, sizeof (cmdline), argv, argc, " ");
+ if (status < 0)
+ WARNING ("processes plugin: Command line did not fit into buffer.");
+ else
+ have_cmdline = 1;
+ }
+ } /* if (process has argument list) */
+
+ pse.id = procs[i].ki_pid;
+ pse.age = 0;
+
+ pse.num_proc = 1;
+ pse.num_lwp = procs[i].ki_numthreads;
+
+ pse.vmem_size = procs[i].ki_size;
+ pse.vmem_rss = procs[i].ki_rssize * pagesize;
+ pse.vmem_data = procs[i].ki_dsize * pagesize;
+ pse.vmem_code = procs[i].ki_tsize * pagesize;
+ pse.stack_size = procs[i].ki_ssize * pagesize;
+ pse.vmem_minflt = 0;
+ pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
+ pse.vmem_majflt = 0;
+ pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt;
+
+ pse.cpu_user = 0;
+ pse.cpu_system = 0;
+ pse.cpu_user_counter = 0;
+ pse.cpu_system_counter = 0;
+ /*
+ * The u-area might be swapped out, and we can't get
+ * at it because we have a crashdump and no swap.
+ * If it's here fill in these fields, otherwise, just
+ * leave them 0.
+ */
+ if (procs[i].ki_flag & P_INMEM)
{
- cmdline_ptr = &cmdline[0];
+ pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_usec
+ + (1000000lu * procs[i].ki_rusage.ru_utime.tv_sec);
+ pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_usec
+ + (1000000lu * procs[i].ki_rusage.ru_stime.tv_sec);
}
- }
- pse.id = procs[i].ki_pid;
- pse.age = 0;
-
- pse.num_proc = 1;
- pse.num_lwp = procs[i].ki_numthreads;
-
- pse.vmem_size = procs[i].ki_size;
- pse.vmem_rss = procs[i].ki_rssize * getpagesize();
- pse.vmem_data = procs[i].ki_dsize * getpagesize();
- pse.vmem_code = procs[i].ki_tsize * getpagesize();
- pse.stack_size = procs[i].ki_ssize * getpagesize();
- pse.vmem_minflt = 0;
- pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
- pse.vmem_majflt = 0;
- pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt;
+ /* no I/O data */
+ pse.io_rchar = -1;
+ pse.io_wchar = -1;
+ pse.io_syscr = -1;
+ pse.io_syscw = -1;
- pse.cpu_user = 0;
- pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_sec
- * 1000
- + procs[i].ki_rusage.ru_utime.tv_usec;
- pse.cpu_system = 0;
- pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_sec
- * 1000
- + procs[i].ki_rusage.ru_stime.tv_usec;
-
- /* no io data */
- pse.io_rchar = -1;
- pse.io_wchar = -1;
- pse.io_syscr = -1;
- pse.io_syscw = -1;
+ ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
+ } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
switch (procs[i].ki_stat)
{
case SLOCK: blocked++; break;
case SZOMB: zombies++; break;
}
-
- ps_list_add (procs[i].ki_comm, cmdline_ptr, &pse);
}
kvm_close(kd);
/* TODO: Check if negative values wrap around. Problem: negative temperatures. */
static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
- double scale, double shift)
+ double scale, double shift,
+ const char *host_name, const char *data_name)
{
value_t ret;
uint64_t tmp_unsigned = 0;
int64_t tmp_signed = 0;
- int defined = 1;
+ _Bool defined = 1;
+ /* Set to true when the original SNMP type appears to have been signed. */
+ _Bool prefer_signed = 0;
if ((vl->type == ASN_INTEGER)
|| (vl->type == ASN_UINTEGER)
{
tmp_unsigned = (uint32_t) *vl->val.integer;
tmp_signed = (int32_t) *vl->val.integer;
- DEBUG ("snmp plugin: Parsed int32 value is %"PRIi64".", tmp_signed);
+
+ if ((vl->type == ASN_INTEGER)
+ || (vl->type == ASN_GAUGE))
+ prefer_signed = 1;
+
+ DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
}
else if (vl->type == ASN_COUNTER64)
{
oid_buffer);
else
#endif
- WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)",
- (int) vl->type, oid_buffer);
+ WARNING ("snmp plugin: I don't know the ASN type #%i "
+ "(OID: \"%s\", data block \"%s\", host block \"%s\")",
+ (int) vl->type, oid_buffer,
+ (data_name != NULL) ? data_name : "UNKNOWN",
+ (host_name != NULL) ? host_name : "UNKNOWN");
defined = 0;
}
}
else if (type == DS_TYPE_GAUGE)
{
- ret.gauge = NAN;
- if (defined != 0)
+ if (!defined)
+ ret.gauge = NAN;
+ else if (prefer_signed)
ret.gauge = (scale * tmp_signed) + shift;
+ else
+ ret.gauge = (scale * tmp_unsigned) + shift;
}
else if (type == DS_TYPE_DERIVE)
- ret.derive = (derive_t) tmp_signed;
+ {
+ if (prefer_signed)
+ ret.derive = (derive_t) tmp_signed;
+ else
+ ret.derive = (derive_t) tmp_unsigned;
+ }
else if (type == DS_TYPE_ABSOLUTE)
+ {
ret.absolute = (absolute_t) tmp_unsigned;
+ }
else
{
ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source "
static int csnmp_instance_list_add (csnmp_list_instances_t **head,
csnmp_list_instances_t **tail,
- const struct snmp_pdu *res)
+ const struct snmp_pdu *res,
+ const host_definition_t *hd, const data_definition_t *dd)
{
csnmp_list_instances_t *il;
struct variable_list *vb;
}
else
{
- value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0);
+ value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER,
+ /* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name);
ssnprintf (il->instance, sizeof (il->instance),
"%llu", val.counter);
}
/* Allocate a new `csnmp_list_instances_t', insert the instance name and
* add it to the list */
if (csnmp_instance_list_add (&instance_list, &instance_list_ptr,
- res) != 0)
+ res, host, data) != 0)
{
ERROR ("snmp plugin: csnmp_instance_list_add failed.");
status = -1;
vt->subid = vb->name[vb->name_length - 1];
vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type,
- data->scale, data->shift);
+ data->scale, data->shift, host->name, data->name);
vt->next = NULL;
if (value_table_ptr[i] == NULL)
for (i = 0; i < data->values_len; i++)
if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len,
vb->name, vb->name_length) == 0)
- vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
- data->scale, data->shift);
+ vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
+ data->scale, data->shift, host->name, data->name);
} /* for (res->variables) */
if (res != NULL)
#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
#endif
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
# error "No applicable input method."
#endif
# include <netinet/tcp_var.h>
# include <netdb.h>
# include <arpa/inet.h>
- # include <nlist.h>
+ # if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H
+ # include <nlist.h>
+ # else /* HAVE_BSD_NLIST_H */
+ # include <bsd/nlist.h>
+ # endif
# include <kvm.h>
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+# include <arpa/inet.h>
+# include <sys/socketvar.h>
+#endif /* KERNEL_AIX */
#if KERNEL_LINUX
static const char *tcp_state[] =
# define TCP_STATE_LISTEN 1
# define TCP_STATE_MIN 1
# define TCP_STATE_MAX 10
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+static const char *tcp_state[] =
+{
+ "CLOSED",
+ "LISTEN",
+ "SYN_SENT",
+ "SYN_RCVD",
+ "ESTABLISHED",
+ "CLOSE_WAIT",
+ "FIN_WAIT_1",
+ "CLOSING",
+ "LAST_ACK",
+ "FIN_WAIT_2",
+ "TIME_WAIT"
+};
+
+# define TCP_STATE_LISTEN 1
+# define TCP_STATE_MIN 0
+# define TCP_STATE_MAX 10
+
+struct netinfo_conn {
+ uint32_t unknow1[2];
+ uint16_t dstport;
+ uint16_t unknow2;
+ struct in6_addr dstaddr;
+ uint16_t srcport;
+ uint16_t unknow3;
+ struct in6_addr srcaddr;
+ uint32_t unknow4[36];
+ uint16_t tcp_state;
+ uint16_t unknow5[7];
+};
+
+struct netinfo_header {
+ unsigned int proto;
+ unsigned int size;
+};
+
+# define NETINFO_TCP 3
+extern int netinfo (int proto, void *data, int *size, int n);
+#endif /* KERNEL_AIX */
#define PORT_COLLECT_LOCAL 0x01
#define PORT_COLLECT_REMOTE 0x02
return (0);
}
-#endif /* HAVE_LIBKVM_NLIST */
+/* #endif HAVE_LIBKVM_NLIST */
+
+#elif KERNEL_AIX
+
+static int conn_read (void)
+{
+ int size;
+ int i;
+ int nconn;
+ void *data;
+ struct netinfo_header *header;
+ struct netinfo_conn *conn;
+
+ conn_reset_port_entry ();
+
+ size = netinfo(NETINFO_TCP, 0, 0, 0);
+ if (size < 0)
+ {
+ ERROR ("tcpconns plugin: netinfo failed return: %i", size);
+ return (-1);
+ }
+
+ if (size == 0)
+ return (0);
+
+ if ((size - sizeof (struct netinfo_header)) % sizeof (struct netinfo_conn))
+ {
+ ERROR ("tcpconns plugin: invalid buffer size");
+ return (-1);
+ }
+
+ data = malloc(size);
+ if (data == NULL)
+ {
+ ERROR ("tcpconns plugin: malloc failed");
+ return (-1);
+ }
+
+ if (netinfo(NETINFO_TCP, data, &size, 0) < 0)
+ {
+ ERROR ("tcpconns plugin: netinfo failed");
+ free(data);
+ return (-1);
+ }
+
+ header = (struct netinfo_header *)data;
+ nconn = header->size;
+ conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header));
+
+ for (i=0; i < nconn; conn++, i++)
+ {
+ conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state);
+ }
+
+ free(data);
+
+ conn_submit_all ();
+
+ return (0);
+}
+#endif /* KERNEL_AIX */
void module_register (void)
{
/* no initialization */
#elif HAVE_LIBKVM_NLIST
plugin_register_init ("tcpconns", conn_init);
+#elif KERNEL_AIX
+ /* no initialization */
#endif
plugin_register_read ("tcpconns", conn_read);
} /* void module_register */
#!/usr/bin/env bash
- DEFAULT_VERSION="5.0.3.git"
+ DEFAULT_VERSION="5.0.4.git"
VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`"
VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`"
-if test "x`uname -s`" = "xAIX" || test "x`uname -s`" = "xSunOS" ; then
+if test "x`uname -s`" = "xAIX" ; then
echo "$VERSION\c"
else
echo -n "$VERSION"