Merge branch 'collectd-5.4'
authorFlorian Forster <octo@collectd.org>
Sat, 6 Sep 2014 09:30:20 +0000 (11:30 +0200)
committerFlorian Forster <octo@collectd.org>
Sat, 6 Sep 2014 09:30:20 +0000 (11:30 +0200)
13 files changed:
1  2 
bindings/java/org/collectd/java/GenericJMXConfConnection.java
contrib/redhat/collectd.spec
src/collectd.conf.in
src/collectd.conf.pod
src/curl.c
src/java.c
src/memcachec.c
src/meta_data.c
src/network.c
src/utils_format_json.c
src/utils_match.c
src/utils_match.h
src/utils_rrdcreate.c

@@@ -1,24 -1,19 +1,24 @@@
 -/*
 - * collectd/java - org/collectd/java/GenericJMXConfConnection.java
 +/**
 + * collectd - bindings/java/org/collectd/java/GenericJMXConfConnection.java
   * Copyright (C) 2009-2012  Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; only version 2 of the License is applicable.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
   *   Florian octo Forster <octo at collectd.org>
@@@ -35,8 -30,6 +35,6 @@@ import java.net.InetAddress
  import java.net.UnknownHostException;
  
  import javax.management.MBeanServerConnection;
- import javax.management.ObjectName;
- import javax.management.MalformedObjectNameException;
  
  import javax.management.remote.JMXServiceURL;
  import javax.management.remote.JMXConnector;
@@@ -91,7 -84,15 +89,7 @@@ class GenericJMXConfConnectio
        return (this._host);
      }
  
 -    try
 -    {
 -      InetAddress localHost = InetAddress.getLocalHost();
 -      return (localHost.getHostName ());
 -    }
 -    catch (UnknownHostException e)
 -    {
 -      return ("localhost");
 -    }
 +    return Collectd.getHostname();
    } /* }}} String getHost */
  
  private void connect () /* {{{ */
  
      environment = new HashMap ();
      environment.put (JMXConnector.CREDENTIALS, credentials);
 +    environment.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader());
    }
  
    try
  %define with_nut 0%{!?_without_nut:1}
  %define with_olsrd 0%{!?_without_olsrd:1}
  %define with_openvpn 0%{!?_without_openvpn:1}
- %define with_perl 0%{!?_without_perl:0%{?_has_perl_extutils_embed}}
+ %define with_perl 0%{!?_without_perl:1}
  %define with_pinba 0%{!?_without_pinba:1}
  %define with_ping 0%{!?_without_ping:1}
  %define with_postgresql 0%{!?_without_postgresql:1}
  %define with_write_graphite 0%{!?_without_write_graphite:1}
  %define with_write_http 0%{!?_without_write_http:1}
  %define with_write_riemann 0%{!?_without_write_riemann:1}
 +%define with_zfs_arc 0%{!?_without_zfs_arc:1}
  
  # Plugins not built by default because of dependencies on libraries not
  # available in RHEL or EPEL:
  %define with_write_redis 0%{!?_without_write_redis:0}
  # plugin xmms disabled, requires xmms
  %define with_xmms 0%{!?_without_xmms:0}
 -# plugin zfs_arc disabled, requires FreeBSD/Solaris
 -%define with_zfs_arc 0%{!?_without_zfs_arc:0}
  
  Summary:      Statistics collection daemon for filling RRD files
  Name:         collectd
@@@ -503,7 -504,11 +503,11 @@@ Summary: Perl plugin for collect
  Group:                System Environment/Daemons
  Requires:     %{name}%{?_isa} = %{version}-%{release}
  Requires:     perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
+ %if 0%{?rhel} >= 6
  BuildRequires:        perl-ExtUtils-Embed
+ %else
+ BuildRequires:        perl
+ %endif
  %description perl
  The Perl plugin embeds a Perl interpreter into collectd and exposes the
  application programming interface (API) to Perl-scripts.
  - Enable cgroups, lvm and statsd plugins
  - Enable (but don't build by default) mic, aquaero and sigrok plugins
  
- * Wed Aug 06 2014 Marc Fournier <marc.fournier@camptocamp.com> 5.3.1-2
- - Enabled modbus plugin
  * Tue Aug 06 2013 Marc Fournier <marc.fournier@camptocamp.com> 5.3.1-1
  - New upstream version
  - Added RHEL5 support:
  - Removed duplicate --enable-aggregation
  - Added some comments & usage examples
  - Replaced a couple of "Buildrequires" by "BuildRequires"
+ - Enabled modbus plugin
+ - Allow perl plugin to build on RHEL5
  
  * Wed Apr 10 2013 Marc Fournier <marc.fournier@camptocamp.com> 5.3.0-1
  - New upstream version
  * Sat Nov 17 2012 Ruben Kerkhof <ruben@tilaa.nl> 5.1.0-2
  - Move perl stuff to perl_vendorlib
  - Replace hardcoded paths with macros
 -- Remove unneccesary Requires
 +- Remove unnecessary Requires
  - Removed .a and .la files
  - Some other small cleanups
  
  - New upstream version
  - Changes to support 5.1.0
  - Enabled all buildable plugins based on libraries available on EL6 + EPEL
 -- All plugins requiring external libraries are now shipped in seperate
 +- All plugins requiring external libraries are now shipped in separate
    packages.
  - No longer treat Java plugin as an exception, correctly set $JAVA_HOME during
    the build process + ensure build deps are installed.
diff --combined src/collectd.conf.in
@@@ -52,7 -52,6 +52,7 @@@
  
  @LOAD_PLUGIN_SYSLOG@LoadPlugin syslog
  @LOAD_PLUGIN_LOGFILE@LoadPlugin logfile
 +@LOAD_PLUGIN_LOG_LOGSTASH@LoadPlugin log_logstash
  
  #<Plugin logfile>
  #     LogLevel @DEFAULT_LOG_LEVEL@
  #     PrintSeverity false
  #</Plugin>
  
 +#<Plugin log_logstash>
 +#     LogLevel @DEFAULT_LOG_LEVEL@
 +#     File "@localstatedir@/log/@PACKAGE_NAME@.json.log"
 +#</Plugin>
 +
  #<Plugin syslog>
  #     LogLevel @DEFAULT_LOG_LEVEL@
  #</Plugin>
@@@ -87,7 -81,6 +87,7 @@@
  #@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors
  #@BUILD_PLUGIN_AQUAERO_TRUE@LoadPlugin aquaero
  #@BUILD_PLUGIN_ASCENT_TRUE@LoadPlugin ascent
 +#@BUILD_PLUGIN_BAROMETER_TRUE@LoadPlugin barometer
  #@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
  #@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
  #@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
  #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
  #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
  #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
 +#@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd
  #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
  #@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy
  #@BUILD_PLUGIN_ETHSTAT_TRUE@LoadPlugin ethstat
  #@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
  #@BUILD_PLUGIN_WRITE_GRAPHITE_TRUE@LoadPlugin write_graphite
  #@BUILD_PLUGIN_WRITE_HTTP_TRUE@LoadPlugin write_http
 +#@BUILD_PLUGIN_WRITE_KAFKA_TRUE@LoadPlugin write_kafka
  #@BUILD_PLUGIN_WRITE_MONGODB_TRUE@LoadPlugin write_mongodb
  #@BUILD_PLUGIN_WRITE_REDIS_TRUE@LoadPlugin write_redis
  #@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann
 +#@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb
  #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
  #@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
  
  # ription of those options is available in the collectd.conf(5) manual page. #
  ##############################################################################
  
 -#<Plugin "aggregation">
 +#<Plugin aggregation>
  #  <Aggregation>
  #    #Host "unspecified"
  #    Plugin "cpu"
  #  </Aggregation>
  #</Plugin>
  
 -#<Plugin "amqp">
 +#<Plugin amqp>
  #  <Publish "name">
  #    Host "localhost"
  #    Port "5672"
  #     CACert "/etc/ssl/ca.crt"
  #</Plugin>
  
 +#<Plugin "barometer">
 +#   Device            "/dev/i2c-0";
 +#   Oversampling      512
 +#   PressureOffset    0.0
 +#   TemperatureOffset 0.0
 +#   Normalization     2
 +#   Altitude          238.0
 +#   TemperatureSensor "myserver/onewire-F10FCA000800/temperature"
 +#</Plugin>
 +
  #<Plugin "bind">
  #  URL "http://localhost:8053/"
  #  ParseTime       false
  #  IgnoreSelected false
  #</Plugin>
  
 +#<Plugin cpu>
 +#  ReportActive false
 +#  ReportByCpu true
 +#  ValuesPercentage false
 +#</Plugin>
 +#
  #<Plugin csv>
  #     DataDir "@localstatedir@/lib/@PACKAGE_NAME@/csv"
  #     StoreRates false
  #    URL "http://finance.google.com/finance?q=NYSE%3AAMD"
  #    User "foo"
  #    Password "bar"
 +#    Digest false
 +#    VerifyPeer true
 +#    VerifyHost true
 +#    CACert "/path/to/ca.crt"
 +#    Header "X-Custom-Header: foobar"
 +#    Post "foo=bar"
 +#
  #    MeasureResponseTime false
 +#    MeasureResponseCode false
  #    <Match>
  #      Regex "<span +class=\"pr\"[^>]*> *([0-9]*\\.[0-9]+) *</span>"
  #      DSType "GaugeAverage"
  #  </URL>
  #</Plugin>
  
 -#<Plugin "curl_xml">
 +#<Plugin curl_xml>
  #  <URL "http://localhost/stats.xml">
  #    Host "my_host"
  #    Instance "some_instance"
  #    User "collectd"
  #    Password "thaiNg0I"
 +#    Digest false
  #    VerifyPeer true
  #    VerifyHost true
  #    CACert "/path/to/ca.crt"
 +#    Header "X-Custom-Header: foobar"
 +#    Post "foo=bar"
  #
  #    <XPath "table[@id=\"magic_level\"]/tr">
  #      Type "magic_level"
  #<Plugin disk>
  #     Disk "/^[hs]d[a-f][0-9]?$/"
  #     IgnoreSelected false
 +#     UseBSDName false
 +#     UdevNameAttr "DEVNAME"
  #</Plugin>
  
  #<Plugin dns>
  #     </Directory>
  #</Plugin>
  
 -#<Plugin "gmond">
 +#<Plugin gmond>
  #  MCReceiveFrom "239.2.11.71" "8649"
  #  <Metric "swap_total">
  #    Type "swap"
  #     IgnoreSelected true
  #</Plugin>
  
 -#<Plugin "java">
 +#<Plugin java>
  #     JVMArg "-verbose:jni"
  #     JVMArg "-Djava.class.path=@prefix@/share/collectd/java/collectd-api.jar"
  #
  #     IgnoreSelected false
  #     HostnameFormat name
  #     InterfaceFormat name
 +#     PluginInstanceFormat name
 +#</Plugin>
 +
 +#<Plugin load>
 +#        ReportRelative true
  #</Plugin>
  
  #<Plugin lpar>
  #     </Instance>
  #</Plugin>
  
 +#<Plugin memory>
 +#     ValuesAbsolute true
 +#     ValuesPercentage false
 +#</Plugin>
 +
  #<Plugin modbus>
  #     <Data "data_name">
  #             RegisterBase 1234
  #             Password "secret"
  #             Database "db_name"
  #             MasterStats true
 +#             ConnectTimeout 10
 +#             InnodbStats true
  #     </Database>
  #
  #     <Database db_name2>
 +#             Alias "squeeze"
  #             Host "localhost"
  #             Socket "/var/run/mysql/mysqld.sock"
  #             SlaveStats true
  #             AuthFile "/etc/collectd/passwd"
  #             Interface "eth0"
  #     </Listen>
- #     MaxPacketSize 1024
+ #     MaxPacketSize 1452
  #
  #     # proxy setup (client and server as above):
  #     Forward true
  #  TimerPercentile 90.0
  #</Plugin>
  
 -#<Plugin "swap">
 +#<Plugin swap>
  #     ReportByDevice false
  #     ReportBytes true
 +#     ValuesAbsolute true
 +#     ValuesPercentage false
  #</Plugin>
  
 -#<Plugin "table">
 +#<Plugin table>
  #     <Table "/proc/slabinfo">
  #             Instance "slabinfo"
  #             Separator " "
  #     </Table>
  #</Plugin>
  
 -#<Plugin "tail">
 +#<Plugin tail>
  #  <File "/var/log/exim4/mainlog">
  #    Instance "exim"
 +#    Interval 60
  #    <Match>
  #      Regex "S=([1-9][0-9]*)"
  #      DSType "CounterAdd"
  #  </File>
  #</Plugin>
  
 -#<Plugin "tail_csv">
 +#<Plugin tail_csv>
  #   <Metric "dropped">
  #       Type "percent"
  #       Instance "dropped"
  #             VerifyPeer true
  #             VerifyHost true
  #             CACert "/etc/ssl/ca.crt"
 +#             CAPath "/etc/ssl/certs/"
 +#             ClientKey "/etc/ssl/client.pem"
 +#             ClientCert "/etc/ssl/client.crt"
 +#             ClientKeyPass "secret"
 +#             SSLVersion "TLSv1"
  #             Format "Command"
  #             StoreRates false
 +#             BufferSize 4096
  #     </URL>
  #</Plugin>
  
 +#<Plugin write_kafka>
 +#  Property "metadata.broker.list" "localhost:9092"
 +#  <Topic "collectd">
 +#    Format JSON
 +#  </Topic>
 +#</Plugin>
 +
  #<Plugin write_mongodb>
  #     <Node "example">
  #             Host "localhost"
  #             StoreRates true
  #             AlwaysAppendDS false
  #             TTLFactor 2.0
 +#             EventServicePrefix ""
  #     </Node>
  #     Tag "foobar"
 +#       Attribute "foo" "bar"
 +#</Plugin>
 +
 +#<Plugin write_tsdb>
 +#     <Node>
 +#             Host "localhost"
 +#             Port "4242"
 +#             HostTags "status=production"
 +#             StoreRates false
 +#             AlwaysAppendDS false
 +#     </Node>
  #</Plugin>
  
  ##############################################################################
  ##############################################################################
  
  #@BUILD_PLUGIN_THRESHOLD_TRUE@LoadPlugin "threshold"
 -#<Plugin "threshold">
 +#<Plugin threshold>
  #  <Type "foo">
  #    WarningMin    0.00
  #    WarningMax 1000.00
diff --combined src/collectd.conf.pod
@@@ -6,17 -6,20 +6,20 @@@ collectd.conf - Configuration for the s
  
  =head1 SYNOPSIS
  
-   BaseDir "/path/to/data/"
-   PIDFile "/path/to/pidfile/collectd.pid"
-   Server  "123.123.123.123" 12345
+   BaseDir "/var/lib/collectd"
+   PIDFile "/run/collectd.pid"
+   Interval 10.0
+   
    LoadPlugin cpu
    LoadPlugin load
+   
    <LoadPlugin df>
      Interval 3600
    </LoadPlugin>
+   <Plugin df>
+     ValuesPercentage true
+   </Plugin>
+   
    LoadPlugin ping
    <Plugin ping>
      Host "example.org"
@@@ -28,7 -31,9 +31,9 @@@
  This config file controls how the system statistics collection daemon
  B<collectd> behaves. The most significant option is B<LoadPlugin>, which
  controls which plugins to load. These plugins ultimately define collectd's
- behavior.
+ behavior. If the B<AutoLoadPlugin> option has been enabled, the explicit
+ B<LoadPlugin> lines may be omitted for all plugins with a configuration block,
+ i.e. a C<E<lt>PluginE<nbsp>...E<gt>> block.
  
  The syntax of this config file is similar to the config file of the famous
  I<Apache> webserver. Each line contains either an option (a key and a list of
@@@ -55,8 -60,9 +60,9 @@@ indenting the wrapped lines
  The configuration is read and processed in order, i.e. from top to bottom. So
  the plugins are loaded in the order listed in this config file. It is a good
  idea to load any logging plugins first in order to catch messages from plugins
- during configuration. Also, the C<LoadPlugin> option B<must> occur B<before>
- the appropriate C<E<lt>Plugin ...E<gt>> block.
+ during configuration. Also, unless B<AutoLoadPlugin> is enabled, the
+ B<LoadPlugin> option I<must> occur I<before> the appropriate
+ C<E<lt>B<Plugin> ...E<gt>> block.
  
  =head1 GLOBAL OPTIONS
  
@@@ -341,10 -347,10 +347,10 @@@ The full example configuration looks li
     <Aggregation>
       Plugin "cpu"
       Type "cpu"
 -     
 +
       GroupBy "Host"
       GroupBy "TypeInstance"
 -     
 +
       CalculateSum true
       CalculateAverage true
     </Aggregation>
@@@ -420,13 -426,13 +426,13 @@@ The following example calculates the av
       Plugin "cpu"
       PluginInstance "/[0,2,4,6,8]$/"
       Type "cpu"
 -     
 +
       SetPlugin "cpu"
       SetPluginInstance "even-%{aggregation}"
 -     
 +
       GroupBy "Host"
       GroupBy "TypeInstance"
 -     
 +
       CalculateAverage true
     </Aggregation>
   </Plugin>
@@@ -497,7 -503,7 +503,7 @@@ possibly filtering or messages
   #   GraphiteSeparateInstances false
   #   GraphiteAlwaysAppendDS false
     </Publish>
 -   
 +
     # Receive values from an AMQP broker
     <Subscribe "some_name">
       Host "localhost"
       Exchange "amq.fanout"
   #   ExchangeType "fanout"
   #   Queue "queue_name"
 + #   QueueDurable false
 + #   QueueAutoDelete true
   #   RoutingKey "collectd.#"
     </Subscribe>
   </Plugin>
@@@ -562,23 -566,9 +568,23 @@@ be bound to this exchange
  
  =item B<Queue> I<Queue> (Subscribe only)
  
 -Configures the I<queue> name to subscribe to. If no queue name was configures
 +Configures the I<queue> name to subscribe to. If no queue name was configured
  explicitly, a unique queue name will be created by the broker.
  
 +=item B<QueueDurable> B<true>|B<false> (Subscribe only)
 +
 +Defines if the I<queue> subscribed to is durable (saved to persistent storage)
 +or transient (will disappear if the AMQP broker is restarted). Defaults to
 +"false".
 +
 +This option should be used in conjunction with the I<Persistent> option on the
 +publish side.
 +
 +=item B<QueueAutoDelete> B<true>|B<false> (Subscribe only)
 +
 +Defines if the I<queue> subscribed to will be deleted once the last consumer
 +unsubscribes. Defaults to "true".
 +
  =item B<RoutingKey> I<Key>
  
  In I<Publish> blocks, this configures the routing key to set on all outgoing
@@@ -827,131 -817,6 +833,131 @@@ and are checked by default depends on t
  
  =back
  
 +=head2 Plugin C<barometer>
 +
 +This plugin reads absolute air pressure using digital barometer sensor MPL115A2
 +or MPL3115 from Freescale (sensor attached to any I2C bus available in
 +the computer, for HW details see 
 +I<http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPL115A> or
 +I<http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPL3115A2>).
 +The sensor type - one fo these two - is detected automatically by the plugin
 +and indicated in the plugin_instance (typically you will see subdirectory
 +"barometer-mpl115" or "barometer-mpl3115").
 +
 +The plugin provides absolute barometric pressure, air pressure reduced to sea
 +level (several possible approximations) and as an auxiliary value also internal
 +sensor temperature. It uses (expects/provides) typical metric units - pressure
 +in [hPa], temperature in [C], altitude in [m].
 +
 +It was developed and tested under Linux only. The only platform dependency is
 +the standard Linux i2c-dev interface (the particular bus driver has to
 +support the SM Bus command subset).
 +
 +The reduction or normalization to mean sea level pressure requires (depedning on
 +selected method/approximation) also altitude and reference to temperature sensor(s).
 +When multiple temperature sensors are configured the minumum of their values is
 +always used (expecting that the warmer ones are affected by e.g. direct sun light
 +at that moment).
 +
 +Synopsis:
 +
 +  <Plugin "barometer">
 +     Device            "/dev/i2c-0";
 +     Oversampling      512
 +     PressureOffset    0.0
 +     TemperatureOffset 0.0
 +     Normalization     2
 +     Altitude          238.0
 +     TemperatureSensor "myserver/onewire-F10FCA000800/temperature"
 +  </Plugin>
 +
 +=over 4
 +
 +=item B<Device> I<device>
 +
 +Device name of the I2C bus to which the sensor is connected. Note that typically
 +you need to have loaded the i2c-dev module.
 +Using i2c-tools you can check/list i2c buses available on your system by:
 +
 +  i2cdetect -l
 +
 +Then you can scan for devices on given bus. E.g. to scan the whole bus 0 use:
 +
 +  i2cdetect -y -a 0
 +
 +This way you should be able to verify that the pressure sensor (either type) is
 +connected and detected on address 0x60.
 +
 +=item B<Oversampling> I<value>
 +
 +For MPL115 this is the size of the averaging window. To filter out sensor noise
 +a simple averaging using floating window of configurable size is used. The plugin
 +will use average of the last C<value> measurements (value of 1 means no averaging).
 +Minimal size is 1, maximal 1024.
 +
 +For MPL3115 this is the oversampling value. The actual oversampling is performed
 +by the sensor and the higher value the higher accuracy and longer conversion time
 +(although nothing to worry about in the collectd context). Supported values are:
 +1, 2, 4, 8, 16, 32, 64 and 128. Any other value is adjusted by the plugin to
 +the closest supported one. Default is 128.
 +
 +=item B<PressureOffset> I<offset>
 +
 +You can further calibrate the sensor by supplying pressure and/or temperature offsets.
 +This is added to the measured/caclulated value (i.e. if the measured value is too high
 +then use negative offset).
 +In hPa, default is 0.0.
 +
 +=item B<TemperatureOffset> I<offset>
 +
 +You can further calibrate the sensor by supplying pressure and/or temperature offsets.
 +This is added to the measured/caclulated value (i.e. if the measured value is too high
 +then use negative offset).
 +In C, default is 0.0.
 +
 +=item B<Normalization> I<method>
 +
 +Normalization method - what approximation/model is used to compute mean sea
 +level pressure from the air absolute pressure.
 +
 +Supported values of the C<method> (integer between from 0 to 2) are:
 +
 +=over 5
 +
 +=item B<0> - no conversion, absolute pressrure is simply copied over. For this method you
 +       do not need to configure C<Altitude> or C<TemperatureSensor>.
 +
 +=item B<1> - international formula for conversion ,
 +See I<http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation>.
 +For this method you have to configure C<Altitude> but do not need C<TemperatureSensor>
 +(uses fixed global temperature average instead).
 +
 +=item B<2> - formula as recommended by the Deutsche Wetterdienst (German
 +Meteorological Service).
 +See I<http://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Theorie>
 +For this method you have to configure both  C<Altitude> and C<TemperatureSensor>.
 +
 +=back
 +
 +
 +=item B<Altitude> I<altitude>
 +
 +The altitude (in meters) of the location where you meassure the pressure.
 +
 +=item B<TemperatureSensor> I<reference>
 +
 +Temperature sensor which should be used as a reference when normalizing the pressure.
 +When specified more sensors a minumum is found and uses each time.
 +The temperature reading directly from this pressure sensor/plugin
 +is typically not suitable as the pressure sensor
 +will be probably inside while we want outside temperature. 
 +The collectd reference name is something like
 +<hostname>/<plugin_name>-<plugin_instance>/<type>-<type_instance>
 +(<type_instance> is usually omitted when there is just single value type).
 +Or you can figure it out from the path of the output data files.
 +
 +=back
 +
  =head2 Plugin C<bind>
  
  Starting with BIND 9.5.0, the most widely used DNS server software provides
@@@ -978,17 -843,17 +984,17 @@@ Synopsis
     ParseTime       false
     OpCodes         true
     QTypes          true
 - 
 +
     ServerStats     true
     ZoneMaintStats  true
     ResolverStats   false
     MemoryStats     true
 - 
 +
     <View "_default">
       QTypes        true
       ResolverStats true
       CacheRRSets   true
 - 
 +
       Zone "127.in-addr.arpa/IN"
     </View>
   </Plugin>
@@@ -1129,44 -994,6 +1135,44 @@@ at all, B<all> cgroups are selected
  
  =back
  
 +=head2 Plugin C<conntrack>
 +
 +This plugin collects IP conntrack statistics.
 +
 +=over 4
 +
 +=item B<OldFiles>
 +
 +Assume the B<conntrack_count> and B<conntrack_max> files to be found in
 +F</proc/sys/net/ipv4/netfilter> instead of F</proc/sys/net/netfilter/>.
 +
 +=back
 +
 +=head2 Plugin C<cpu>
 +
 +The I<CPU plugin> collects CPU usage metrics.
 +
 +The following configuration options are available:
 +
 +=over 4
 +
 +=item B<ReportActive> B<false>|B<true>
 +
 +Reports non-idle CPU usage as the "active" value. Defaults to false.
 +
 +=item B<ReportByCpu> B<false>|B<true>
 +
 +When true reports usage for all cores. When false, reports cpu usage
 +aggregated over all cores.
 +Defaults to true.
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +When true report percentage usage instead of tick values. Defaults to false.
 +
 +=back
 +
 +
  =head2 Plugin C<cpufreq>
  
  This plugin doesn't have any options. It reads
@@@ -1209,16 -1036,6 +1215,16 @@@ finance page and dispatch the value to 
        URL "http://finance.google.com/finance?q=NYSE%3AAMD"
        User "foo"
        Password "bar"
 +      Digest false
 +      VerifyPeer true
 +      VerifyHost true
 +      CACert "/path/to/ca.crt"
 +      Header "X-Custom-Header: foobar"
 +      Post "foo=bar"
 +
 +      MeasureResponseTime false
 +      MeasureResponseCode false
 +
        <Match>
          Regex "<span +class=\"pr\"[^>]*> *([0-9]*\\.[0-9]+) *</span>"
          DSType "GaugeAverage"
@@@ -1250,10 -1067,6 +1256,10 @@@ Username to use if authorization is req
  
  Password to use if authorization is required to read the page.
  
 +=item B<Digest> B<true>|B<false>
 +
 +Enable HTTP digest authentication.
 +
  =item B<VerifyPeer> B<true>|B<false>
  
  Enable or disable peer SSL certificate verification. See
@@@ -1291,19 -1104,13 +1297,19 @@@ C<application/x-www-form-urlencoded>)
  Measure response time for the request. If this setting is enabled, B<Match>
  blocks (see below) are optional. Disabled by default.
  
 +=item B<MeasureResponseCode> B<true>|B<false>
 +
 +Measure response code for the request. If this setting is enabled, B<Match>
 +blocks (see below) are optional. Disabled by default.
 +
  =item B<E<lt>MatchE<gt>>
  
  One or more B<Match> blocks that define how to match information in the data
  returned by C<libcurl>. The C<curl> plugin uses the same infrastructure that's
  used by the C<tail> plugin, so please see the documentation of the C<tail>
 -plugin below on how matches are defined. If the B<MeasureResponseTime> option
 -is set to B<true>, B<Match> blocks are optional.
 +plugin below on how matches are defined. If the B<MeasureResponseTime> or
 +B<MeasureResponseCode> options are set to B<true>, B<Match> blocks are
 +optional.
  
  =back
  
@@@ -1370,25 -1177,12 +1376,25 @@@ The following options are valid within 
  
  Sets the plugin instance to I<Instance>.
  
 +=item B<Interval> I<Interval>
 +
 +Sets the interval (in seconds) in which the values will be collected from this
 +URL. By default the global B<Interval> setting will be used.
 +
  =item B<User> I<Name>
 +
  =item B<Password> I<Password>
 +
 +=item B<Digest> B<true>|B<false>
 +
  =item B<VerifyPeer> B<true>|B<false>
 +
  =item B<VerifyHost> B<true>|B<false>
 +
  =item B<CACert> I<file>
 +
  =item B<Header> I<Header>
 +
  =item B<Post> I<Body>
  
  These options behave exactly equivalent to the appropriate options of the
@@@ -1426,8 -1220,6 +1432,8 @@@ The B<curl_xml plugin> uses B<libcurl> 
       VerifyPeer true
       VerifyHost true
       CACert "/path/to/ca.crt"
 +     Header "X-Custom-Header: foobar"
 +     Post "foo=bar"
  
       <XPath "table[@id=\"magic_level\"]/tr">
         Type "magic_level"
@@@ -1479,8 -1271,6 +1485,8 @@@ Examples
  
  =item B<Password> I<Password>
  
 +=item B<Digest> B<true>|B<false>
 +
  =item B<VerifyPeer> B<true>|B<false>
  
  =item B<VerifyHost> B<true>|B<false>
@@@ -1720,16 -1510,6 +1726,16 @@@ it should be able to handle integer an 
  
  There must be at least one B<ValuesFrom> option inside each B<Result> block.
  
 +=item B<MetadataFrom> [I<column0> I<column1> ...]
 +
 +Names the columns whose content is used as metadata for the data sets
 +that are dispatched to the daemon. 
 +
 +The actual data type in the columns is not that important. The plugin will
 +automatically cast the values to the right type if it know how to do that. So
 +it should be able to handle integer an floating point types, as well as strings
 +(if they include a number at the beginning).
 +
  =back
  
  =head3 B<Database> blocks
@@@ -1844,17 -1624,17 +1850,17 @@@ transfer agents and web caches
  
  =item B<ValuesAbsolute> B<true>|B<false>
  
 -Enables or disables reporting of free, used and used disk space in 1K-blocks. 
 -Defaults to true.
 +Enables or disables reporting of free and used disk space in 1K-blocks.
 +Defaults to B<true>.
  
 -=item B<ValuesPercentage> B<true>|B<false>
 +=item B<ValuesPercentage> B<false>|B<true>
  
 -Enables or disables reporting of free, used and used disk space in percentage.
 -Defaults to false.
 +Enables or disables reporting of free and used disk space in percentage.
 +Defaults to B<false>.
  
 -This is useful for deploying collectd on the cloud, where machines with
 -different disk size may exist. Then it is more practical to configure thresholds
 -based on relative disk size.
 +This is useful for deploying I<collectd> on the cloud, where machines with
 +different disk size may exist. Then it is more practical to configure
 +thresholds based on relative disk size.
  
  =back
  
@@@ -1890,20 -1670,6 +1896,20 @@@ collected. If at least one B<Disk> opti
  set to B<false>, B<only> matching disks will be collected. If B<IgnoreSelected>
  is set to B<true>, all disks are collected B<except> the ones matched.
  
 +=item B<UseBSDName> B<true>|B<false>
 +
 +Whether to use the device's "BSD Name", on MacE<nbsp>OSE<nbsp>X, instead of the
 +default major/minor numbers. Requires collectd to be built with Apple's
 +IOKitLib support.
 +
 +=item B<UdevNameAttr> I<Attribute>
 +
 +Attempt to override disk instance name with the value of a specified udev
 +attribute when built with B<libudev>.  If the attribute is not defined for the
 +given device, the default name is used. Example:
 +
 +  UdevNameAttr "DM_NAME"
 +
  =back
  
  =head2 Plugin C<dns>
@@@ -2452,35 -2218,8 +2458,35 @@@ setting B<name>
  B<address> means use the interface's mac address. This is useful since the
  interface path might change between reboots of a guest or across migrations.
  
 +=item B<PluginInstanceFormat> B<name|uuid>
 +
 +When the libvirt plugin logs data, it sets the plugin_instance of the collected 
 +data according to this setting. The default is to use the guest name as provided 
 +by the hypervisor, which is equal to setting B<name>.
 +
 +B<uuid> means use the guest's UUID.
 +
 +=back
 +
 +=head2 Plugin C<load>
 +
 +The I<Load plugin> collects the system load. These numbers give a rough overview
 +over the utilization of a machine. The system load is defined as the number of
 +runnable tasks in the run-queue and is provided by many operating systems as a
 +one, five or fifteen minute average.
 +
 +The following configuration options are available:
 +
 +=over 4
 +
 +=item B<ReportRelative> B<false>|B<true>
 +
 +When enabled, system load divided by number of available CPU cores is reported
 +for intervals 1 min, 5 min and 15 min. Defaults to false.
 +
  =back
  
 +
  =head2 Plugin C<logfile>
  
  =over 4
@@@ -2515,34 -2254,6 +2521,34 @@@ B<Note>: There is no need to notify th
  log file (e.E<nbsp>g. when rotating the logs). The plugin reopens the file
  for each line it writes.
  
 +=head2 Plugin C<log_logstash>
 +
 +The I<log logstash plugin> behaves like the logfile plugin but formats
 +messages as JSON events for logstash to parse and input.
 +
 +=over 4
 +
 +=item B<LogLevel> B<debug|info|notice|warning|err>
 +
 +Sets the log-level. If, for example, set to B<notice>, then all events with
 +severity B<notice>, B<warning>, or B<err> will be written to the logfile.
 +
 +Please note that B<debug> is only available if collectd has been compiled with
 +debugging support.
 +
 +=item B<File> I<File>
 +
 +Sets the file to write log messages to. The special strings B<stdout> and
 +B<stderr> can be used to write to the standard output and standard error
 +channels, respectively. This, of course, only makes much sense when I<collectd>
 +is running in foreground- or non-daemon-mode.
 +
 +=back
 +
 +B<Note>: There is no need to notify the daemon after moving or removing the
 +log file (e.E<nbsp>g. when rotating the logs). The plugin reopens the file
 +for each line it writes.
 +
  =head2 Plugin C<lpar>
  
  The I<LPAR plugin> reads CPU statistics of I<Logical Partitions>, a
@@@ -2716,7 -2427,7 +2722,7 @@@ B<Synopsis:
     ShowCPU true
     ShowCPUCores true
     ShowMemory true
 -   
 +
     ShowTemperatures true
     Temperature vddg
     Temperature vddq
     ShowPower true
     Power total0
     Power total1
 -   IgnoreSelectedPower true   
 +   IgnoreSelectedPower true
   </Plugin>
  
  The following options are valid inside the B<PluginE<nbsp>mic> block:
  
  =item B<ShowCPU> B<true>|B<false>
  
 -If enabled (the default) a sum of the CPU usage accross all cores is reported.
 +If enabled (the default) a sum of the CPU usage across all cores is reported.
  
  =item B<ShowCPUCores> B<true>|B<false>
  
@@@ -2782,7 -2493,7 +2788,7 @@@ Fan I
  
  =item fout
  
 -Fan Out 
 +Fan Out
  
  =item vccp
  
@@@ -2823,11 -2534,11 +2829,11 @@@ Known power names are
  
  =item total0
  
 -Total power utilization averaged over Time Window 0 (uWatts). 
 +Total power utilization averaged over Time Window 0 (uWatts).
  
  =item total1
  
 -Total power utilization averaged over Time Window 0 (uWatts). 
 +Total power utilization averaged over Time Window 0 (uWatts).
  
  =item inst
  
@@@ -2835,55 -2546,34 +2841,55 @@@ Instantaneous power (uWatts)
  
  =item imax
  
 -Max instantaneous power (uWatts). 
 +Max instantaneous power (uWatts).
  
  =item pcie
  
 -PCI-E connector power (uWatts). 
 +PCI-E connector power (uWatts).
  
  =item c2x3
  
 -2x3 connector power (uWatts). 
 +2x3 connector power (uWatts).
  
  =item c2x4
  
 -2x4 connector power (uWatts). 
 +2x4 connector power (uWatts).
  
  =item vccp
  
 -Core rail (uVolts). 
 +Core rail (uVolts).
  
  =item vddg
  
 -Uncore rail (uVolts). 
 +Uncore rail (uVolts).
  
  =item vddq
  
 -Memory subsystem rail (uVolts). 
 +Memory subsystem rail (uVolts).
 +
 +=back
  
  =back
  
 +=head2 Plugin C<memory>
 +
 +The I<memory plugin> provides the following configuration options:
 +
 +=over 4
 +
 +=item B<ValuesAbsolute> B<true>|B<false>
 +
 +Enables or disables reporting of physical memory usage in absolute numbers,
 +i.e. bytes. Defaults to B<true>.
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +Enables or disables reporting of physical memory usage in percentages, e.g.
 +percent of physical memory used. Defaults to B<false>.
 +
 +This is useful for deploying I<collectd> in a heterogeneous environment in
 +which the sizes of physical memory vary.
 +
  =back
  
  =head2 Plugin C<modbus>
@@@ -2901,19 -2591,19 +2907,19 @@@ B<Synopsis:
     Type voltage
     Instance "input-1"
   </Data>
 - 
 +
   <Data "voltage-input-2">
     RegisterBase 2
     RegisterType float
     Type voltage
     Instance "input-2"
   </Data>
 - 
 +
   <Host "modbus.example.com">
     Address "192.168.0.42"
     Port    "502"
     Interval 60
 -   
 +
     <Slave 1>
       Instance "power-supply"
       Collect  "voltage-input-1"
@@@ -3044,11 -2734,9 +3050,11 @@@ Synopsis
        Password "password"
        Port "3306"
        MasterStats true
 +      ConnectTimeout 10
      </Database>
  
      <Database bar>
 +      Alias "squeeze"
        Host "localhost"
        Socket "/var/run/mysql/mysqld.sock"
        SlaveStats true
@@@ -3063,11 -2751,6 +3069,11 @@@ section "mysql_real_connect()" in the B
  
  =over 4
  
 +=item B<Alias> I<Alias>
 +
 +Alias to use as sender instead of hostname when reporting. This may be useful
 +when having cryptic hostnames.
 +
  =item B<Host> I<Hostname>
  
  Hostname of the database server. Defaults to B<localhost>.
@@@ -3106,11 -2789,6 +3112,11 @@@ only has any effect, if B<Host> is set 
  Otherwise, use the B<Port> option above. See the documentation for the
  C<mysql_real_connect> function for details.
  
 +=item B<InnodbStats> I<true|false>
 +
 +If enabled, metrics about the InnoDB storage engine are collected.
 +Disabled by default.
 +
  =item B<MasterStats> I<true|false>
  
  =item B<SlaveStats> I<true|false>
@@@ -3124,10 -2802,6 +3130,10 @@@ privileges. See the B<User> documentati
  If enabled, the plugin sends a notification if the replication slave I/O and /
  or SQL threads are not running.
  
 +=item B<ConnectTimeout> I<Seconds>
 +
 +Sets the connect timeout for the MySQL client.
 +
  =back
  
  =head2 Plugin C<netapp>
@@@ -3162,7 -2836,7 +3168,7 @@@ Required capabilities are documented be
      User          "username"
      Password      "aef4Aebe"
      Interval      30
 -    
 +
      <WAFL>
        Interval 30
        GetNameCache   true
        GetBufferCache true
        GetInodeCache  true
      </WAFL>
 -    
 +
      <Disks>
        Interval 30
        GetBusy true
      </Disks>
 -    
 +
      <VolumePerf>
        Interval 30
        GetIO      "volume0"
        GetLatency "volume0"
        IgnoreSelectedLatency false
      </VolumePerf>
 -    
 +
      <VolumeUsage>
        Interval 30
        GetCapacity "vol0"
        GetSnapshot "vol3"
        IgnoreSelectedSnapshot false
      </VolumeUsage>
 -    
 +
      <Quota>
        Interval 60
      </Quota>
 -    
 +
      <Snapvault>
        Interval 30
      </Snapvault>
 -    
 +
      <System>
        Interval 30
        GetCPULoad     true
@@@ -3764,7 -3438,7 +3770,7 @@@ signature)
     # Export to an internal server
     # (demonstrates usage without additional options)
     Server "collectd.internal.tld"
 -   
 +
     # Export to an external server
     # (demonstrates usage with signature options)
     <Server "collectd.external.tld">
@@@ -4153,36 -3827,13 +4159,36 @@@ B<EXPERIMENTAL!> See notes below
  The C<onewire> plugin uses the B<owcapi> library from the B<owfs> project
  L<http://owfs.org/> to read sensors connected via the onewire bus.
  
 -Currently only temperature sensors (sensors with the family code C<10>,
 -e.E<nbsp>g. DS1820, DS18S20, DS1920) can be read. If you have other sensors you
 -would like to have included, please send a sort request to the mailing list.
 +It can be used in two possible modes - standard or advanced.
 +
 +In the standard mode only temperature sensors (sensors with the family code
 +C<10>, C<22> and C<28> - e.g. DS1820, DS18S20, DS1920) can be read. If you have
 +other sensors you would like to have included, please send a sort request to
 +the mailing list. You can select sensors to be read or to be ignored depending
 +on the option B<IgnoreSelected>). When no list is provided the whole bus is
 +walked and all sensors are read.
  
  Hubs (the DS2409 chips) are working, but read the note, why this plugin is
  experimental, below.
  
 +In the advanced mode you can configure any sensor to be read (only numerical
 +value) using full OWFS path (e.g. "/uncached/10.F10FCA000800/temperature").
 +In this mode you have to list all the sensors. Neither default bus walk nor
 +B<IgnoreSelected> are used here. Address and type (file) is extracted from
 +the path automatically and should produce compatible structure with the "standard"
 +mode (basically the path is expected as for example
 +"/uncached/10.F10FCA000800/temperature" where it would extract address part
 +"F10FCA000800" and the rest after the slash is considered the type - here
 +"temperature").
 +There are two advantages to this mode - you can access virtually any sensor
 +(not just temperature), select whether to use cached or directly read values
 +and it is slighlty faster. The downside is more complex configuration.
 +
 +The two modes are distinguished automatically by the format of the address.
 +It is not possible to mix the two modes. Once a full path is detected in any
 +B<Sensor> then the whole addressing (all sensors) is considered to be this way
 +(and as standard addresses will fail parsing they will be ignored).
 +
  =over 4
  
  =item B<Device> I<Device>
@@@ -4203,23 -3854,14 +4209,23 @@@ This directive is B<required> and does 
  
  =item B<Sensor> I<Sensor>
  
 -Selects sensors to collect or to ignore, depending on B<IgnoreSelected>, see
 -below. Sensors are specified without the family byte at the beginning, to you'd
 -use C<F10FCA000800>, and B<not> include the leading C<10.> family byte and
 -point.
 +In the standard mode selects sensors to collect or to ignore
 +(depending on B<IgnoreSelected>, see below). Sensors are specified without
 +the family byte at the beginning, so you have to use for example C<F10FCA000800>,
 +and B<not> include the leading C<10.> family byte and point.
 +When no B<Sensor> is configured the whole Onewire bus is walked and all supported
 +sensors (see above) are read.
 +
 +In the advanced mode the B<Sensor> specifies full OWFS path - e.g.
 +C</uncached/10.F10FCA000800/temperature> (or when cached values are OK
 +C</10.F10FCA000800/temperature>). B<IgnoreSelected> is not used.
 +
 +As there can be multiple devices on the bus you can list multiple sensor (use
 +multiple B<Sensor> elements).
  
  =item B<IgnoreSelected> I<true>|I<false>
  
 -If no configuration if given, the B<onewire> plugin will collect data from all
 +If no configuration is given, the B<onewire> plugin will collect data from all
  sensors found. This may not be practical, especially if sensors are added and
  removed regularly. Sometimes, however, it's easier/preferred to collect only
  specific sensors or all sensors I<except> a few specified ones. This option
@@@ -4227,8 -3869,6 +4233,8 @@@ enables you to do that: By setting B<Ig
  B<Sensor> is inverted: All selected interfaces are ignored and all other
  interfaces are collected.
  
 +Used only in the standard mode - see above.
 +
  =item B<Interval> I<Seconds>
  
  Sets the interval in which all sensors should be read. If not specified, the
@@@ -4905,6 -4545,13 +4911,6 @@@ Specify the password to be used when co
  Specify whether to use an SSL connection when contacting the server. The
  following modes are supported:
  
 -=item B<Instance> I<name>
 -
 -Specify the plugin instance name that should be used instead of the database
 -name (which is the default, if this option has not been specified). This
 -allows to query multiple databases of the same name on the same host (e.g.
 -when running multiple database server versions in parallel).
 -
  =over 4
  
  =item I<disable>
@@@ -4925,13 -4572,6 +4931,13 @@@ Use SSL only
  
  =back
  
 +=item B<Instance> I<name>
 +
 +Specify the plugin instance name that should be used instead of the database
 +name (which is the default, if this option has not been specified). This
 +allows to query multiple databases of the same name on the same host (e.g.
 +when running multiple database server versions in parallel).
 +
  =item B<KRBSrvName> I<kerberos_service_name>
  
  Specify the Kerberos service name to use when authenticating with Kerberos 5
@@@ -5718,19 -5358,6 +5724,19 @@@ This option is only available if the I<
  When enabled, the I<swap I/O> is reported in bytes. When disabled, the default,
  I<swap I/O> is reported in pages. This option is available under Linux only.
  
 +=item B<ValuesAbsolute> B<true>|B<false>
 +
 +Enables or disables reporting of absolute swap metrics, i.e. number of I<bytes>
 +available and used. Defaults to B<true>.
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +Enables or disables reporting of relative swap metrics, i.e. I<percent>
 +available and free. Defaults to B<false>.
 +
 +This is useful for deploying I<collectd> in a heterogeneous environment, where
 +swap sizes differ and you want to specify generic thresholds or similar.
 +
  =back
  
  =head2 Plugin C<syslog>
@@@ -5866,7 -5493,6 +5872,7 @@@ user using (extended) regular expressio
    <Plugin "tail">
      <File "/var/log/exim4/mainlog">
        Instance "exim"
 +      Interval 60
        <Match>
          Regex "S=([1-9][0-9]*)"
          DSType "CounterAdd"
@@@ -5893,9 -5519,6 +5899,9 @@@ This plugin instance is for all B<Match
  next B<Instance> option. This way you can extract several plugin instances from
  one logfile, handy when parsing syslog and the like.
  
 +The B<Interval> option allows you to define the length of time between reads. If
 +this is not set, the default Interval will be used.
 +
  Each B<Match> block has the following options to describe how the match should
  be performed:
  
@@@ -6551,59 -6174,6 +6557,59 @@@ more than one DS
  
  =back
  
 +=head2 Plugin C<write_tsdb>
 +
 +The C<write_tsdb> plugin writes data to I<OpenTSDB>, a scalable open-source
 +time series database. The plugin connects to a I<TSD>, a masterless, no shared
 +state daemon that ingests metrics and stores them in HBase. The plugin uses
 +I<TCP> over the "line based" protocol with a default port 4242. The data will
 +be sent in blocks of at most 1428 bytes to minimize the number of network
 +packets.
 +
 +Synopsis:
 +
 + <Plugin write_tsdb>
 +   <Node "example">
 +     Host "tsd-1.my.domain"
 +     Port "4242"
 +     HostTags "status=production"
 +   </Node>
 + </Plugin>
 +
 +The configuration consists of one or more E<lt>B<Node>E<nbsp>I<Name>E<gt>
 +blocks. Inside the B<Node> blocks, the following options are recognized:
 +
 +=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<4242>.
 +
 +
 +=item B<HostTags> I<String>
 +
 +When set, I<HostTags> is added to the end of the metric. It is intended to be
 +used for name=value pairs that the TSD will tag the metric with. Dots and
 +whitespace are I<not> escaped in this string.
 +
 +=item B<StoreRates> B<false>|B<true>
 +
 +If set to B<true>, convert counter values to rates. If set to B<false>
 +(the default) counter values are stored as is, as an increasing
 +integer number.
 +
 +=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
@@@ -6659,9 -6229,8 +6665,9 @@@ want to use authentication all three fi
  
  =head2 Plugin C<write_http>
  
 -This output plugin submits values to an http server by POST them using the
 -PUTVAL plain-text protocol. Each destination you want to post data to needs to
 +This output plugin submits values to an HTTP server using POST requests and
 +encoding metrics with JSON or using the C<PUTVAL> command described in
 +L<collectd-unixsock(5)>. Each destination you want to post data to needs to
  have one B<URL> block, within which the destination can be configured further,
  for example by specifying authentication data.
  
@@@ -6671,7 -6240,6 +6677,7 @@@ Synopsis
     <URL "http://example.com/post-collectd">
       User "collectd"
       Password "weCh3ik0"
 +     Format JSON
     </URL>
   </Plugin>
  
@@@ -6707,33 -6275,6 +6713,33 @@@ File that holds one or more SSL certifi
  possibly need this option. What CA certificates come bundled with C<libcurl>
  and are checked by default depends on the distribution you use.
  
 +=item B<CAPath> I<Directory>
 +
 +Directory holding one or more CA certificate files. You can use this if for
 +some reason all the needed CA certificates aren't in the same file and can't be
 +pointed to using the B<CACert> option. Requires C<libcurl> to be built against
 +OpenSSL.
 +
 +=item B<ClientKey> I<File>
 +
 +File that holds the private key in PEM format to be used for certificate-based
 +authentication.
 +
 +=item B<ClientCert> I<File>
 +
 +File that holds the SSL certificate to be used for certificate-based
 +authentication.
 +
 +=item B<ClientKeyPass> I<Password>
 +
 +Password required to load the private key in B<ClientKey>.
 +
 +=item B<SSLVersion> B<SSLv2>|B<SSLv3>|B<TLSv1>|B<TLSv1_0>|B<TLSv1_1>|B<TLSv1_2>
 +
 +Define which SSL protocol version must be used. By default C<libcurl> will
 +attempt to figure out the remote SSL protocol version. See
 +L<curl_easy_setopt(3)> for more details.
 +
  =item B<Format> B<Command>|B<JSON>
  
  Format of the output to generate. If set to B<Command>, will create output that
@@@ -6745,129 -6286,14 +6751,129 @@@ Defaults to B<Command>
  =item B<StoreRates> B<true|false>
  
  If set to B<true>, convert counter values to rates. If set to B<false> (the
 -default) counter values are stored as is, i.E<nbsp>e. as an increasing integer
 -number.
 +default) counter values are stored as is, i.e. as an increasing integer number.
 +
 +=item B<BufferSize> I<Bytes>
 +
 +Sets the send buffer size to I<Bytes>. By increasing this buffer, less HTTP
 +requests will be generated, but more metrics will be batched / metrics are
 +cached for longer before being sent, introducing additional delay until they
 +are available on the server side. I<Bytes> must be at least 1024 and cannot
 +exceed the size of an C<int>, i.e. 2E<nbsp>GByte.
 +Defaults to C<4096>.
 +
 +=back
 +
 +=head2 Plugin C<write_kafka>
 +
 +The I<write_kafka plugin> will send values to a I<Kafka> topic, a distributed
 +queue.
 +Synopsis:
 +
 + <Plugin "write_kafka">
 +   Property "metadata.broker.list" "broker1:9092,broker2:9092"
 +   <Topic "collectd">
 +     Format JSON
 +   </Topic>
 + </Plugin>
 +
 +The following options are understood by the I<write_kafka plugin>:
 +
 +=over 4
 +
 +=item E<lt>B<Topic> I<Name>E<gt>
 +
 +The plugin's configuration consists of one or more B<Topic> blocks. Each block
 +is given a unique I<Name> and specifies one kafka producer.
 +Inside the B<Topic> block, the following per-topic options are
 +understood:
 +
 +=over 4
 +
 +=item B<Property> I<String> I<String>
 +
 +Configure the named property for the current topic. Properties are
 +forwarded to the kafka producer library B<librdkafka>.
 +
 +=item B<Key> I<String>
 +
 +Use the specified string as a partioning key for the topic. Kafka breaks
 +topic into partitions and guarantees that for a given topology, the same
 +consumer will be used for a specific key. The special (case insensitive)
 +string B<Random> can be used to specify that an arbitrary partition should
 +be used.
 +
 +=item B<Format> B<Command>|B<JSON>|B<Graphite>
 +
 +Selects the format in which messages are sent to the broker. If set to
 +B<Command> (the default), values are sent as C<PUTVAL> commands which are
 +identical to the syntax used by the I<Exec> and I<UnixSock plugins>.
 +
 +If set to B<JSON>, the values are encoded in the I<JavaScript Object Notation>,
 +an easy and straight forward exchange format.
 +
 +If set to B<Graphite>, values are encoded in the I<Graphite> format, which is
 +C<E<lt>metricE<gt> E<lt>valueE<gt> E<lt>timestampE<gt>\n>.
 +
 +=item B<StoreRates> B<true>|B<false>
 +
 +Determines whether or not C<COUNTER>, C<DERIVE> and C<ABSOLUTE> data sources
 +are converted to a I<rate> (i.e. a C<GAUGE> value). If set to B<false> (the
 +default), no conversion is performed. Otherwise the conversion is performed
 +using the internal value cache.
 +
 +Please note that currently this option is only used if the B<Format> option has
 +been set to B<JSON>.
 +
 +=item B<GraphitePrefix> (B<Format>=I<Graphite> only)
 +
 +A prefix can be added in the metric name when outputting in the I<Graphite>
 +format. It's added before the I<Host> name.
 +Metric name will be
 +C<E<lt>prefixE<gt>E<lt>hostE<gt>E<lt>postfixE<gt>E<lt>pluginE<gt>E<lt>typeE<gt>E<lt>nameE<gt>>
 +
 +=item B<GraphitePostfix> (B<Format>=I<Graphite> only)
 +
 +A postfix can be added in the metric name when outputting in the I<Graphite>
 +format. It's added after the I<Host> name.
 +Metric name will be
 +C<E<lt>prefixE<gt>E<lt>hostE<gt>E<lt>postfixE<gt>E<lt>pluginE<gt>E<lt>typeE<gt>E<lt>nameE<gt>>
 +
 +=item B<GraphiteEscapeChar> (B<Format>=I<Graphite> only)
 +
 +Specify a character to replace dots (.) in the host part of the metric name.
 +In I<Graphite> metric name, dots are used as separators between different
 +metric parts (host, plugin, type).
 +Default is C<_> (I<Underscore>).
 +
 +=item B<GraphiteSeparateInstances> 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 one component, for example C<host.cpu-0.cpu-idle>.
 +
 +=item B<StoreRates> B<true>|B<false>
 +
 +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.
 +
 +This will be reflected in the C<ds_type> tag: If B<StoreRates> is enabled,
 +converted values will have "rate" appended to the data source type, e.g.
 +C<ds_type:derive:rate>.
 +
 +=back
 +
 +=item B<Property> I<String> I<String>
 +
 +Configure the kafka producer through properties, you almost always will
 +want to set B<metadata.broker.list> to your Kafka broker list.
  
  =back
  
  =head2 Plugin C<write_riemann>
  
 -The I<write_riemann plugin> will send values to I<Riemann>, a powerfull stream
 +The I<write_riemann plugin> will send values to I<Riemann>, a powerful stream
  aggregation and monitoring system. The plugin sends I<Protobuf> encoded data to
  I<Riemann> using UDP packets.
  
@@@ -6883,7 -6309,6 +6889,7 @@@ Synopsis
       TTLFactor 2.0
     </Node>
     Tag "foobar"
 +   Attribute "foo" "bar"
   </Plugin>
  
  The following options are understood by the I<write_riemann plugin>:
@@@ -6937,23 -6362,6 +6943,23 @@@ interval is multiplied to set the TTL. 
  know exactly what you're doing, you should only increase this setting from its
  default value.
  
 +=item B<Notifications> B<false>|B<true>
 +
 +If set to B<true>, create riemann events for notifications. This is B<true>
 +by default. When processing thresholds from write_riemann, it might prove
 +useful to avoid getting notification events.
 +
 +=item B<CheckThresholds> B<false>|B<true>
 +
 +If set to B<true>, attach state to events based on thresholds defined
 +in the B<Threshold> plugin. Defaults to B<false>.
 +
 +=item B<EventServicePrefix> I<String>
 +
 +Add the given string as a prefix to the event service name.
 +If B<EventServicePrefix> not set or set to an empty string (""),
 +no prefix will be used.
 +
  =back
  
  =item B<Tag> I<String>
  Add the given string as an additional tag to the metric being sent to
  I<Riemann>.
  
 +=item B<Attribute> I<String> I<String>
 +
 +Consider the two given strings to be the key and value of an additional
 +attribute for each metric being sent out to I<Riemann>.
 +
  =back
  
  =head1 THRESHOLD CONFIGURATION
@@@ -7637,7 -7040,7 +7643,7 @@@ Example
     Max 100
     Satisfy "All"
   </Match>
 - 
 +
   # Match if the value of any data source is outside the range of 0 - 100.
   <Match "value">
     Min   0
@@@ -7819,7 -7222,7 +7825,7 @@@ Example
   <Target "replace">
     # Replace "example.net" with "example.com"
     Host "\\<example.net\\>" "example.com"
 - 
 +
     # Strip "www." from hostnames
     Host "\\<www\\." ""
   </Target>
@@@ -7902,6 -7305,6 +7908,6 @@@ L<sensors(1)
  
  =head1 AUTHOR
  
 -Florian Forster E<lt>octo@verplant.orgE<gt>
 +Florian Forster E<lt>octo@collectd.orgE<gt>
  
  =cut
diff --combined src/curl.c
@@@ -17,7 -17,7 +17,7 @@@
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   *   Aman Gupta <aman at tmm1.net>
   **/
  
@@@ -58,7 -58,6 +58,7 @@@ struct web_page_s /* {{{ *
    char *user;
    char *pass;
    char *credentials;
 +  _Bool digest;
    _Bool verify_peer;
    _Bool verify_host;
    char *cacert;
@@@ -365,7 -364,8 +365,7 @@@ static int cc_page_init_curl (web_page_
    curl_easy_setopt (wp->curl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt (wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback);
    curl_easy_setopt (wp->curl, CURLOPT_WRITEDATA, wp);
 -  curl_easy_setopt (wp->curl, CURLOPT_USERAGENT,
 -      PACKAGE_NAME"/"PACKAGE_VERSION);
 +  curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
    curl_easy_setopt (wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf);
    curl_easy_setopt (wp->curl, CURLOPT_URL, wp->url);
    curl_easy_setopt (wp->curl, CURLOPT_FOLLOWLOCATION, 1L);
  
    if (wp->user != NULL)
    {
 +#ifdef HAVE_CURLOPT_USERNAME
 +    curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user);
 +    curl_easy_setopt (wp->curl, CURLOPT_PASSWORD,
 +        (wp->pass == NULL) ? "" : wp->pass);
 +#else
      size_t credentials_size;
  
      credentials_size = strlen (wp->user) + 2;
      ssnprintf (wp->credentials, credentials_size, "%s:%s",
          wp->user, (wp->pass == NULL) ? "" : wp->pass);
      curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials);
 +#endif
 +
 +    if (wp->digest)
 +      curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
    }
  
    curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer);
@@@ -435,7 -426,6 +435,7 @@@ static int cc_config_add_page (oconfig_
    page->url = NULL;
    page->user = NULL;
    page->pass = NULL;
 +  page->digest = 0;
    page->verify_peer = 1;
    page->verify_host = 1;
    page->response_time = 0;
        status = cf_util_get_string (child, &page->user);
      else if (strcasecmp ("Password", child->key) == 0)
        status = cf_util_get_string (child, &page->pass);
 +    else if (strcasecmp ("Digest", child->key) == 0)
 +      status = cf_util_get_boolean (child, &page->digest);
      else if (strcasecmp ("VerifyPeer", child->key) == 0)
        status = cf_util_get_boolean (child, &page->verify_peer);
      else if (strcasecmp ("VerifyHost", child->key) == 0)
@@@ -692,6 -680,7 +692,7 @@@ static int cc_read_page (web_page_t *wp
      }
  
      cc_submit (wp, wm, mv);
+     match_value_reset (mv);
    } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
  
    return (0);
diff --combined src/java.c
@@@ -17,7 -17,7 +17,7 @@@
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   *   Justo Alonso Achaques <justo.alonso at gmail.com>
   **/
  
@@@ -120,7 -120,7 +120,7 @@@ static int cjni_match_target_destroy (v
  static int cjni_match_target_invoke (const data_set_t *ds, value_list_t *vl,
      notification_meta_t **meta, void **user_data);
  
 -/* 
 +/*
   * C to Java conversion functions
   */
  static int ctoj_string (JNIEnv *jvm_env, /* {{{ */
    return (0);
  } /* }}} int ctoj_string */
  
 +static jstring ctoj_output_string (JNIEnv *jvm_env, /* {{{ */
 +    const char *string)
 +{
 +  jstring o_string;
 +
 +  /* Create a java.lang.String */
 +  o_string = (*jvm_env)->NewStringUTF (jvm_env,
 +      (string != NULL) ? string : "");
 +  if (o_string == NULL)
 +  {
 +    ERROR ("java plugin: ctoj_output_string: NewStringUTF failed.");
 +    return NULL;
 +  }
 +
 +  return (o_string);
 +} /* }}} int ctoj_output_string */
 +
  static int ctoj_int (JNIEnv *jvm_env, /* {{{ */
      jint value,
      jclass class_ptr, jobject object_ptr, const char *method_name)
@@@ -1336,7 -1319,7 +1336,7 @@@ static int jtoc_notification (JNIEnv *j
  
    return (0);
  } /* }}} int jtoc_notification */
 -/* 
 +/*
   * Functions accessible from Java
   */
  static jint JNICALL cjni_api_dispatch_values (JNIEnv *jvm_env, /* {{{ */
@@@ -1646,11 -1629,6 +1646,11 @@@ static void JNICALL cjni_api_log (JNIEn
    (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_message, c_str);
  } /* }}} void cjni_api_log */
  
 +static jstring JNICALL cjni_api_get_hostname (JNIEnv *jvm_env, jobject this)
 +{
 +    return ctoj_output_string(jvm_env, hostname_g);
 +}
 +
  /* List of ``native'' functions, i. e. C-functions that can be called from
   * Java. */
  static JNINativeMethod jni_api_functions[] = /* {{{ */
    { "log",
      "(ILjava/lang/String;)V",
      cjni_api_log },
 +
 +  { "getHostname",
 +    "()Ljava/lang/String;",
 +    cjni_api_get_hostname },
 +
  };
  static size_t jni_api_functions_num = sizeof (jni_api_functions)
    / sizeof (jni_api_functions[0]);
@@@ -2142,7 -2115,7 +2142,7 @@@ static int cjni_thread_detach (void) /
    cjni_env->jvm_env = NULL;
  
    return (0);
- } /* }}} JNIEnv *cjni_thread_attach */
+ } /* }}} int cjni_thread_detach */
  
  static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */
  {
@@@ -2463,7 -2436,7 +2463,7 @@@ static void cjni_callback_info_destroy 
  
    cbi = (cjni_callback_info_t *) arg;
  
 -  /* This condition can occurr when shutting down. */
 +  /* This condition can occur when shutting down. */
    if (jvm == NULL)
    {
      sfree (cbi);
@@@ -2495,7 -2468,6 +2495,6 @@@ static int cjni_read (user_data_t *ud) 
  {
    JNIEnv *jvm_env;
    cjni_callback_info_t *cbi;
-   int status;
    int ret_status;
  
    if (jvm == NULL)
    ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object,
        cbi->method);
  
-   status = cjni_thread_detach ();
-   if (status != 0)
-   {
-     ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
-     return (-1);
-   }
+   cjni_thread_detach ();
    return (ret_status);
  } /* }}} int cjni_read */
  
@@@ -2536,7 -2502,6 +2529,6 @@@ static int cjni_write (const data_set_
    JNIEnv *jvm_env;
    cjni_callback_info_t *cbi;
    jobject vl_java;
-   int status;
    int ret_status;
  
    if (jvm == NULL)
    if (vl_java == NULL)
    {
      ERROR ("java plugin: cjni_write: ctoj_value_list failed.");
+     cjni_thread_detach ();
      return (-1);
    }
  
  
    (*jvm_env)->DeleteLocalRef (jvm_env, vl_java);
  
-   status = cjni_thread_detach ();
-   if (status != 0)
-   {
-     ERROR ("java plugin: cjni_write: cjni_thread_detach failed.");
-     return (-1);
-   }
+   cjni_thread_detach ();
    return (ret_status);
  } /* }}} int cjni_write */
  
@@@ -2587,7 -2547,6 +2574,6 @@@ static int cjni_flush (cdtime_t timeout
    cjni_callback_info_t *cbi;
    jobject o_timeout;
    jobject o_identifier;
-   int status;
    int ret_status;
  
    if (jvm == NULL)
    {
      ERROR ("java plugin: cjni_flush: Converting double "
          "to Number object failed.");
+     cjni_thread_detach ();
      return (-1);
    }
  
      {
        (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
        ERROR ("java plugin: cjni_flush: NewStringUTF failed.");
+       cjni_thread_detach ();
        return (-1);
      }
    }
    (*jvm_env)->DeleteLocalRef (jvm_env, o_identifier);
    (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
  
-   status = cjni_thread_detach ();
-   if (status != 0)
-   {
-     ERROR ("java plugin: cjni_flush: cjni_thread_detach failed.");
-     return (-1);
-   }
+   cjni_thread_detach ();
    return (ret_status);
  } /* }}} int cjni_flush */
  
@@@ -2667,7 -2622,10 +2649,10 @@@ static void cjni_log (int severity, con
  
    o_message = (*jvm_env)->NewStringUTF (jvm_env, message);
    if (o_message == NULL)
+   {
+     cjni_thread_detach ();
      return;
+   }
  
    (*jvm_env)->CallVoidMethod (jvm_env,
        cbi->object, cbi->method, (jint) severity, o_message);
@@@ -2685,7 -2643,6 +2670,6 @@@ static int cjni_notification (const not
    JNIEnv *jvm_env;
    cjni_callback_info_t *cbi;
    jobject o_notification;
-   int status;
    int ret_status;
  
    if (jvm == NULL)
    if (o_notification == NULL)
    {
      ERROR ("java plugin: cjni_notification: ctoj_notification failed.");
+     cjni_thread_detach ();
      return (-1);
    }
  
  
    (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
  
-   status = cjni_thread_detach ();
-   if (status != 0)
-   {
-     ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
-     return (-1);
-   }
+   cjni_thread_detach ();
    return (ret_status);
  } /* }}} int cjni_notification */
  
@@@ -2752,24 -2704,20 +2731,20 @@@ static int cjni_match_target_create (co
        (*jvm_env)->DeleteLocalRef (jvm_env, cbi_ret->object); \
    } \
    free (cbi_ret); \
-   if (jvm_env != NULL) { \
-     if (o_ci != NULL) \
-       (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
-     cjni_thread_detach (); \
-   } \
+   if (o_ci != NULL) \
+     (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
+   cjni_thread_detach (); \
    return (status)
  
    if (jvm == NULL)
    {
      ERROR ("java plugin: cjni_read: jvm == NULL");
-     BAIL_OUT (-1);
+     return (-1);
    }
  
    jvm_env = cjni_thread_attach ();
    if (jvm_env == NULL)
-   {
-     BAIL_OUT (-1);
-   }
+     return (-1);
  
    /* Find out whether to create a match or a target. */
    if (strcasecmp ("Match", ci->key) == 0)
@@@ -2963,10 -2911,7 +2938,7 @@@ static int cjni_match_target_invoke (co
      }
    } /* if (cbi->type == CB_TYPE_TARGET) */
  
-   status = cjni_thread_detach ();
-   if (status != 0)
-     ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
+   cjni_thread_detach ();
    return (ret_status);
  } /* }}} int cjni_match_target_invoke */
  
diff --combined src/memcachec.c
@@@ -18,7 -18,7 +18,7 @@@
   *
   * Authors:
   *   Doug MacEachern <Doug.MacEachern at hyperic.com>
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -500,6 -500,7 +500,7 @@@ static int cmc_read_page (web_page_t *w
      }
  
      cmc_submit (wp, wm, mv);
+     match_value_reset (mv);
    } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
  
    sfree (wp->buffer);
diff --combined src/meta_data.c
@@@ -2,26 -2,21 +2,26 @@@
   * collectd - src/meta_data.c
   * Copyright (C) 2008-2011  Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; only version 2 of the License is applicable.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -318,7 -313,13 +318,13 @@@ int meta_data_toc (meta_data_t *md, cha
    for (e = md->head; e != NULL; e = e->next)
      ++count;    
  
-   *toc = malloc(count * sizeof(**toc));
+   if (count == 0)
+   {
+     pthread_mutex_unlock (&md->lock);
+     return (count);
+   }
+   *toc = calloc(count, sizeof(**toc));
    for (e = md->head; e != NULL; e = e->next)
      (*toc)[i++] = strdup(e->key);
    
diff --combined src/network.c
@@@ -395,7 -395,7 +395,7 @@@ static _Bool check_send_notify_okay (co
    {
      c_complain_once (LOG_ERR, &complain_forwarding,
          "network plugin: A notification has been received via the network "
-         "forwarding if enabled. Forwarding of notifications is currently "
+         "and forwarding is enabled. Forwarding of notifications is currently "
          "not supported, because there is not loop-deteciton available. "
          "Please contact the collectd mailing list if you need this "
          "feature.");
@@@ -917,19 -917,15 +917,19 @@@ static int parse_part_number (void **re
  } /* int parse_part_number */
  
  static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len,
 -              char *output, int output_len)
 +              char *output, size_t const output_len)
  {
        char *buffer = *ret_buffer;
        size_t buffer_len = *ret_buffer_len;
  
        uint16_t tmp16;
 -      size_t header_size = 2 * sizeof (uint16_t);
 +      size_t const header_size = 2 * sizeof (uint16_t);
  
        uint16_t pkg_length;
 +      size_t payload_size;
 +
 +      if (output_len <= 0)
 +              return (EINVAL);
  
        if (buffer_len < header_size)
        {
        memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
        buffer += sizeof (tmp16);
        pkg_length = ntohs (tmp16);
 +      payload_size = ((size_t) pkg_length) - header_size;
  
        /* Check that packet fits in the input buffer */
        if (pkg_length > buffer_len)
        /* Check that the package data fits into the output buffer.
         * The previous if-statement ensures that:
         * `pkg_length > header_size' */
 -      if ((output_len < 0)
 -                      || ((size_t) output_len < ((size_t) pkg_length - header_size)))
 +      if (output_len < payload_size)
        {
                WARNING ("network plugin: parse_part_string: "
 -                              "Output buffer too small.");
 +                              "Buffer too small: "
 +                              "Output buffer holds %zu bytes, "
 +                              "which is too small to hold the received "
 +                              "%zu byte string.",
 +                              output_len, payload_size);
                return (-1);
        }
  
        /* All sanity checks successfull, let's copy the data over */
 -      output_len = pkg_length - header_size;
 -      memcpy ((void *) output, (void *) buffer, output_len);
 -      buffer += output_len;
 +      memcpy ((void *) output, (void *) buffer, payload_size);
 +      buffer += payload_size;
  
        /* For some very weird reason '\0' doesn't do the trick on SPARC in
         * this statement. */
 -      if (output[output_len - 1] != 0)
 +      if (output[payload_size - 1] != 0)
        {
                WARNING ("network plugin: parse_part_string: "
                                "Received string does not end "
@@@ -1999,14 -1992,19 +1999,19 @@@ static int network_bind_socket (int fd
  
  /* Initialize a sockent structure. `type' must be either `SOCKENT_TYPE_CLIENT'
   * or `SOCKENT_TYPE_SERVER' */
- static int sockent_init (sockent_t *se, int type) /* {{{ */
+ static sockent_t *sockent_create (int type) /* {{{ */
  {
-       if (se == NULL)
-               return (-1);
+       sockent_t *se;
+       if ((type != SOCKENT_TYPE_CLIENT) || (type != SOCKENT_TYPE_SERVER))
+               return (NULL);
  
+       se = malloc (sizeof (*se));
+       if (se == NULL)
+               return (NULL);
        memset (se, 0, sizeof (*se));
  
-       se->type = SOCKENT_TYPE_CLIENT;
+       se->type = type;
        se->node = NULL;
        se->service = NULL;
        se->interface = 0;
  
        if (type == SOCKENT_TYPE_SERVER)
        {
-               se->type = SOCKENT_TYPE_SERVER;
                se->data.server.fd = NULL;
  #if HAVE_LIBGCRYPT
                se->data.server.security_level = SECURITY_LEVEL_NONE;
  #endif
        }
  
-       return (0);
- } /* }}} int sockent_init */
+       return (se);
+ } /* }}} sockent_t *sockent_create */
  
- /* Open the file descriptors for a initialized sockent structure. */
- static int sockent_open (sockent_t *se) /* {{{ */
+ static int sockent_init_crypto (sockent_t *se) /* {{{ */
  {
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
-       int              ai_return;
-         const char *node;
-         const char *service;
-       if (se == NULL)
-               return (-1);
-       /* Set up the security structures. */
  #if HAVE_LIBGCRYPT /* {{{ */
        if (se->type == SOCKENT_TYPE_CLIENT)
        {
        }
  #endif /* }}} HAVE_LIBGCRYPT */
  
+       return (0);
+ } /* }}} int sockent_init_crypto */
+ static int sockent_client_connect (sockent_t *se) /* {{{ */
+ {
+       static c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
+       struct sockent_client *client;
+       struct addrinfo  ai_hints;
+       struct addrinfo *ai_list = NULL, *ai_ptr;
+       int status;
+       if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT))
+               return (EINVAL);
+       client = &se->data.client;
+       if (client->fd >= 0) /* already connected */
+               return (0);
+       memset (&ai_hints, 0, sizeof (ai_hints));
+ #ifdef AI_ADDRCONFIG
+       ai_hints.ai_flags |= AI_ADDRCONFIG;
+ #endif
+       ai_hints.ai_family   = AF_UNSPEC;
+       ai_hints.ai_socktype = SOCK_DGRAM;
+       ai_hints.ai_protocol = IPPROTO_UDP;
+       status = getaddrinfo (se->node,
+                       (se->service != NULL) ? se->service : NET_DEFAULT_PORT,
+                       &ai_hints, &ai_list);
+       if (status != 0)
+       {
+               c_complain (LOG_ERR, &complaint,
+                               "network plugin: getaddrinfo (%s, %s) failed: %s",
+                               (se->node == NULL) ? "(null)" : se->node,
+                               (se->service == NULL) ? "(null)" : se->service,
+                               gai_strerror (status));
+               return (-1);
+       }
+       else
+       {
+               c_release (LOG_NOTICE, &complaint,
+                               "network plugin: Successfully resolved \"%s\".",
+                               se->node);
+       }
+       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       {
+               client->fd = socket (ai_ptr->ai_family,
+                               ai_ptr->ai_socktype,
+                               ai_ptr->ai_protocol);
+               if (client->fd < 0)
+               {
+                       char errbuf[1024];
+                       ERROR ("network plugin: socket(2) failed: %s",
+                                       sstrerror (errno, errbuf,
+                                               sizeof (errbuf)));
+                       continue;
+               }
+               client->addr = malloc (sizeof (*client->addr));
+               if (client->addr == NULL)
+               {
+                       ERROR ("network plugin: malloc failed.");
+                       close (client->fd);
+                       client->fd = -1;
+                       continue;
+               }
+               memset (client->addr, 0, sizeof (*client->addr));
+               assert (sizeof (*client->addr) >= ai_ptr->ai_addrlen);
+               memcpy (client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+               client->addrlen = ai_ptr->ai_addrlen;
+               network_set_ttl (se, ai_ptr);
+               network_set_interface (se, ai_ptr);
+               /* We don't open more than one write-socket per
+                * node/service pair.. */
+               break;
+       }
+       freeaddrinfo (ai_list);
+       if (client->fd < 0)
+               return (-1);
+       return (0);
+ } /* }}} int sockent_client_connect */
+ static int sockent_client_disconnect (sockent_t *se) /* {{{ */
+ {
+       struct sockent_client *client;
+       if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT))
+               return (EINVAL);
+       client = &se->data.client;
+       if (client->fd >= 0) /* connected */
+       {
+               close (client->fd);
+               client->fd = -1;
+       }
+       sfree (client->addr);
+       client->addrlen = 0;
+       return (0);
+ } /* }}} int sockent_client_disconnect */
+ /* Open the file descriptors for a initialized sockent structure. */
+ static int sockent_server_listen (sockent_t *se) /* {{{ */
+ {
+       struct addrinfo  ai_hints;
+       struct addrinfo *ai_list, *ai_ptr;
+       int              status;
+         const char *node;
+         const char *service;
+       if (se == NULL)
+               return (-1);
          node = se->node;
          service = se->service;
  
          if (service == NULL)
            service = NET_DEFAULT_PORT;
  
-         DEBUG ("network plugin: sockent_open: node = %s; service = %s;",
+         DEBUG ("network plugin: sockent_server_listen: node = %s; service = %s;",
              node, service);
  
        memset (&ai_hints, 0, sizeof (ai_hints));
        ai_hints.ai_socktype = SOCK_DGRAM;
        ai_hints.ai_protocol = IPPROTO_UDP;
  
-       ai_return = getaddrinfo (node, service, &ai_hints, &ai_list);
-       if (ai_return != 0)
+       status = getaddrinfo (node, service, &ai_hints, &ai_list);
+       if (status != 0)
        {
                ERROR ("network plugin: getaddrinfo (%s, %s) failed: %s",
                                (se->node == NULL) ? "(null)" : se->node,
                                (se->service == NULL) ? "(null)" : se->service,
-                               gai_strerror (ai_return));
+                               gai_strerror (status));
                return (-1);
        }
  
        for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
-               int status;
+               int *tmp;
  
-               if (se->type == SOCKENT_TYPE_SERVER) /* {{{ */
+               tmp = realloc (se->data.server.fd,
+                               sizeof (*tmp) * (se->data.server.fd_num + 1));
+               if (tmp == NULL)
                {
-                       int *tmp;
-                       tmp = realloc (se->data.server.fd,
-                                       sizeof (*tmp) * (se->data.server.fd_num + 1));
-                       if (tmp == NULL)
-                       {
-                               ERROR ("network plugin: realloc failed.");
-                               continue;
-                       }
-                       se->data.server.fd = tmp;
-                       tmp = se->data.server.fd + se->data.server.fd_num;
-                       *tmp = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
-                                       ai_ptr->ai_protocol);
-                       if (*tmp < 0)
-                       {
-                               char errbuf[1024];
-                               ERROR ("network plugin: socket(2) failed: %s",
-                                               sstrerror (errno, errbuf,
-                                                       sizeof (errbuf)));
-                               continue;
-                       }
-                       status = network_bind_socket (*tmp, ai_ptr, se->interface);
-                       if (status != 0)
-                       {
-                               close (*tmp);
-                               *tmp = -1;
-                               continue;
-                       }
-                       se->data.server.fd_num++;
+                       ERROR ("network plugin: realloc failed.");
                        continue;
-               } /* }}} if (se->type == SOCKENT_TYPE_SERVER) */
-               else /* if (se->type == SOCKENT_TYPE_CLIENT) {{{ */
-               {
-                       se->data.client.fd = socket (ai_ptr->ai_family,
-                                       ai_ptr->ai_socktype,
-                                       ai_ptr->ai_protocol);
-                       if (se->data.client.fd < 0)
-                       {
-                               char errbuf[1024];
-                               ERROR ("network plugin: socket(2) failed: %s",
-                                               sstrerror (errno, errbuf,
-                                                       sizeof (errbuf)));
-                               continue;
-                       }
-                       se->data.client.addr = malloc (sizeof (*se->data.client.addr));
-                       if (se->data.client.addr == NULL)
-                       {
-                               ERROR ("network plugin: malloc failed.");
-                               close (se->data.client.fd);
-                               se->data.client.fd = -1;
-                               continue;
-                       }
+               }
+               se->data.server.fd = tmp;
+               tmp = se->data.server.fd + se->data.server.fd_num;
  
-                       memset (se->data.client.addr, 0, sizeof (*se->data.client.addr));
-                       assert (sizeof (*se->data.client.addr) >= ai_ptr->ai_addrlen);
-                       memcpy (se->data.client.addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
-                       se->data.client.addrlen = ai_ptr->ai_addrlen;
+               *tmp = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
+                               ai_ptr->ai_protocol);
+               if (*tmp < 0)
+               {
+                       char errbuf[1024];
+                       ERROR ("network plugin: socket(2) failed: %s",
+                                       sstrerror (errno, errbuf,
+                                               sizeof (errbuf)));
+                       continue;
+               }
  
-                       network_set_ttl (se, ai_ptr);
-                       network_set_interface (se, ai_ptr);
+               status = network_bind_socket (*tmp, ai_ptr, se->interface);
+               if (status != 0)
+               {
+                       close (*tmp);
+                       *tmp = -1;
+                       continue;
+               }
  
-                       /* We don't open more than one write-socket per
-                        * node/service pair.. */
-                       break;
-               } /* }}} if (se->type == SOCKENT_TYPE_CLIENT) */
+               se->data.server.fd_num++;
+               continue;
        } /* for (ai_list) */
  
        freeaddrinfo (ai_list);
  
-       /* Check if all went well. */
-       if (se->type == SOCKENT_TYPE_SERVER)
-       {
-               if (se->data.server.fd_num <= 0)
-                       return (-1);
-       }
-       else /* if (se->type == SOCKENT_TYPE_CLIENT) */
-       {
-               if (se->data.client.fd < 0)
-                       return (-1);
-       }
+       if (se->data.server.fd_num <= 0)
+               return (-1);
        return (0);
- } /* }}} int sockent_open */
+ } /* }}} int sockent_server_listen */
  
  /* Add a sockent to the global list of sockets */
  static int sockent_add (sockent_t *se) /* {{{ */
@@@ -2493,26 -2549,32 +2556,32 @@@ static void network_init_buffer (void
        memset (&send_buffer_vl, 0, sizeof (send_buffer_vl));
  } /* int network_init_buffer */
  
- static void networt_send_buffer_plain (const sockent_t *se, /* {{{ */
+ static void networt_send_buffer_plain (sockent_t *se, /* {{{ */
                const char *buffer, size_t buffer_size)
  {
        int status;
  
        while (42)
        {
+               status = sockent_client_connect (se);
+               if (status != 0)
+                       return;
                status = sendto (se->data.client.fd, buffer, buffer_size,
-                     /* flags = */ 0,
-                     (struct sockaddr *) se->data.client.addr,
-                     se->data.client.addrlen);
-                 if (status < 0)
+                               /* flags = */ 0,
+                               (struct sockaddr *) se->data.client.addr,
+                               se->data.client.addrlen);
+               if (status < 0)
                {
                        char errbuf[1024];
-                       if (errno == EINTR)
+                       if ((errno == EINTR) || (errno == EAGAIN))
                                continue;
-                       ERROR ("network plugin: sendto failed: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       break;
+                       ERROR ("network plugin: sendto failed: %s. Closing sending socket.",
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       sockent_client_disconnect (se);
+                       return;
                }
  
                break;
    buffer_offset += (s); \
  } while (0)
  
- static void networt_send_buffer_signed (const sockent_t *se, /* {{{ */
+ static void networt_send_buffer_signed (sockent_t *se, /* {{{ */
                const char *in_buffer, size_t in_buffer_size)
  {
    part_signature_sha256_t ps;
@@@ -2911,10 -2973,6 +2980,10 @@@ static int network_config_set_ttl (cons
    tmp = (int) ci->values[0].value.number;
    if ((tmp > 0) && (tmp <= 255))
      network_config_ttl = tmp;
 +  else {
 +    WARNING ("network plugin: The `TimeToLive' must be between 1 and 255.");
 +    return (-1);    
 +  }
  
    return (0);
  } /* }}} int network_config_set_ttl */
@@@ -3025,13 -3083,12 +3094,12 @@@ static int network_config_add_listen (c
      return (-1);
    }
  
-   se = malloc (sizeof (*se));
+   se = sockent_create (SOCKENT_TYPE_SERVER);
    if (se == NULL)
    {
-     ERROR ("network plugin: malloc failed.");
+     ERROR ("network plugin: sockent_create failed.");
      return (-1);
    }
-   sockent_init (se, SOCKENT_TYPE_SERVER);
  
    se->node = strdup (ci->values[0].value.string);
    if (ci->values_num >= 2)
    }
  #endif /* HAVE_LIBGCRYPT */
  
-   status = sockent_open (se);
+   status = sockent_init_crypto (se);
    if (status != 0)
    {
-     ERROR ("network plugin: network_config_add_listen: sockent_open failed.");
+     ERROR ("network plugin: network_config_add_listen: sockent_init_crypto() failed.");
+     sockent_destroy (se);
+     return (-1);
+   }
+   status = sockent_server_listen (se);
+   if (status != 0)
+   {
+     ERROR ("network plugin: network_config_add_server: sockent_server_listen failed.");
      sockent_destroy (se);
      return (-1);
    }
@@@ -3105,13 -3170,12 +3181,12 @@@ static int network_config_add_server (c
      return (-1);
    }
  
-   se = malloc (sizeof (*se));
+   se = sockent_create (SOCKENT_TYPE_CLIENT);
    if (se == NULL)
    {
-     ERROR ("network plugin: malloc failed.");
+     ERROR ("network plugin: sockent_create failed.");
      return (-1);
    }
-   sockent_init (se, SOCKENT_TYPE_CLIENT);
  
    se->node = strdup (ci->values[0].value.string);
    if (ci->values_num >= 2)
    }
  #endif /* HAVE_LIBGCRYPT */
  
-   status = sockent_open (se);
+   status = sockent_init_crypto (se);
    if (status != 0)
    {
-     ERROR ("network plugin: network_config_add_server: sockent_open failed.");
+     ERROR ("network plugin: network_config_add_server: sockent_init_crypto() failed.");
      sockent_destroy (se);
      return (-1);
    }
  
+   /* No call to sockent_client_connect() here -- it is called from
+    * networt_send_buffer_plain(). */
    status = sockent_add (se);
    if (status != 0)
    {
@@@ -3177,14 -3244,6 +3255,14 @@@ static int network_config (oconfig_item
  {
    int i;
  
 +  /* The options need to be applied first */
 +  for (i = 0; i < ci->children_num; i++)
 +  {
 +    oconfig_item_t *child = ci->children + i;
 +    if (strcasecmp ("TimeToLive", child->key) == 0)
 +      network_config_set_ttl (child);
 +  }
 +
    for (i = 0; i < ci->children_num; i++)
    {
      oconfig_item_t *child = ci->children + i;
        network_config_add_listen (child);
      else if (strcasecmp ("Server", child->key) == 0)
        network_config_add_server (child);
 -    else if (strcasecmp ("TimeToLive", child->key) == 0)
 -      network_config_set_ttl (child);
 +    else if (strcasecmp ("TimeToLive", child->key) == 0) {
 +      /* Handled earlier */
 +    }
      else if (strcasecmp ("MaxPacketSize", child->key) == 0)
        network_config_set_buffer_size (child);
      else if (strcasecmp ("Forward", child->key) == 0)
@@@ -3288,6 -3346,8 +3366,8 @@@ static int network_notification (const 
  
  static int network_shutdown (void)
  {
+       sockent_t *se;
        listen_loop++;
  
        /* Kill the listening thread */
  
        sfree (send_buffer);
  
-       /* TODO: Close `sending_sockets' */
+       for (se = sending_sockets; se != NULL; se = se->next)
+               sockent_client_disconnect (se);
+       sockent_destroy (sending_sockets);
  
        plugin_unregister_config ("network");
        plugin_unregister_init ("network");
diff --combined src/utils_format_json.c
@@@ -1,27 -1,22 +1,27 @@@
  /**
   * collectd - src/utils_format_json.c
 - * Copyright (C) 2009  Florian octo Forster
 + * Copyright (C) 2009       Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; only version 2 of the License is applicable.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -239,7 -234,10 +239,10 @@@ static int meta_data_to_json (char *buf
    int status;
    int i;
  
-   memset (buffer, 0, buffer_size);
+   buffer[0] = 0;
+   if (meta == NULL)
+     return (EINVAL);
  
  #define BUFFER_ADD(...) do { \
    status = ssnprintf (buffer + offset, buffer_size - offset, \
  } while (0)
  
    keys_num = meta_data_toc (meta, &keys);
+   if (keys_num == 0)
+   {
+     sfree (keys);
+     return (0);
+   }
    for (i = 0; i < keys_num; ++i)
    {
      int type;
  #undef BUFFER_ADD
  
    return (0);
- } /* int meta_data_to_json */
+ } /* }}} int meta_data_to_json */
  
  static int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */
                  const data_set_t *ds, const value_list_t *vl, int store_rates)
diff --combined src/utils_match.c
@@@ -1,27 -1,23 +1,27 @@@
  /**
   * collectd - src/utils_match.c
-  * Copyright (C) 2008       Florian octo Forster
+  * Copyright (C) 2008-2014  Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; either version 2 of the License, or (at your
 - * option) any later version.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -84,13 -80,6 +84,13 @@@ static int default_callback (const cha
      gauge_t value;
      char *endptr = NULL;
  
 +    if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC)
 +    {
 +      data->value.gauge = isnan (data->value.gauge) ? 1 : data->value.gauge + 1;
 +      data->values_num++;
 +      return(0);
 +    }
 +
      if (matches_num < 2)
        return (-1);
  
      {
        if (data->value.gauge < value)
        data->value.gauge = value;
 +    }
 +    else if (data->ds_type & UTILS_MATCH_CF_GAUGE_ADD)
 +    {
 +      data->value.gauge += value;
      }
      else
      {
@@@ -294,6 -279,18 +294,18 @@@ cu_match_t *match_create_simple (const 
    return (obj);
  } /* cu_match_t *match_create_simple */
  
+ void match_value_reset (cu_match_value_t *mv)
+ {
+   if (mv == NULL)
+     return;
+   if (mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE)
+   {
+     mv->value.gauge = NAN;
+     mv->values_num = 0;
+   }
+ } /* }}} void match_value_reset */
  void match_destroy (cu_match_t *obj)
  {
    if (obj == NULL)
diff --combined src/utils_match.h
@@@ -1,27 -1,23 +1,27 @@@
  /**
   * collectd - src/utils_match.h
-  * Copyright (C) 2008       Florian octo Forster
+  * Copyright (C) 2008-2014  Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; either version 2 of the License, or (at your
 - * option) any later version.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #ifndef UTILS_MATCH_H
  #include "plugin.h"
  
  /*
 - * Defines
 + * Each type may have 12 sub-types
 + * 0x1000 = 1000000000000
 + *          ^             <- Type bit
 + *           ^^^^^^^^^^^^ <- Subtype bits
   */
 -#define UTILS_MATCH_DS_TYPE_GAUGE    0x10
 -#define UTILS_MATCH_DS_TYPE_COUNTER  0x20
 -#define UTILS_MATCH_DS_TYPE_DERIVE   0x40
 -#define UTILS_MATCH_DS_TYPE_ABSOLUTE 0x80
 +#define UTILS_MATCH_DS_TYPE_GAUGE    0x1000
 +#define UTILS_MATCH_DS_TYPE_COUNTER  0x2000
 +#define UTILS_MATCH_DS_TYPE_DERIVE   0x4000
 +#define UTILS_MATCH_DS_TYPE_ABSOLUTE 0x8000
  
  #define UTILS_MATCH_CF_GAUGE_AVERAGE 0x01
  #define UTILS_MATCH_CF_GAUGE_MIN     0x02
  #define UTILS_MATCH_CF_GAUGE_MAX     0x04
  #define UTILS_MATCH_CF_GAUGE_LAST    0x08
 +#define UTILS_MATCH_CF_GAUGE_INC     0x10
 +#define UTILS_MATCH_CF_GAUGE_ADD     0x20
  
  #define UTILS_MATCH_CF_COUNTER_SET   0x01
  #define UTILS_MATCH_CF_COUNTER_ADD   0x02
@@@ -128,6 -119,17 +128,17 @@@ cu_match_t *match_create_simple (const 
  
  /*
   * NAME
+  *  match_value_reset
+  *
+  * DESCRIPTION
+  *   Resets the internal state, if applicable. This function must be called
+  *   after each iteration for "simple" matches, usually after dispatching the
+  *   metrics.
+  */
+ void match_value_reset (cu_match_value_t *mv);
+ /*
+  * NAME
   *  match_destroy
   *
   * DESCRIPTION
diff --combined src/utils_rrdcreate.c
@@@ -2,23 -2,18 +2,23 @@@
   * collectd - src/utils_rrdcreate.c
   * Copyright (C) 2006-2013  Florian octo Forster
   *
 - * This program is free software; you can redistribute it and/or modify it
 - * under the terms of the GNU General Public License as published by the
 - * Free Software Foundation; only version 2 of the License is applicable.
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
   *
 - * This program is distributed in the hope that it will be useful, but
 - * WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * General Public License for more details.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
   *   Florian octo Forster <octo at collectd.org>
@@@ -104,6 -99,7 +104,7 @@@ static void srrd_create_args_destroy (s
        sfree (args->argv[i]);
      sfree (args->argv);
    }
+   sfree (args);
  } /* void srrd_create_args_destroy */
  
  static srrd_create_args_t *srrd_create_args_create (const char *filename,