Merge branch 'collectd-4.8' into collectd-4.9
authorFlorian Forster <octo@huhu.verplant.org>
Wed, 7 Apr 2010 09:55:15 +0000 (11:55 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Wed, 7 Apr 2010 09:55:15 +0000 (11:55 +0200)
1  2 
README
configure.in
src/Makefile.am
src/collectd.conf.in
src/network.c

diff --combined README
--- 1/README
--- 2/README
+++ b/README
@@@ -40,9 -40,6 +40,9 @@@ Feature
      - conntrack
        Number of nf_conntrack entries.
  
 +    - contextswitch
 +      Number of context switches done by the operating system.
 +
      - cpu
        CPU utilization: Time spent in the system, user, nice, idle, and related
        states.
        MySQL server statistics: Commands issued, handlers triggered, thread
        usage, query cache utilization and traffic/octets sent and received.
  
 +    - netapp
 +      Plugin to query performance values from a NetApp storage system using the
 +      “Manage ONTAP” SDK provided by NetApp.
 +
      - netlink
        Very detailed Linux network interface and routing statistics. You can get
        (detailed) information on interfaces, qdiscs, classes, and, if you can
      - protocols
        Counts various aspects of network protocols such as IP, TCP, UDP, etc.
  
 +    - python
 +      The python plugin implements a Python interpreter into collectd. This
 +      makes it possible to write plugins in Python which are executed by
 +      collectd without the need to start a heavy interpreter every interval.
 +      See collectd-python(5) for details.
 +
 +    - routeros
 +      Query interface and wireless registration statistics from RouterOS.
 +
      - rrdcached
        RRDtool caching daemon (RRDcacheD) statistics.
  
      - zfs_arc
        Statistics for ZFS' “Adaptive Replacement Cache” (ARC).
  
-   * Output can be written or send to various destinations by the following
+   * Output can be written or sent to various destinations by the following
      plugins:
  
      - csv
        you can easily do weird stuff with the plugins we didn't dare think of
        ;) See collectd-perl(5).
  
 +    - python
 +      It's possible to implement write plugins in Python using the python
 +      plugin. See collectd-python(5) for details.
 +
      - rrdcached
        Output to round-robin-database (RRD) files using the RRDtool caching
        daemon (RRDcacheD) - see rrdcached(1). That daemon provides a general
        Log messages are propagated to plugins written in Perl as well.
        See collectd-perl(5).
  
 +    - python
 +      It's possible to implement log plugins in Python using the python plugin.
 +      See collectd-python(5) for details.
 +
      - syslog
        Logs to the standard UNIX logging mechanism, syslog.
  
        Notifications are propagated to plugins written in Perl as well.
        See collectd-perl(5).
  
 +    - python
 +      It's possible to implement notification plugins in Python using the
 +      python plugin. See collectd-python(5) for details.
 +
    * Value processing can be controlled using the "filter chain" infrastructure
      and "matches" and "targets". The following plugins are available:
  
      - match_empty_counter
        Match counter values which are currently zero.
  
 +    - match_hashed
 +      Match values using a hash function of the hostname.
 +
      - match_regex
        Match values by their identifier based on regular expressions.
  
      - target_replace
        Replace parts of an identifier using regular expressions.
  
 +    - target_scale
 +      Scale (multiply) values by an arbitrary value.
 +
      - target_set
        Set (overwrite) entire parts of an identifier.
  
      network plugins, makes sure your resources are used efficiently. Also,
      since collectd is programmed multithreaded it benefits from hyperthreading
      and multicore processors and makes sure that the daemon isn't idle if only
-     one plugins waits for an IO-operation to complete.
+     one plugin waits for an IO-operation to complete.
  
    * Once set up, hardly any maintenance is necessary. Setup is kept as easy
      as possible and the default values should be okay for most users.
@@@ -541,10 -507,6 +541,10 @@@ Prerequisite
      Unsurprisingly used by the `mysql' plugin.
      <http://dev.mysql.com/>
  
 +  * libnetapp (optional)
 +    Required for the “netapp” plugin.
 +    This library is part of the “Manage ONTAP SDK” published by NetApp.
 +
    * libnetlink (optional)
      Used, obviously, for the `netlink' plugin.
      <http://www.linuxfoundation.org/en/Net:Iproute2>
      The PostgreSQL C client library used by the `postgresql' plugin.
      <http://www.postgresql.org/>
  
 +  * libpython (optional)
 +    Used by the `python' plugin. Currently, only 2.3 ≦ Python < 3 is supported.
 +    <http://www.python.org/>
 +
 +  * librouteros (optional)
 +    Used by the `routeros' plugin to connect to a device running `RouterOS'.
 +    <http://verplant.org/librouteros/>
 +
    * librrd (optional)
      Used by the `rrdtool' and `rrdcached' plugins. The latter requires RRDtool
      client support which was added after version 1.3 of RRDtool. Versions 1.0,
diff --combined configure.in
@@@ -9,7 -9,6 +9,7 @@@ m4_ifdef([LT_PACKAGE_VERSION]
         LT_CONFIG_LTDL_DIR([libltdl])
         LT_INIT([dlopen])
         LTDL_INIT([convenience])
 +       AC_DEFINE(LIBTOOL_VERSION, 2, [Define to used libtool version.])
        ]
  ,
        # libtool <= 1.5
@@@ -19,7 -18,6 +19,7 @@@
         AC_SUBST(LIBLTDL)
         AC_LIBTOOL_DLOPEN
         AC_CONFIG_SUBDIRS(libltdl)
 +       AC_DEFINE(LIBTOOL_VERSION, 1, [Define to used libtool version.])
        ]
  )
  
@@@ -63,10 -61,6 +63,10 @@@ case $host_os i
        *openbsd*)
        ac_system="OpenBSD"
        ;;
 +      *aix*)
 +      AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel])
 +      ac_system="AIX"
 +      ;;
        *)
        ac_system="unknown"
  esac
@@@ -268,22 -262,6 +268,22 @@@ AC_CHECK_HEADERS(sys/sysctl.h, [], []
  #endif
  ])
  
 +AC_MSG_CHECKING([for sysctl kern.cp_times])
 +if test -x /sbin/sysctl
 +then
 +      /sbin/sysctl kern.cp_times 2>/dev/null
 +      if test $? -eq 0
 +      then
 +              AC_MSG_RESULT([yes])
 +              AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIMES, 1,
 +              [Define if sysctl supports kern.cp_times])
 +      else
 +              AC_MSG_RESULT([no])
 +      fi
 +else
 +      AC_MSG_RESULT([no])
 +fi
 +
  # For hddtemp module
  AC_CHECK_HEADERS(linux/major.h libgen.h)
  
@@@ -550,8 -528,16 +550,16 @@@ AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB
  AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
  
  nanosleep_needs_rt="no"
- AC_CHECK_FUNCS(nanosleep, [], AC_CHECK_LIB(rt, nanosleep, [nanosleep_needs_rt="yes"], AC_MSG_ERROR(cannot find nanosleep)))
+ nanosleep_needs_posix4="no"
+ AC_CHECK_FUNCS(nanosleep,
+     [],
+     AC_CHECK_LIB(rt, nanosleep,
+         [nanosleep_needs_rt="yes"],
+         AC_CHECK_LIB(posix4, nanosleep,
+             [nanosleep_needs_posix4="yes"],
+             AC_MSG_ERROR(cannot find nanosleep))))
  AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes")
+ AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$nanosleep_needs_posix4" = "xyes")
  
  AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"])
  AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
@@@ -633,8 -619,6 +641,8 @@@ static float foo = NAN
    fi
  fi
  if test "x$nan_type" = "xnone"; then
 +  SAVE_LDFLAGS=$LDFLAGS
 +  LDFLAGS="$LDFLAGS -lm"
    AC_CACHE_CHECK([whether NAN can be defined by 0/0],
      [c_cv_have_nan_zero],
      AC_RUN_IFELSE(
@@@ -661,7 -645,6 +669,7 @@@ static float foo = NAN
        [c_cv_have_nan_zero="no"]
      )
    )
 +  LDFLAGS=$SAVE_LDFLAGS
    if test "x$c_cv_have_nan_zero" = "xyes"
    then
      nan_type="zero"
  m4_divert_once([HELP_WITH], [
  collectd additional packages:])
  
 +AM_CONDITIONAL([BUILD_AIX],[test "x$x$ac_system" = "xAIX"]) 
 +
 +if test "x$ac_system" = "xAIX"
 +then
 +      with_perfstat="yes"
 +      with_procinfo="yes"
 +else
 +      with_perfstat="no (AIX only)"
 +      with_procinfo="no (AIX only)"
 +fi
 +
 +if test "x$with_perfstat" = "xyes"
 +then
 +      AC_CHECK_LIB(perfstat, perfstat_reset, [with_perfstat="yes"], [with_perfstat="no (perfstat not found)"], [])
 +#     AC_CHECK_HEADERS(sys/protosw.h libperfstat.h,, [with_perfstat="no (perfstat not found)"])
 +fi
 +if test "x$with_perfstat" = "xyes"
 +then
 +       AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)])
 +fi
 +AM_CONDITIONAL(BUILD_WITH_PERFSTAT, test "x$with_perfstat" = "xyes")
 +
 +# Processes plugin under AIX.
 +if test "x$with_procinfo" = "xyes"
 +then
 +      AC_CHECK_HEADERS(procinfo.h,, [with_procinfo="no (procinfo.h not found)"])
 +fi
 +if test "x$with_procinfo" = "xyes"
 +then
 +       AC_DEFINE(HAVE_PROCINFO_H, 1, [Define to 1 if you have the procinfo.h])
 +fi
 +
  if test "x$ac_system" = "xSolaris"
  then
        with_kstat="yes"
  AM_CONDITIONAL(BUILD_WITH_LIBNETLINK, test "x$with_libnetlink" = "xyes")
  # }}}
  
 +# --with-libnetapp {{{
 +AC_ARG_VAR([LIBNETAPP_CPPFLAGS], [C preprocessor flags required to build with libnetapp])
 +AC_ARG_VAR([LIBNETAPP_LDFLAGS],  [Linker flags required to build with libnetapp])
 +AC_ARG_VAR([LIBNETAPP_LIBS],     [Other libraries required to link against libnetapp])
 +LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS"
 +LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS"
 +LIBNETAPP_LIBS="$LIBNETAPP_LIBS"
 +AC_ARG_WITH(libnetapp, [AS_HELP_STRING([--with-libnetapp@<:@=PREFIX@:>@], [Path to libnetapp.])],
 +[
 + if test -d "$withval"
 + then
 +       LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS -I$withval/include"
 +       LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS -L$withval/lib"
 +       with_libnetapp="yes"
 + else
 +       with_libnetapp="$withval"
 + fi
 +],
 +[
 + with_libnetapp="yes"
 +])
 +
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +CPPFLAGS="$CPPFLAGS $LIBNETAPP_CPPFLAGS"
 +LDFLAGS="$LDFLAGS $LIBNETAPP_LDFLAGS"
 +
 +if test "x$with_libnetapp" = "xyes"
 +then
 +      if test "x$LIBNETAPP_CPPFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([netapp CPPFLAGS: $LIBNETAPP_CPPFLAGS])
 +      fi
 +      AC_CHECK_HEADERS(netapp_api.h,
 +              [with_libnetapp="yes"],
 +              [with_libnetapp="no (netapp_api.h not found)"])
 +fi
 +
 +if test "x$with_libnetapp" = "xyes"
 +then
 +      if test "x$LIBNETAPP_LDFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([netapp LDFLAGS: $LIBNETAPP_LDFLAGS])
 +      fi
 +
 +      if test "x$LIBNETAPP_LIBS" = "x"
 +      then
 +              LIBNETAPP_LIBS="-lpthread -lxml -ladt -lssl -lm -lcrypto -lz"
 +      fi
 +      AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
 +
 +      AC_CHECK_LIB(netapp, na_server_invoke_elem,
 +              [with_libnetapp="yes"],
 +              [with_libnetapp="no (symbol na_server_invoke_elem not found)"],
 +              [$LIBNETAPP_LIBS])
 +      LIBNETAPP_LIBS="-lnetapp $LIBNETAPP_LIBS"
 +fi
 +
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +
 +if test "x$with_libnetapp" = "xyes"
 +then
 +      AC_DEFINE(HAVE_LIBNETAPP, 1, [Define to 1 if you have the netapp library (-lnetapp).])
 +fi
 +
 +AC_SUBST(LIBNETAPP_CPPFLAGS)
 +AC_SUBST(LIBNETAPP_LDFLAGS)
 +AC_SUBST(LIBNETAPP_LIBS)
 +AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, test "x$with_libnetapp" = "xyes")
 +# }}}
 +
  # --with-libnetsnmp {{{
  with_snmp_config="net-snmp-config"
  with_snmp_cflags=""
@@@ -2746,184 -2625,6 +2754,184 @@@ AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$c
  AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
  # }}}
  
 +# --with-python {{{
 +with_python_prog=""
 +with_python_path="$PATH"
 +AC_ARG_WITH(python, [AS_HELP_STRING([--with-python@<:@=PREFIX@:>@], [Path to the python interpreter.])],
 +[
 + if test "x$withval" = "xyes" || test "x$withval" = "xno"
 + then
 +       with_python="$withval"
 + else if test -x "$withval"
 + then
 +       with_python_prog="$withval"
 +       with_python_path="`dirname \"$withval\"`$PATH_SEPARATOR$with_python_path"
 +       with_python="yes"
 + else if test -d "$withval"
 + then
 +       with_python_path="$withval$PATH_SEPARATOR$with_python_path"
 +       with_python="yes"
 + else
 +       AC_MSG_WARN([Argument not recognized: $withval])
 + fi; fi; fi
 +], [with_python="yes"])
 +
 +SAVE_PATH="$PATH"
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +SAVE_LIBS="$LIBS"
 +
 +PATH="$with_python_path"
 +
 +if test "x$with_python" = "xyes" && test "x$with_python_prog" = "x"
 +then
 +      AC_MSG_CHECKING([for python])
 +      with_python_prog="`which python 2>/dev/null`"
 +      if test "x$with_python_prog" = "x"
 +      then
 +              AC_MSG_RESULT([not found])
 +              with_python="no (interpreter not found)"
 +      else
 +              AC_MSG_RESULT([$with_python_prog])
 +      fi
 +fi
 +
 +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_config_status=$?
 +
 +      if test "$python_config_status" -ne 0 || test "x$python_include_path" = "x"
 +      then
 +              AC_MSG_RESULT([failed with status $python_config_status (output: $python_include_path)])
 +              with_python="no"
 +      else
 +              AC_MSG_RESULT([$python_include_path])
 +      fi
 +fi
 +
 +if test "x$with_python" = "xyes"
 +then
 +      CPPFLAGS="-I$python_include_path $CPPFLAGS"
 +      AC_CHECK_HEADERS(Python.h,
 +                       [with_python="yes"],
 +                       [with_python="no ('Python.h' not found)"])
 +fi
 +
 +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_config_status=$?
 +
 +      if test "$python_config_status" -ne 0 || test "x$python_library_path" = "x"
 +      then
 +              AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_path)])
 +              with_python="no"
 +      else
 +              AC_MSG_RESULT([$python_library_path])
 +      fi
 +fi
 +
 +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_config_status=$?
 +
 +      if test "$python_config_status" -ne 0 || test "x$python_library_flags" = "x"
 +      then
 +              AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_flags)])
 +              with_python="no"
 +      else
 +              AC_MSG_RESULT([$python_library_flags])
 +      fi
 +fi
 +
 +if test "x$with_python" = "xyes"
 +then
 +      LDFLAGS="-L$python_library_path $LDFLAGS"
 +      LIBS="$python_library_flags $LIBS"
 +
 +      AC_CHECK_FUNC(PyObject_CallFunction,
 +                    [with_python="yes"],
 +                    [with_python="no (Symbol 'PyObject_CallFunction' not found)"])
 +fi
 +
 +PATH="$SAVE_PATH"
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +LIBS="$SAVE_LIBS"
 +
 +if test "x$with_python" = "xyes"
 +then
 +      BUILD_WITH_PYTHON_CPPFLAGS="-I$python_include_path"
 +      BUILD_WITH_PYTHON_LDFLAGS="-L$python_library_path"
 +      BUILD_WITH_PYTHON_LIBS="$python_library_flags"
 +      AC_SUBST(BUILD_WITH_PYTHON_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_PYTHON_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_PYTHON_LIBS)
 +fi
 +# }}} --with-python
 +
 +# --with-librouteros {{{
 +AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
 +[
 + if test "x$withval" = "xyes"
 + then
 +       with_librouteros="yes"
 + else if test "x$withval" = "xno"
 + then
 +       with_librouteros="no"
 + else
 +       with_librouteros="yes"
 +       LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS -I$withval/include"
 +       LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS -L$withval/lib"
 + fi; fi
 +],
 +[with_librouteros="yes"])
 +
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +
 +CPPFLAGS="$CPPFLAGS $LIBROUTEROS_CPPFLAGS"
 +LDFLAGS="$LDFLAGS $LIBROUTEROS_LDFLAGS"
 +
 +if test "x$with_librouteros" = "xyes"
 +then
 +      if test "x$LIBROUTEROS_CPPFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([librouteros CPPFLAGS: $LIBROUTEROS_CPPFLAGS])
 +      fi
 +      AC_CHECK_HEADERS(routeros_api.h,
 +      [with_librouteros="yes"],
 +      [with_librouteros="no ('routeros_api.h' not found)"])
 +fi
 +if test "x$with_librouteros" = "xyes"
 +then
 +      if test "x$LIBROUTEROS_LDFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([librouteros LDFLAGS: $LIBROUTEROS_LDFLAGS])
 +      fi
 +      AC_CHECK_LIB(routeros, ros_interface,
 +      [with_librouteros="yes"],
 +      [with_librouteros="no (symbol 'ros_interface' not found)"])
 +fi
 +
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +
 +if test "x$with_librouteros" = "xyes"
 +then
 +      BUILD_WITH_LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS"
 +      BUILD_WITH_LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS"
 +      AC_SUBST(BUILD_WITH_LIBROUTEROS_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBROUTEROS_LDFLAGS)
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBROUTEROS, test "x$with_librouteros" = "xyes")
 +# }}}
 +
  # --with-librrd {{{
  # AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
  librrd_cflags=""
@@@ -3838,7 -3539,6 +3846,7 @@@ plugin_ascent="no
  plugin_battery="no"
  plugin_bind="no"
  plugin_conntrack="no"
 +plugin_contextswitch="no"
  plugin_cpu="no"
  plugin_cpufreq="no"
  plugin_curl_json="no"
@@@ -3876,7 -3576,6 +3884,7 @@@ if test "x$ac_system" = "xLinux
  then
        plugin_battery="yes"
        plugin_conntrack="yes"
 +      plugin_contextswitch="yes"
        plugin_cpu="yes"
        plugin_cpufreq="yes"
        plugin_disk="yes"
        plugin_disk="yes"
  fi
  
 +# AIX
 +if test "x$with_perfstat" = "xyes"
 +then
 +      plugin_cpu="yes"
 +      plugin_disk="yes"
 +      plugin_memory="yes"
 +      plugin_swap="yes"
 +      plugin_interface="yes"
 +      plugin_load="yes"
 +fi
 +
 +if test "x$with_procinfo" = "xyes"
 +then
 +      plugin_processes="yes"
 +fi
 +
  # Solaris
  if test "x$with_kstat" = "xyes"
  then
@@@ -4128,7 -3811,6 +4136,7 @@@ AC_PLUGIN([ascent],      [$plugin_ascen
  AC_PLUGIN([battery],     [$plugin_battery],    [Battery statistics])
  AC_PLUGIN([bind],        [$plugin_bind],       [ISC Bind nameserver statistics])
  AC_PLUGIN([conntrack],   [$plugin_conntrack],  [nf_conntrack statistics])
 +AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
  AC_PLUGIN([cpufreq],     [$plugin_cpufreq],    [CPU frequency statistics])
  AC_PLUGIN([cpu],         [$plugin_cpu],        [CPU usage statistics])
  AC_PLUGIN([csv],         [yes],                [CSV output plugin])
@@@ -4156,7 -3838,6 +4164,7 @@@ AC_PLUGIN([load],        [$plugin_load]
  AC_PLUGIN([logfile],     [yes],                [File logging plugin])
  AC_PLUGIN([madwifi],     [$have_linux_wireless_h], [Madwifi wireless statistics])
  AC_PLUGIN([match_empty_counter], [yes],        [The empty counter match])
 +AC_PLUGIN([match_hashed], [yes],               [The hashed match])
  AC_PLUGIN([match_regex], [yes],                [The regex match])
  AC_PLUGIN([match_timediff], [yes],             [The timediff match])
  AC_PLUGIN([match_value], [yes],                [The value match])
@@@ -4166,7 -3847,6 +4174,7 @@@ AC_PLUGIN([memcached],   [yes]
  AC_PLUGIN([memory],      [$plugin_memory],     [Memory usage])
  AC_PLUGIN([multimeter],  [$plugin_multimeter], [Read multimeter values])
  AC_PLUGIN([mysql],       [$with_libmysql],     [MySQL statistics])
 +AC_PLUGIN([netapp],      [$with_libnetapp],    [NetApp plugin])
  AC_PLUGIN([netlink],     [$with_libnetlink],   [Enhanced Linux network statistics])
  AC_PLUGIN([network],     [yes],                [Network communication plugin])
  AC_PLUGIN([nfs],         [$plugin_nfs],        [NFS statistics])
@@@ -4185,8 -3865,6 +4193,8 @@@ AC_PLUGIN([postgresql],  [$with_libpq]
  AC_PLUGIN([powerdns],    [yes],                [PowerDNS statistics])
  AC_PLUGIN([processes],   [$plugin_processes],  [Process statistics])
  AC_PLUGIN([protocols],   [$plugin_protocols],  [Protocol (IP, TCP, ...) statistics])
 +AC_PLUGIN([python],      [$with_python],       [Embed a Python interpreter])
 +AC_PLUGIN([routeros],    [$with_librouteros],  [RouterOS plugin])
  AC_PLUGIN([rrdcached],   [$librrd_rrdc_update], [RRDTool output plugin])
  AC_PLUGIN([rrdtool],     [$with_librrd],       [RRDTool output plugin])
  AC_PLUGIN([sensors],     [$with_libsensors],   [lm_sensors statistics])
@@@ -4199,7 -3877,6 +4207,7 @@@ AC_PLUGIN([tail],        [yes]
  AC_PLUGIN([tape],        [$plugin_tape],       [Tape drive statistics])
  AC_PLUGIN([target_notification], [yes],        [The notification target])
  AC_PLUGIN([target_replace], [yes],             [The replace target])
 +AC_PLUGIN([target_scale],[yes],                [The scale target])
  AC_PLUGIN([target_set],  [yes],                [The set target])
  AC_PLUGIN([tcpconns],    [$plugin_tcpconns],   [TCP connection statistics])
  AC_PLUGIN([teamspeak2],  [yes],                [TeamSpeak2 server statistics])
@@@ -4398,7 -4075,6 +4406,7 @@@ Configuration
      libkvm  . . . . . . . $with_libkvm
      libmemcached  . . . . $with_libmemcached
      libmysql  . . . . . . $with_libmysql
 +    libnetapp . . . . . . $with_libnetapp
      libnetlink  . . . . . $with_libnetlink
      libnetsnmp  . . . . . $with_libnetsnmp
      libnotify . . . . . . $with_libnotify
      libopenipmi . . . . . $with_libopenipmipthread
      liboping  . . . . . . $with_liboping
      libpcap . . . . . . . $with_libpcap
 +    libperfstat . . . . . $with_perfstat
      libperl . . . . . . . $with_libperl
      libpq . . . . . . . . $with_libpq
      libpthread  . . . . . $with_libpthread
 +    librouteros . . . . . $with_librouteros
      librrd  . . . . . . . $with_librrd
      libsensors  . . . . . $with_libsensors
      libstatgrab . . . . . $with_libstatgrab
      libxmms . . . . . . . $with_libxmms
      libyajl . . . . . . . $with_libyajl
      oracle  . . . . . . . $with_oracle
 +    python  . . . . . . . $with_python
  
    Features:
      daemon mode . . . . . $enable_daemon
      battery . . . . . . . $enable_battery
      bind  . . . . . . . . $enable_bind
      conntrack . . . . . . $enable_conntrack
 +    contextswitch . . . . $enable_contextswitch
      cpu . . . . . . . . . $enable_cpu
      cpufreq . . . . . . . $enable_cpufreq
      csv . . . . . . . . . $enable_csv
      logfile . . . . . . . $enable_logfile
      madwifi . . . . . . . $enable_madwifi
      match_empty_counter . $enable_match_empty_counter
 +    match_hashed  . . . . $enable_match_hashed
      match_regex . . . . . $enable_match_regex
      match_timediff  . . . $enable_match_timediff
      match_value . . . . . $enable_match_value
      memory  . . . . . . . $enable_memory
      multimeter  . . . . . $enable_multimeter
      mysql . . . . . . . . $enable_mysql
 +    netapp  . . . . . . . $enable_netapp
      netlink . . . . . . . $enable_netlink
      network . . . . . . . $enable_network
      nfs . . . . . . . . . $enable_nfs
      powerdns  . . . . . . $enable_powerdns
      processes . . . . . . $enable_processes
      protocols . . . . . . $enable_protocols
 +    python  . . . . . . . $enable_python
 +    routeros  . . . . . . $enable_routeros
      rrdcached . . . . . . $enable_rrdcached
      rrdtool . . . . . . . $enable_rrdtool
      sensors . . . . . . . $enable_sensors
      tape  . . . . . . . . $enable_tape
      target_notification . $enable_target_notification
      target_replace  . . . $enable_target_replace
 +    target_scale  . . . . $enable_target_scale
      target_set  . . . . . $enable_target_set
      tcpconns  . . . . . . $enable_tcpconns
      teamspeak2  . . . . . $enable_teamspeak2
diff --combined src/Makefile.am
@@@ -53,6 -53,9 +53,9 @@@ collectd_DEPENDENCIES 
  if BUILD_WITH_LIBRT
  collectd_LDADD += -lrt
  endif
+ if BUILD_WITH_LIBPOSIX4
+ collectd_LDADD += -lposix4
+ endif
  if BUILD_WITH_LIBSOCKET
  collectd_LDADD += -lsocket
  endif
@@@ -68,10 -71,6 +71,10 @@@ endi
  if BUILD_WITH_LIBDEVINFO
  collectd_LDADD += -ldevinfo
  endif
 +if BUILD_AIX
 +collectd_LDFLAGS += -Wl,-bexpall,-brtllib
 +collectd_LDADD += -lm
 +endif
  
  # The daemon needs to call sg_init, so we need to link it against libstatgrab,
  # too. -octo
@@@ -95,10 -94,6 +98,10 @@@ collectd_nagios_LDADD 
  if BUILD_WITH_LIBSOCKET
  collectd_nagios_LDADD += -lsocket
  endif
 +if BUILD_AIX
 +collectd_nagios_LDADD += -lm
 +endif
 +
  collectd_nagios_LDADD += libcollectdclient/libcollectdclient.la
  collectd_nagios_DEPENDENCIES = libcollectdclient/libcollectdclient.la
  
@@@ -181,14 -176,6 +184,14 @@@ collectd_LDADD += "-dlopen" conntrack.l
  collectd_DEPENDENCIES += conntrack.la
  endif
  
 +if BUILD_PLUGIN_CONTEXTSWITCH
 +pkglib_LTLIBRARIES += contextswitch.la
 +contextswitch_la_SOURCES = contextswitch.c
 +contextswitch_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" contextswitch.la
 +collectd_DEPENDENCIES += contextswitch.la
 +endif
 +
  if BUILD_PLUGIN_CPU
  pkglib_LTLIBRARIES += cpu.la
  cpu_la_SOURCES = cpu.c
@@@ -205,9 -192,6 +208,9 @@@ if BUILD_WITH_LIBSTATGRA
  cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
  endif
 +if BUILD_WITH_PERFSTAT
 +cpu_la_LIBADD += -lperfstat
 +endif
  collectd_LDADD += "-dlopen" cpu.la
  collectd_DEPENDENCIES += cpu.la
  endif
@@@ -295,9 -279,6 +298,9 @@@ if BUILD_WITH_LIBSTATGRA
  disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)  
  disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
  endif
 +if BUILD_WITH_PERFSTAT
 +disk_la_LIBADD += -lperfstat
 +endif
  collectd_LDADD += "-dlopen" disk.la
  collectd_DEPENDENCIES += disk.la
  endif
@@@ -388,9 -369,6 +391,9 @@@ if BUILD_WITH_LIBDEVINF
  interface_la_LIBADD += -ldevinfo
  endif # BUILD_WITH_LIBDEVINFO
  endif # !BUILD_WITH_LIBSTATGRAB
 +if BUILD_WITH_PERFSTAT
 +interface_la_LIBADD += -lperfstat
 +endif
  endif # BUILD_PLUGIN_INTERFACE
  
  if BUILD_PLUGIN_IPTABLES
@@@ -469,9 -447,6 +472,9 @@@ if BUILD_WITH_LIBSTATGRA
  load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
  endif # BUILD_WITH_LIBSTATGRAB
 +if BUILD_WITH_PERFSTAT
 +load_la_LIBADD += -lperfstat
 +endif
  endif # BUILD_PLUGIN_LOAD
  
  if BUILD_PLUGIN_LOGFILE
@@@ -498,14 -473,6 +501,14 @@@ collectd_LDADD += "-dlopen" match_empty
  collectd_DEPENDENCIES += match_empty_counter.la
  endif
  
 +if BUILD_PLUGIN_MATCH_HASHED
 +pkglib_LTLIBRARIES += match_hashed.la
 +match_hashed_la_SOURCES = match_hashed.c
 +match_hashed_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" match_hashed.la
 +collectd_DEPENDENCIES += match_hashed.la
 +endif
 +
  if BUILD_PLUGIN_MATCH_REGEX
  pkglib_LTLIBRARIES += match_regex.la
  match_regex_la_SOURCES = match_regex.c
@@@ -582,9 -549,6 +585,9 @@@ if BUILD_WITH_LIBSTATGRA
  memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
  endif
 +if BUILD_WITH_PERFSTAT
 +memory_la_LIBADD += -lperfstat
 +endif
  endif
  
  if BUILD_PLUGIN_MULTIMETER
@@@ -609,16 -573,6 +612,16 @@@ endi
  collectd_DEPENDENCIES += mysql.la
  endif
  
 +if BUILD_PLUGIN_NETAPP
 +pkglib_LTLIBRARIES += netapp.la
 +netapp_la_SOURCES = netapp.c
 +netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
 +netapp_la_LDFLAGS = -module -avoid-version $(LIBNETAPP_LDFLAGS)
 +netapp_la_LIBADD = $(LIBNETAPP_LIBS)
 +collectd_LDADD += "-dlopen" netapp.la
 +collectd_DEPENDENCIES += netapp.la
 +endif
 +
  if BUILD_PLUGIN_NETLINK
  pkglib_LTLIBRARIES += netlink.la
  netlink_la_SOURCES = netlink.c
@@@ -813,16 -767,6 +816,16 @@@ collectd_LDADD += "-dlopen" powerdns.l
  collectd_DEPENDENCIES += powerdns.la
  endif
  
 +if BUILD_PLUGIN_PYTHON
 +pkglib_LTLIBRARIES += python.la
 +python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h
 +python_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_PYTHON_CPPFLAGS)
 +python_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_PYTHON_LDFLAGS)
 +python_la_LIBADD = $(BUILD_WITH_PYTHON_LIBS)
 +collectd_LDADD += "-dlopen" python.la
 +collectd_DEPENDENCIES += python.la
 +endif
 +
  if BUILD_PLUGIN_PROCESSES
  pkglib_LTLIBRARIES += processes.la
  processes_la_SOURCES = processes.c
@@@ -843,16 -787,6 +846,16 @@@ collectd_LDADD += "-dlopen" protocols.l
  collectd_DEPENDENCIES += protocols.la
  endif
  
 +if BUILD_PLUGIN_ROUTEROS
 +pkglib_LTLIBRARIES += routeros.la
 +routeros_la_SOURCES = routeros.c
 +routeros_la_CPPFLAGS = $(BUILD_WITH_LIBROUTEROS_CPPFLAGS)
 +routeros_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBROUTEROS_LDFLAGS)
 +routeros_la_LIBADD = -lrouteros
 +collectd_LDADD += "-dlopen" routeros.la
 +collectd_DEPENDENCIES += routeros.la
 +endif
 +
  if BUILD_PLUGIN_RRDCACHED
  pkglib_LTLIBRARIES += rrdcached.la
  rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h
@@@ -929,10 -863,6 +932,10 @@@ if BUILD_WITH_LIBSTATGRA
  swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
  endif
 +if BUILD_WITH_PERFSTAT
 +swap_la_LIBADD += -lperfstat
 +endif
 +
  endif
  
  if BUILD_PLUGIN_SYSLOG
@@@ -984,14 -914,6 +987,14 @@@ collectd_LDADD += "-dlopen" target_repl
  collectd_DEPENDENCIES += target_replace.la
  endif
  
 +if BUILD_PLUGIN_TARGET_SCALE
 +pkglib_LTLIBRARIES += target_scale.la
 +target_scale_la_SOURCES = target_scale.c
 +target_scale_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" target_scale.la
 +collectd_DEPENDENCIES += target_scale.la
 +endif
 +
  if BUILD_PLUGIN_TARGET_SET
  pkglib_LTLIBRARIES += target_set.la
  target_set_la_SOURCES = target_set.c
@@@ -1169,7 -1091,6 +1172,7 @@@ dist_man_MANS = collectd.1 
                collectdmon.1 \
                collectd-nagios.1 \
                collectd-perl.5 \
 +              collectd-python.5 \
                collectd-snmp.5 \
                collectd-unixsock.5 \
                types.db.5
@@@ -1185,7 -1106,6 +1188,7 @@@ EXTRA_DIST +=   collectd.conf.pod 
                collectdmon.pod \
                collectd-nagios.pod \
                collectd-perl.pod \
 +              collectd-python.pod \
                collectd.pod \
                collectd-snmp.pod \
                collectd-unixsock.pod \
diff --combined src/collectd.conf.in
@@@ -57,7 -57,6 +57,7 @@@ FQDNLookup   tru
  #@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
  #@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
  #@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
 +#@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch
  @BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
  #@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
  @LOAD_PLUGIN_CSV@LoadPlugin csv
@@@ -89,7 -88,6 +89,7 @@@
  @BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
  #@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
  #@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
 +#@BUILD_PLUGIN_NETAPP_TRUE@LoadPlugin netapp
  #@BUILD_PLUGIN_NETLINK_TRUE@LoadPlugin netlink
  @LOAD_PLUGIN_NETWORK@LoadPlugin network
  #@BUILD_PLUGIN_NFS_TRUE@LoadPlugin nfs
  #@BUILD_PLUGIN_POWERDNS_TRUE@LoadPlugin powerdns
  #@BUILD_PLUGIN_PROCESSES_TRUE@LoadPlugin processes
  #@BUILD_PLUGIN_PROTOCOLS_TRUE@LoadPlugin protocols
 +#@BUILD_PLUGIN_PYTHON_TRUE@LoadPlugin python
 +#@BUILD_PLUGIN_ROUTEROS_TRUE@LoadPlugin routeros
  #@BUILD_PLUGIN_RRDCACHED_TRUE@LoadPlugin rrdcached
  @LOAD_PLUGIN_RRDTOOL@LoadPlugin rrdtool
  #@BUILD_PLUGIN_SENSORS_TRUE@LoadPlugin sensors
  #    URL "http://finance.google.com/finance?q=NYSE%3AAMD"
  #    User "foo"
  #    Password "bar"
 +#    MeasureResponseTime false
  #    <Match>
  #      Regex "<span +class=\"pr\"[^>]*> *([0-9]*\\.[0-9]+) *</span>"
  #      DSType "GaugeAverage"
  #     FSType "ext3"
  #     IgnoreSelected false
  #     ReportByDevice false
 +#     ReportReserved false
 +#     ReportInodes false
  #</Plugin>
  
  #<Plugin disk>
  #     </Database>
  #</Plugin>
  
 +#<Plugin netapp>
 +#     <Host "netapp1.example.com">
 +#             Protocol      "https"
 +#             Address       "10.0.0.1"
 +#             Port          443
 +#             User          "username"
 +#             Password      "aef4Aebe"
 +#             Interval      30
 +#
 +#             <WAFL>
 +#                     Interval 30
 +#                     GetNameCache   true
 +#                     GetDirCache    true
 +#                     GetBufferCache true
 +#                     GetInodeCache  true
 +#             </WAFL>
 +#
 +#             <Disks>
 +#                     Interval 30
 +#                     GetBusy true
 +#             </Disks>
 +#
 +#             <VolumePerf>
 +#                     Interval 30
 +#                     GetIO      "volume0"
 +#                     IgnoreSelectedIO      false
 +#                     GetOps     "volume0"
 +#                     IgnoreSelectedOps     false
 +#                     GetLatency "volume0"
 +#                     IgnoreSelectedLatency false
 +#             </VolumePerf>
 +#
 +#             <VolumeUsage>
 +#                     Interval 30
 +#                     GetCapacity "vol0"
 +#                     GetCapacity "vol1"
 +#                     IgnoreSelectedCapacity false
 +#                     GetSnapshot "vol1"
 +#                     GetSnapshot "vol3"
 +#                     IgnoreSelectedSnapshot false
 +#             </VolumeUsage>
 +#
 +#             <System>
 +#                     Interval 30
 +#                     GetCPULoad     true
 +#                     GetInterfaces  true
 +#                     GetDiskOps     true
 +#                     GetDiskIO      true
 +#             </System>
 +#     </Host>
 +#</Plugin>
 +
  #<Plugin netlink>
  #     Interface "All"
  #     VerboseInterface "All"
  #     TimeToLive "128"
  #     Forward false
  #     CacheFlush 1800
 +#     ReportStats false
  @LOAD_PLUGIN_NETWORK@</Plugin>
  
  #<Plugin nginx>
  
  #<Plugin perl>
  #     IncludeDir "/my/include/path"
- #     BaseName "Collectd::Plugin"
+ #     BaseName "Collectd::Plugins"
  #     EnableDebugger ""
 -#     LoadPlugin foo
 +#     LoadPlugin Monitorus
 +#     LoadPlugin OpenVZ
  #
  #     <Plugin foo>
  #             Foo "Bar"
  
  #<Plugin ping>
  #     Host "host.foo.bar"
 +#     Interval 1.0
 +#     Timeout 0.9
  #     TTL 255
 +#     SourceAddress "1.2.3.4"
 +#     Device "eth0"
 +#     MaxMissed -1
  #</Plugin>
  
  #<Plugin postgresql>
  #     IgnoreSelected false
  #</Plugin>
  
 +#<Plugin python>
 +#     ModulePath "/path/to/your/python/modules"
 +#     LogTraces true
 +#     Interactive true
 +#     Import "spam"
 +#
 +#     <Module spam>
 +#             spam "wonderful" "lovely"
 +#     </Module>
 +#</Plugin>
 +
 +#<Plugin routeros>
 +#     <Router>
 +#             Host "router.example.com"
 +#             Port "8728"
 +#             User "admin"
 +#             Password "dozaiTh4"
 +#             CollectInterface true
 +#             CollectRegistrationTable true
 +#     </Router>
 +#</Plugin>
 +
  #<Plugin rrdcached>
  #     DaemonAddress "unix:/tmp/rrdcached.sock"
  #     DataDir "@prefix@/var/lib/@PACKAGE_NAME@/rrd"
  
  # Load required matches:
  #@BUILD_PLUGIN_MATCH_EMPTY_COUNTER_TRUE@LoadPlugin match_empty_counter
 +#@BUILD_PLUGIN_MATCH_HASHED_TRUE@LoadPlugin match_hashed
  #@BUILD_PLUGIN_MATCH_REGEX_TRUE@LoadPlugin match_regex
  #@BUILD_PLUGIN_MATCH_VALUE_TRUE@LoadPlugin match_value
  #@BUILD_PLUGIN_MATCH_TIMEDIFF_TRUE@LoadPlugin match_timediff
  # Load required targets:
  #@BUILD_PLUGIN_TARGET_NOTIFICATION_TRUE@LoadPlugin target_notification
  #@BUILD_PLUGIN_TARGET_REPLACE_TRUE@LoadPlugin target_replace
 +#@BUILD_PLUGIN_TARGET_SCALE_TRUE@LoadPlugin target_scale
  #@BUILD_PLUGIN_TARGET_SET_TRUE@LoadPlugin target_set
  
  #----------------------------------------------------------------------------#
diff --combined src/network.c
@@@ -256,7 -256,6 +256,7 @@@ typedef struct receive_list_entry_s rec
  static int network_config_ttl = 0;
  static size_t network_config_packet_size = 1024;
  static int network_config_forward = 0;
 +static int network_config_stats = 0;
  
  static sockent_t *sending_sockets = NULL;
  
@@@ -264,7 -263,6 +264,7 @@@ static receive_list_entry_t *receive_li
  static receive_list_entry_t *receive_list_tail = NULL;
  static pthread_mutex_t       receive_list_lock = PTHREAD_MUTEX_INITIALIZER;
  static pthread_cond_t        receive_list_cond = PTHREAD_COND_INITIALIZER;
 +static uint64_t              receive_list_length = 0;
  
  static sockent_t     *listen_sockets = NULL;
  static struct pollfd *listen_sockets_pollfd = NULL;
@@@ -285,22 -283,6 +285,22 @@@ static int              send_buffer_fil
  static value_list_t     send_buffer_vl = VALUE_LIST_STATIC;
  static pthread_mutex_t  send_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
  
 +/* XXX: These counters are incremented from one place only. The spot in which
 + * the values are incremented is either only reachable by one thread (the
 + * dispatch thread, for example) or locked by some lock (send_buffer_lock for
 + * example). Only if neither is true, the stats_lock is acquired. The counters
 + * are always read without holding a lock in the hope that writing 8 bytes to
 + * memory is an atomic operation. */
 +static uint64_t stats_octets_rx  = 0;
 +static uint64_t stats_octets_tx  = 0;
 +static uint64_t stats_packets_rx = 0;
 +static uint64_t stats_packets_tx = 0;
 +static uint64_t stats_values_dispatched = 0;
 +static uint64_t stats_values_not_dispatched = 0;
 +static uint64_t stats_values_sent = 0;
 +static uint64_t stats_values_not_sent = 0;
 +static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
 +
  /*
   * Private functions
   */
@@@ -359,13 -341,12 +359,13 @@@ static int network_dispatch_values (val
    if (!check_receive_okay (vl))
    {
  #if COLLECT_DEBUG
 -        char name[6*DATA_MAX_NAME_LEN];
 -        FORMAT_VL (name, sizeof (name), vl);
 -        name[sizeof (name) - 1] = 0;
 -        DEBUG ("network plugin: network_dispatch_values: "
 -            "NOT dispatching %s.", name);
 +    char name[6*DATA_MAX_NAME_LEN];
 +    FORMAT_VL (name, sizeof (name), vl);
 +    name[sizeof (name) - 1] = 0;
 +    DEBUG ("network plugin: network_dispatch_values: "
 +      "NOT dispatching %s.", name);
  #endif
 +    stats_values_not_dispatched++;
      return (0);
    }
  
    }
  
    plugin_dispatch_values (vl);
 +  stats_values_dispatched++;
  
    meta_data_destroy (vl->meta);
    vl->meta = NULL;
@@@ -1140,7 -1120,10 +1140,10 @@@ static int parse_part_encr_aes256 (sock
    cypher = network_get_aes256_cypher (se, pea.iv, sizeof (pea.iv),
        pea.username);
    if (cypher == NULL)
+   {
+     sfree (pea.username);
      return (-1);
+   }
  
    payload_len = part_size - (PART_ENCRYPTION_AES256_SIZE + username_len);
    assert (payload_len > 0);
        /* in = */ NULL, /* in len = */ 0);
    if (err != 0)
    {
+     sfree (pea.username);
      ERROR ("network plugin: gcry_cipher_decrypt returned: %s",
          gcry_strerror (err));
      return (-1);
        buffer + buffer_offset, payload_len);
    if (memcmp (hash, pea.hash, sizeof (hash)) != 0)
    {
+     sfree (pea.username);
      ERROR ("network plugin: Decryption failed: Checksum mismatch.");
      return (-1);
    }
    *ret_buffer =     buffer     + part_size;
    *ret_buffer_len = buffer_len - part_size;
  
+   sfree (pea.username);
    return (0);
  } /* }}} int parse_part_encr_aes256 */
  /* #endif HAVE_LIBGCRYPT */
@@@ -1549,7 -1536,7 +1556,7 @@@ static int network_set_ttl (const socke
  
                if (setsockopt (se->data.client.fd, IPPROTO_IP, optname,
                                        &network_config_ttl,
-                                       sizeof (network_config_ttl)) == -1)
+                                       sizeof (network_config_ttl)) != 0)
                {
                        char errbuf[1024];
                        ERROR ("setsockopt: %s",
  
                if (setsockopt (se->data.client.fd, IPPROTO_IPV6, optname,
                                        &network_config_ttl,
-                                       sizeof (network_config_ttl)) == -1)
+                                       sizeof (network_config_ttl)) != 0)
                {
                        char errbuf[1024];
                        ERROR ("setsockopt: %s",
@@@ -1989,7 -1976,6 +1996,7 @@@ static void *dispatch_thread (void __at
      ent = receive_list_head;
      if (ent != NULL)
        receive_list_head = ent->next;
 +    receive_list_length--;
      pthread_mutex_unlock (&receive_list_lock);
  
      /* Check whether we are supposed to exit. We do NOT check `listen_loop'
@@@ -2041,13 -2027,11 +2048,13 @@@ static int network_receive (void) /* {{
  
        receive_list_entry_t *private_list_head;
        receive_list_entry_t *private_list_tail;
 +      uint64_t              private_list_length;
  
          assert (listen_sockets_num > 0);
  
        private_list_head = NULL;
        private_list_tail = NULL;
 +      private_list_length = 0;
  
        while (listen_loop == 0)
        {
                                return (-1);
                        }
  
 +                      stats_octets_rx += ((uint64_t) buffer_len);
 +                      stats_packets_rx++;
 +
                        /* TODO: Possible performance enhancement: Do not free
                         * these entries in the dispatch thread but put them in
                         * another list, so we don't have to allocate more and
                        ent->data = malloc (network_config_packet_size);
                        if (ent->data == NULL)
                        {
 +                              sfree (ent);
                                ERROR ("network plugin: malloc failed.");
                                return (-1);
                        }
                        else
                                private_list_tail->next = ent;
                        private_list_tail = ent;
 +                      private_list_length++;
  
                        /* Do not block here. Blocking here has led to
                         * insufficient performance in the past. */
                        if (pthread_mutex_trylock (&receive_list_lock) == 0)
                        {
 +                              assert (((receive_list_head == NULL) && (receive_list_length == 0))
 +                                              || ((receive_list_head != NULL) && (receive_list_length != 0)));
 +
                                if (receive_list_head == NULL)
                                        receive_list_head = private_list_head;
                                else
                                        receive_list_tail->next = private_list_head;
                                receive_list_tail = private_list_tail;
 -
 -                              private_list_head = NULL;
 -                              private_list_tail = NULL;
 +                              receive_list_length += private_list_length;
  
                                pthread_cond_signal (&receive_list_cond);
                                pthread_mutex_unlock (&receive_list_lock);
 +
 +                              private_list_head = NULL;
 +                              private_list_tail = NULL;
 +                              private_list_length = 0;
                        }
                } /* for (listen_sockets_pollfd) */
        } /* while (listen_loop == 0) */
                else
                        receive_list_tail->next = private_list_head;
                receive_list_tail = private_list_tail;
 +              receive_list_length += private_list_length;
  
                private_list_head = NULL;
                private_list_tail = NULL;
 +              private_list_length = 0;
  
                pthread_cond_signal (&receive_list_cond);
                pthread_mutex_unlock (&receive_list_lock);
@@@ -2465,10 -2437,6 +2472,10 @@@ static void flush_buffer (void
                        send_buffer_fill);
  
        network_send_buffer (send_buffer, (size_t) send_buffer_fill);
 +
 +      stats_octets_tx += ((uint64_t) send_buffer_fill);
 +      stats_packets_tx++;
 +
        network_init_buffer ();
  }
  
@@@ -2486,11 -2454,6 +2493,11 @@@ static int network_write (const data_se
          DEBUG ("network plugin: network_write: "
              "NOT sending %s.", name);
  #endif
 +        /* Counter is not protected by another lock and may be reached by
 +         * multiple threads */
 +        pthread_mutex_lock (&stats_lock);
 +        stats_values_not_sent++;
 +        pthread_mutex_unlock (&stats_lock);
          return (0);
        }
  
                /* status == bytes added to the buffer */
                send_buffer_fill += status;
                send_buffer_ptr  += status;
 +
 +              stats_values_sent++;
        }
        else
        {
                {
                        send_buffer_fill += status;
                        send_buffer_ptr  += status;
 +
 +                      stats_values_sent++;
                }
        }
  
@@@ -2567,9 -2526,13 +2574,9 @@@ static int network_config_set_boolean (
    {
      char *str = ci->values[0].value.string;
  
 -    if ((strcasecmp ("true", str) == 0)
 -        || (strcasecmp ("yes", str) == 0)
 -        || (strcasecmp ("on", str) == 0))
 +    if (IS_TRUE (str))
        *retval = 1;
 -    else if ((strcasecmp ("false", str) == 0)
 -        || (strcasecmp ("no", str) == 0)
 -        || (strcasecmp ("off", str) == 0))
 +    else if (IS_FALSE (str))
        *retval = 0;
      else
      {
@@@ -2846,8 -2809,6 +2853,8 @@@ static int network_config (oconfig_item
        network_config_set_buffer_size (child);
      else if (strcasecmp ("Forward", child->key) == 0)
        network_config_set_boolean (child, &network_config_forward);
 +    else if (strcasecmp ("ReportStats", child->key) == 0)
 +      network_config_set_boolean (child, &network_config_stats);
      else if (strcasecmp ("CacheFlush", child->key) == 0)
        /* no op for backwards compatibility only */;
      else
@@@ -2974,83 -2935,6 +2981,83 @@@ static int network_shutdown (void
        return (0);
  } /* int network_shutdown */
  
 +static int network_stats_read (void) /* {{{ */
 +{
 +      uint64_t copy_octets_rx;
 +      uint64_t copy_octets_tx;
 +      uint64_t copy_packets_rx;
 +      uint64_t copy_packets_tx;
 +      uint64_t copy_values_dispatched;
 +      uint64_t copy_values_not_dispatched;
 +      uint64_t copy_values_sent;
 +      uint64_t copy_values_not_sent;
 +      uint64_t copy_receive_list_length;
 +      value_list_t vl = VALUE_LIST_INIT;
 +      value_t values[2];
 +
 +      copy_octets_rx = stats_octets_rx;
 +      copy_octets_tx = stats_octets_tx;
 +      copy_packets_rx = stats_packets_rx;
 +      copy_packets_tx = stats_packets_tx;
 +      copy_values_dispatched = stats_values_dispatched;
 +      copy_values_not_dispatched = stats_values_not_dispatched;
 +      copy_values_sent = stats_values_sent;
 +      copy_values_not_sent = stats_values_not_sent;
 +      copy_receive_list_length = receive_list_length;
 +
 +      /* Initialize `vl' */
 +      vl.values = values;
 +      vl.values_len = 2;
 +      vl.time = 0;
 +      vl.interval = interval_g;
 +      sstrncpy (vl.host, hostname_g, sizeof (vl.host));
 +      sstrncpy (vl.plugin, "network", sizeof (vl.plugin));
 +
 +      /* Octets received / sent */
 +      vl.values[0].counter = (counter_t) copy_octets_rx;
 +      vl.values[1].counter = (counter_t) copy_octets_tx;
 +      sstrncpy (vl.type, "if_octets", sizeof (vl.type));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Packets received / send */
 +      vl.values[0].counter = (counter_t) copy_packets_rx;
 +      vl.values[1].counter = (counter_t) copy_packets_tx;
 +      sstrncpy (vl.type, "if_packets", sizeof (vl.type));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Values (not) dispatched and (not) send */
 +      sstrncpy (vl.type, "total_values", sizeof (vl.type));
 +      vl.values_len = 1;
 +
 +      vl.values[0].derive = (derive_t) copy_values_dispatched;
 +      sstrncpy (vl.type_instance, "dispatch-accepted",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_not_dispatched;
 +      sstrncpy (vl.type_instance, "dispatch-rejected",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_sent;
 +      sstrncpy (vl.type_instance, "send-accepted",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_not_sent;
 +      sstrncpy (vl.type_instance, "send-rejected",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Receive queue length */
 +      vl.values[0].gauge = (gauge_t) copy_receive_list_length;
 +      sstrncpy (vl.type, "queue_length", sizeof (vl.type));
 +      vl.type_instance[0] = 0;
 +      plugin_dispatch_values (&vl);
 +
 +      return (0);
 +} /* }}} int network_stats_read */
 +
  static int network_init (void)
  {
        static _Bool have_init = false;
        gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  #endif
  
 +      if (network_config_stats != 0)
 +              plugin_register_read ("network", network_stats_read);
 +
        plugin_register_shutdown ("network", network_shutdown);
  
        send_buffer = malloc (network_config_packet_size);