Merge remote-tracking branch 'origin/pr/752' into wh_low_speed_limit
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 24 Mar 2015 06:37:18 +0000 (07:37 +0100)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 24 Mar 2015 06:37:18 +0000 (07:37 +0100)
Conflicts:
src/write_http.c

Also slipped in a couple of conding-style consistentcy related changes.

1  2 
src/collectd.conf.pod
src/write_http.c

diff --combined src/collectd.conf.pod
@@@ -9,17 -9,17 +9,17 @@@ collectd.conf - Configuration for the s
    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"
@@@ -519,7 -519,6 +519,7 @@@ possibly filtering or messages
   #   ExchangeType "fanout"
   #   RoutingKey "collectd"
   #   Persistent false
 + #   ConnectionRetryDelay 0
   #   Format "command"
   #   StoreRates false
   #   GraphitePrefix "collectd."
   #   QueueDurable false
   #   QueueAutoDelete true
   #   RoutingKey "collectd.#"
 + #   ConnectionRetryDelay 0
     </Subscribe>
   </Plugin>
  
@@@ -632,13 -630,6 +632,13 @@@ mode will be used, i.e. delivery is gua
  default), the I<transient> delivery mode will be used, i.e. messages may be
  lost due to high load, overflowing queues or similar issues.
  
 +=item B<ConnectionRetryDelay> I<Delay>
 +
 +When the connection to the AMQP broker is lost, defines the time in seconds to
 +wait before attempting to reconnect. Defaults to 0, which implies collectd will
 +attempt to reconnect at each read interval (in Subscribe mode) or each time
 +values are ready for submission (in Publish mode).
 +
  =item B<Format> B<Command>|B<JSON>|B<Graphite> (Publish only)
  
  Selects the format in which messages are sent to the broker. If set to
@@@ -1178,74 -1169,6 +1178,74 @@@ By default no detailed zone informatio
  
  =back
  
 +=head2 Plugin C<ceph>
 +
 +The ceph plugin collects values from JSON data to be parsed by B<libyajl>
 +(L<https://lloyd.github.io/yajl/>) retrieved from ceph daemon admin sockets.
 +
 +A separate B<Daemon> block must be configured for each ceph daemon to be
 +monitored. The following example will read daemon statistics from four
 +separate ceph daemons running on the same device (two OSDs, one MON, one MDS) :
 +
 +  <Plugin ceph>
 +    LongRunAvgLatency false
 +    ConvertSpecialMetricTypes true
 +    <Daemon "osd.0">
 +      SocketPath "/var/run/ceph/ceph-osd.0.asok"
 +    </Daemon>
 +    <Daemon "osd.1">
 +      SocketPath "/var/run/ceph/ceph-osd.1.asok"
 +    </Daemon>
 +    <Daemon "mon.a">
 +      SocketPath "/var/run/ceph/ceph-mon.ceph1.asok"
 +    </Daemon>
 +    <Daemon "mds.a">
 +      SocketPath "/var/run/ceph/ceph-mds.ceph1.asok"
 +    </Daemon>
 +  </Plugin>
 +
 +The ceph plugin accepts the following configuration options:
 +
 +=over 4
 +
 +=item B<LongRunAvgLatency> B<true>|B<false>
 +
 +If enabled, latency values(sum,count pairs) are calculated as the long run
 +average - average since the ceph daemon was started = (sum / count).
 +When disabled, latency values are calculated as the average since the last
 +collection = (sum_now - sum_last) / (count_now - count_last).
 +
 +Default: Disabled
 +
 +=item B<ConvertSpecialMetricTypes> B<true>|B<false>
 +
 +If enabled, special metrics (metrics that differ in type from similar counters)
 +are converted to the type of those similar counters. This currently only
 +applies to filestore.journal_wr_bytes which is a counter for OSD daemons. The
 +ceph schema reports this metric type as a sum,count pair while similar counters
 +are treated as derive types. When converted, the sum is used as the counter
 +value and is treated as a derive type.
 +When disabled, all metrics are treated as the types received from the ceph schema.
 +
 +Default: Enabled
 +
 +=back
 +
 +Each B<Daemon> block must have a string argument for the plugin instance name.
 +A B<SocketPath> is also required for each B<Daemon> block:
 +
 +=over 4
 +
 +=item B<Daemon> I<DaemonName>
 +
 +Name to be used as the instance name for this daemon.
 +
 +=item B<SocketPath> I<SocketPath>
 +
 +Specifies the path to the UNIX admin socket of the ceph daemon.
 +
 +=back
 +
  =head2 Plugin C<cgroups>
  
  This plugin collects the CPU user/system time for each I<cgroup> by reading the
@@@ -2957,8 -2880,8 +2957,8 @@@ which the sizes of physical memory vary
  
  =head2 Plugin C<modbus>
  
 -The B<modbus plugin> connects to a Modbus "slave" via Modbus/TCP and reads
 -register values. It supports reading single registers (unsigned 16E<nbsp>bit
 +The B<modbus plugin> connects to a Modbus "slave" via Modbus/TCP or Modbus/RTU and
 +reads register values. It supports reading single registers (unsigned 16E<nbsp>bit
  values), large integer values (unsigned 32E<nbsp>bit values) and floating point
  values (two registers interpreted as IEEE floats in big endian notation).
  
@@@ -2967,7 -2890,6 +2967,7 @@@ B<Synopsis:
   <Data "voltage-input-1">
     RegisterBase 0
     RegisterType float
 +   RegisterCmd ReadHolding
     Type voltage
     Instance "input-1"
   </Data>
   <Data "voltage-input-2">
     RegisterBase 2
     RegisterType float
 +   RegisterCmd ReadHolding
     Type voltage
     Instance "input-2"
   </Data>
  
 + <Data "supply-temperature-1">
 +   RegisterBase 0
 +   RegisterType Int16
 +   RegisterCmd ReadHolding
 +   Type temperature
 +   Instance "temp-1"
 + </Data>
 +
   <Host "modbus.example.com">
     Address "192.168.0.42"
     Port    "502"
     </Slave>
   </Host>
  
 + <Host "localhost">
 +   Device "/dev/ttyUSB0"
 +   Baudrate 38400
 +   Interval 20
 +
 +   <Slave 1>
 +     Instance "temperature"
 +     Collect  "supply-temperature-1"
 +   </Slave>
 + </Host>
 +
  =over 4
  
  =item E<lt>B<Data> I<Name>E<gt> blocks
@@@ -3034,11 -2936,6 +3034,11 @@@ Specifies what kind of data is returne
  B<Uint32> or B<Float>, two 16E<nbsp>bit registers will be read and the data is
  combined into one value. Defaults to B<Uint16>.
  
 +=item B<RegisterCmd> B<ReadHolding>|B<ReadInput>
 +
 +Specifies register type to be collected from device. Works only with libmodbus
 +2.9.2 or higher. Defaults to B<ReadHolding>.
 +
  =item B<Type> I<Type>
  
  Specifies the "type" (data set) to use when dispatching the value to
@@@ -3064,25 -2961,15 +3064,25 @@@ Within E<lt>HostE<nbsp>/E<gt> blocks, t
  
  =item B<Address> I<Hostname>
  
 -Specifies the node name (the actual network address) used to connect to the
 -host. This may be an IP address or a hostname. Please note that the used
 -I<libmodbus> library only supports IPv4 at the moment.
 +For Modbus/TCP, specifies the node name (the actual network address) used to
 +connect to the host. This may be an IP address or a hostname. Please note that
 +the used I<libmodbus> library only supports IPv4 at the moment.
  
  =item B<Port> I<Service>
  
 -Specifies the port used to connect to the host. The port can either be given as
 -a number or as a service name. Please note that the I<Service> argument must be
 -a string, even if ports are given in their numerical form. Defaults to "502".
 +for Modbus/TCP, specifies the port used to connect to the host. The port can
 +either be given as a number or as a service name. Please note that the
 +I<Service> argument must be a string, even if ports are given in their numerical
 +form. Defaults to "502".
 +
 +=item B<Device> I<Devicenode>
 +
 +For Modbus/RTU, specifies the path to the serial device being used.
 +
 +=item B<Baudrate> I<Baudrate>
 +
 +For Modbus/RTU, specifies the baud rate of the serial device.
 +Note, connections currently support only 8/N/1.
  
  =item B<Interval> I<Interval>
  
@@@ -3091,7 -2978,7 +3091,7 @@@ host. By default the global B<Interval
  
  =item E<lt>B<Slave> I<ID>E<gt>
  
 -Over each TCP connection, multiple Modbus devices may be reached. The slave ID
 +Over each connection, multiple Modbus devices may be reached. The slave ID
  is used to specify which device should be addressed. For each device you want
  to query, one B<Slave> block must be given.
  
@@@ -3222,12 -3109,12 +3222,12 @@@ Disabled by default
  
  Enable the collection of master / slave statistics in a replication setup. In
  order to be able to get access to these statistics, the user needs special
 -privileges. See the B<User> documentation above.
 +privileges. See the B<User> documentation above. Defaults to B<false>.
  
  =item B<SlaveNotifications> I<true|false>
  
  If enabled, the plugin sends a notification if the replication slave I/O and /
 -or SQL threads are not running.
 +or SQL threads are not running. Defaults to B<false>.
  
  =item B<ConnectTimeout> I<Seconds>
  
@@@ -4358,70 -4245,6 +4358,70 @@@ short: If it works for you: Great! But 
  change, though this is unlikely. Oh, and if you want to help improving this
  plugin, just send a short notice to the mailing list. ThanksE<nbsp>:)
  
 +=head2 Plugin C<openldap>
 +
 +To use the C<openldap> plugin you first need to configure the I<OpenLDAP>
 +server correctly. The backend database C<monitor> needs to be loaded and
 +working. See slapd-monitor(5) for the details.
 +
 +The configuration of the C<openldap> plugin consists of one or more B<Instance>
 +blocks. Each block requires one string argument as the instance name. For
 +example:
 +
 + <Plugin "openldap">
 +   <Instance "foo">
 +     URL "ldap://localhost/"
 +   </Instance>
 +   <Instance "bar">
 +     URL "ldaps://localhost/"
 +   </Instance>
 + </Plugin>
 +
 +The instance name will be used as the I<plugin instance>. To emulate the old
 +(versionE<nbsp>4) behavior, you can use an empty string (""). In order for the
 +plugin to work correctly, each instance name must be unique. This is not
 +enforced by the plugin and it is your responsibility to ensure it is.
 +
 +The following options are accepted within each B<Instance> block:
 +
 +=over 4
 +
 +=item B<URL> I<ldap://host/binddn>
 +
 +Sets the URL to use to connect to the I<OpenLDAP> server. This option is
 +I<mandatory>.
 +
 +=item B<StartTLS> B<true|false>
 +
 +Defines whether TLS must be used when connecting to the I<OpenLDAP> server.
 +Disabled by default.
 +
 +=item B<VerifyHost> B<true|false>
 +
 +Enables or disables peer host name verification. If enabled, the plugin checks
 +if the C<Common Name> or a C<Subject Alternate Name> field of the SSL
 +certificate matches the host name provided by the B<URL> option. If this
 +identity check fails, the connection is aborted. Enabled by default.
 +
 +=item B<CACert> I<File>
 +
 +File that holds one or more SSL certificates. If you want to use TLS/SSL you
 +may possibly need this option. What CA certificates are checked by default
 +depends on the distribution you use and can be changed with the usual ldap
 +client configuration mechanisms. See ldap.conf(5) for the details.
 +
 +=item B<Timeout> I<Seconds>
 +
 +Sets the timeout value for ldap operations. Defaults to B<-1> which results in
 +an infinite timeout.
 +
 +=item B<Version> I<Version>
 +
 +An integer which sets the LDAP protocol version number to use when connecting
 +to the I<OpenLDAP> server. Defaults to B<3> for using I<LDAPv3>.
 +
 +=back
 +
  =head2 Plugin C<openvpn>
  
  The OpenVPN plugin reads a status file maintained by OpenVPN and gathers
@@@ -5075,10 -4898,6 +5075,10 @@@ Specify the username to be used when co
  
  Specify the password to be used when connecting to the server.
  
 +=item B<ExpireDelay> I<delay>
 +
 +Skip expired values in query output.
 +
  =item B<SSLMode> I<disable>|I<allow>|I<prefer>|I<require>
  
  Specify whether to use an SSL connection when contacting the server. The
@@@ -5450,10 -5269,6 +5450,10 @@@ which configures the connection paramet
          Host "localhost"
          Port "6379"
          Timeout 2000
 +        <Query "LLEN myqueue">
 +          Type "queue_length"
 +          Instance "myqueue"
 +        <Query>
      </Node>
    </Plugin>
  
@@@ -5491,22 -5306,6 +5491,22 @@@ read function is blocking, you should k
  in mind that the sum of all B<Timeout> values for all B<Nodes> should be lower
  than B<Interval> defined globally.
  
 +=item B<Query> I<Querystring>
 +
 +The B<Query> block identifies a query to execute against the redis server.
 +There may be an arbitrary number of queries to execute.
 +
 +=item B<Type> I<Collectd type>
 +
 +Within a query definition, a valid collectd type to use as when submitting
 +the result of the query. When not supplied, will default to B<gauge>.
 +
 +=item B<Instance> I<Type instance>
 +
 +Within a query definition, an optional type instance to use when submitting
 +the result of the query. When not supplied will default to the escaped
 +command, up to 64 chars.
 +
  =back
  
  =head2 Plugin C<rrdcached>
@@@ -5611,14 -5410,6 +5611,14 @@@ Set the "XFiles Factor". The default i
  I<Factor> must be in the range C<[0.0-1.0)>, i.e. between zero (inclusive) and
  one (exclusive).
  
 +=item B<CollectStatistics> B<false>|B<true>
 +
 +When set to B<true>, various statistics about the I<rrdcached> daemon will be
 +collected, with "rrdcached" as the I<plugin name>. Defaults to B<false>.
 +
 +Statistics are read via I<rrdcached>s socket using the STATS command.
 +See L<rrdcached(1)> for details.
 +
  =back
  
  =head2 Plugin C<rrdtool>
@@@ -5848,40 -5639,6 +5848,40 @@@ measurements are discarded
  
  =back
  
 +=head2 Plugin C<smart>
 +
 +The C<smart> plugin collects SMART information from physical
 +disks. Values collectd include temperature, power cycle count, poweron
 +time and bad sectors. Also, all SMART attributes are collected along
 +with the normalized current value, the worst value, the threshold and
 +a human readable value.
 +
 +Using the following two options you can ignore some disks or configure the
 +collection only of specific disks.
 +
 +=over 4
 +
 +=item B<Disk> I<Name>
 +
 +Select the disk I<Name>. Whether it is collected or ignored depends on the
 +B<IgnoreSelected> setting, see below. As with other plugins that use the
 +daemon's ignorelist functionality, a string that starts and ends with a slash
 +is interpreted as a regular expression. Examples:
 +
 +  Disk "sdd"
 +  Disk "/hda[34]/"
 +
 +=item B<IgnoreSelected> B<true>|B<false>
 +
 +Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
 +statements, are ignored or if all other disks are ignored. The behavior
 +(hopefully) is intuitive: If no B<Disk> option is configured, all disks are
 +collected. If at least one B<Disk> option is given and no B<IgnoreSelected> or
 +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.
 +
 +=back
 +
  =head2 Plugin C<snmp>
  
  Since the configuration of the C<snmp plugin> is a little more complicated than
@@@ -5933,20 -5690,7 +5933,20 @@@ that I<Percent> of all reported timers 
  computed latency. This is useful for cutting off the long tail latency, as it's
  often done in I<Service Level Agreements> (SLAs).
  
 -If not specified, no percentile is calculated / dispatched.
 +Different percentiles can be calculated by setting this option several times.
 +If none are specified, no percentiles are calculated / dispatched.
 +
 +=item B<TimerLower> B<false>|B<true>
 +
 +=item B<TimerUpper> B<false>|B<true>
 +
 +=item B<TimerSum> B<false>|B<true>
 +
 +=item B<TimerCount> B<false>|B<true>
 +
 +Calculate and dispatch various values out of I<Timer> metrics received during
 +an interval. If set to B<False>, the default, these values aren't calculated /
 +dispatched.
  
  =back
  
@@@ -6205,8 -5949,6 +6205,8 @@@ Use the last number found
  The matched number is a counter. Simply I<sets> the internal counter to this
  value. Variants exist for C<COUNTER>, C<DERIVE>, and C<ABSOLUTE> data sources.
  
 +=item B<GaugeAdd>
 +
  =item B<CounterAdd>
  
  =item B<DeriveAdd>
@@@ -6215,8 -5957,6 +6215,8 @@@ Add the matched value to the internal c
  matched number may be negative, which will effectively subtract from the
  internal counter.
  
 +=item B<GaugeInc>
 +
  =item B<CounterInc>
  
  =item B<DeriveInc>
@@@ -6436,11 -6176,6 +6436,11 @@@ connections a mail server or news serve
  how many connections a web proxy holds to web servers. You have to give the
  port in numeric form.
  
 +=item B<AllPortsSummary> I<true>|I<false>
 +
 +If this option is set to I<true> a summary of statistics from all connections
 +are collectd. This option defaults to I<false>.
 +
  =back
  
  =head2 Plugin C<thermal>
@@@ -6570,35 -6305,22 +6570,35 @@@ Take the UUID from the given file (defa
  =head2 Plugin C<varnish>
  
  The I<varnish plugin> collects information about Varnish, an HTTP accelerator.
 +It collects a subset of the values displayed by L<varnishstat(1)>, and
 +organizes them in categories which can be enabled or disabled. Currently only
 +metrics shown in L<varnishstat(1)>'s I<MAIN> section are collected. The exact
 +meaning of each metric can be found in L<varnish-counters(7)>.
  
  Synopsis:
  
   <Plugin "varnish">
     <Instance "example">
 +     CollectBackend     true
 +     CollectBan         false
       CollectCache       true
       CollectConnections true
 -     CollectBackend     true
 -     CollectSHM         true
 +     CollectDirectorDNS false
       CollectESI         false
       CollectFetch       false
       CollectHCB         false
 +     CollectObjects     false
 +     CollectPurge       false
 +     CollectSession     false
 +     CollectSHM         true
       CollectSMA         false
       CollectSMS         false
       CollectSM          false
 +     CollectStruct      false
       CollectTotals      false
 +     CollectUptime      false
 +     CollectVCL         false
 +     CollectVSM         false
       CollectWorkers     false
     </Instance>
   </Plugin>
@@@ -6612,24 -6334,29 +6612,24 @@@ Inside each E<lt>B<Instance>E<gt> block
  
  =over 4
  
 -=item B<CollectCache> B<true>|B<false>
 -
 -Cache hits and misses. True by default.
 -
 -=item B<CollectConnections> B<true>|B<false>
 -
 -Number of client connections received, accepted and dropped. True by default.
 -
  =item B<CollectBackend> B<true>|B<false>
  
  Back-end connection statistics, such as successful, reused,
  and closed connections. True by default.
  
 -=item B<CollectSHM> B<true>|B<false>
 -
 -Statistics about the shared memory log, a memory region to store
 -log messages which is flushed to disk when full. True by default.
 -
  =item B<CollectBan> B<true>|B<false>
  
  Statistics about ban operations, such as number of bans added, retired, and
  number of objects tested against ban operations. Only available with Varnish
 -3.x. False by default.
 +3.x and above. False by default.
 +
 +=item B<CollectCache> B<true>|B<false>
 +
 +Cache hits and misses. True by default.
 +
 +=item B<CollectConnections> B<true>|B<false>
 +
 +Number of client connections received, accepted and dropped. True by default.
  
  =item B<CollectDirectorDNS> B<true>|B<false>
  
@@@ -6663,14 -6390,7 +6663,14 @@@ number of objects tested against purge 
  =item B<CollectSession> B<true>|B<false>
  
  Client session statistics. Number of past and current sessions, session herd and
 -linger counters, etc. False by default.
 +linger counters, etc. False by default. Note that if using Varnish 4.x, some
 +metrics found in the Connections and Threads sections with previous versions of
 +Varnish have been moved here.
 +
 +=item B<CollectSHM> B<true>|B<false>
 +
 +Statistics about the shared memory log, a memory region to store
 +log messages which is flushed to disk when full. True by default.
  
  =item B<CollectSMA> B<true>|B<false>
  
@@@ -6701,17 -6421,12 +6701,17 @@@ the number of requests and bytes transf
  
  =item B<CollectUptime> B<true>|B<false>
  
 -Varnish uptime. False by default.
 +Varnish uptime. Only available with Varnish 3.x and above. False by default.
  
  =item B<CollectVCL> B<true>|B<false>
  
  Number of total (available + discarded) VCL (config files). False by default.
  
 +=item B<CollectVSM> B<true>|B<false>
 +
 +Collect statistics about Varnish's shared memory usage (used by the logging and
 +statistics subsystems). Only available with Varnish 4.x. False by default.
 +
  =item B<CollectWorkers> B<true>|B<false>
  
  Collect statistics about worker threads. False by default.
@@@ -6779,7 -6494,7 +6779,7 @@@ will be collected
  
  =item B<HostnameFormat> B<name|uuid|hostname|...>
  
 -When the libvirt plugin logs data, it sets the hostname of the collected data
 +When the virt plugin logs data, it sets the hostname 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>.
  
@@@ -6795,7 -6510,7 +6795,7 @@@ between, thus I<"foo:1234-1234-1234-123
  
  =item B<InterfaceFormat> B<name>|B<address>
  
 -When the libvirt plugin logs interface data, it sets the name of the collected
 +When the virt plugin logs interface data, it sets the name of the collected
  data according to this setting. The default is to use the path as provided by
  the hypervisor (the "dev" property of the target node), which is equal to
  setting B<name>.
@@@ -6805,7 -6520,7 +6805,7 @@@ interface path might change between reb
  
  =item B<PluginInstanceFormat> B<name|uuid>
  
 -When the libvirt plugin logs data, it sets the plugin_instance of the collected
 +When the virt 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>.
  
@@@ -7039,29 -6754,25 +7039,29 @@@ want to use authentication all three fi
  
  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.
 +L<collectd-unixsock(5)>.
  
  Synopsis:
  
   <Plugin "write_http">
 -   <URL "http://example.com/post-collectd">
 +   <Node "example">
 +     URL "http://example.com/post-collectd"
       User "collectd"
       Password "weCh3ik0"
       Format JSON
 -   </URL>
 +   </Node>
   </Plugin>
  
 -B<URL> blocks need one string argument which is used as the URL to which data
 -is posted. The following options are understood within B<URL> blocks.
 +The plugin can send values to multiple HTTP servers by specifying one
 +E<lt>B<Node>E<nbsp>I<Name>E<gt> block for each server. Within each B<Node>
 +block, the following options are available:
  
  =over 4
  
 +=item B<URL> I<URL>
 +
 +URL to which the values are submitted to. Mandatory.
 +
  =item B<User> I<Username>
  
  Optional user name needed for authentication.
@@@ -7138,6 -6849,22 +7138,22 @@@ are available on the server side. I<Byt
  exceed the size of an C<int>, i.e. 2E<nbsp>GByte.
  Defaults to C<4096>.
  
 -If set to B<true>, average transfer speed in bytes per second will be checked. 
 -In case it is below B<LowLimitBytesPerSec> connection will be considered slow 
+ =item B<LowSpeedLimit> B<true|false>
 -Sets bytes per second value for B<LowSpeedLimit> to make a decission if 
++If set to B<true>, average transfer speed in bytes per second will be checked.
++In case it is below B<LowLimitBytesPerSec> connection will be considered slow
+ and aborted.
+ =item B<LowLimitBytesPerSec> I<Bytes>
++Sets bytes per second value for B<LowSpeedLimit> to make a decission if
+ connection is too slow. Default value is C<100>.
+ =item B<PostTimeoutSec> I<Seconds>
+ If defined, provided positive integer value will be used to set maximum time
+ in seconds that you allow for transfer(http post) operation to take.
  =back
  
  =head2 Plugin C<write_kafka>
@@@ -7247,61 -6974,6 +7263,61 @@@ want to set B<metadata.broker.list> to 
  
  =back
  
 +=head2 Plugin C<write_redis>
 +
 +The I<write_redis plugin> submits values to I<Redis>, a data structure server.
 +
 +Synopsis:
 +
 +  <Plugin "write_redis">
 +    <Node "example">
 +        Host "localhost"
 +        Port "6379"
 +        Timeout 1000
 +    </Node>
 +  </Plugin>
 +
 +Values are submitted to I<Sorted Sets>, using the metric name as the key, and
 +the timestamp as the score. Retrieving a date range can then be done using the
 +C<ZRANGEBYSCORE> I<Redis> command. Additionnally, all the identifiers of these
 +I<Sorted Sets> are kept in a I<Set> called C<collectd/values> and can be
 +retrieved using the C<SMEMBERS> I<Redis> command. See
 +L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
 +details.
 +
 +The information shown in the synopsis above is the I<default configuration>
 +which is used by the plugin if no configuration is present.
 +
 +The plugin can send values to multiple instances of I<Redis> by specifying
 +one B<Node> block for each instance. Within the B<Node> blocks, the following
 +options are available:
 +
 +=over 4
 +
 +=item B<Node> I<Nodename>
 +
 +The B<Node> block identifies a new I<Redis> node, that is a new I<Redis>
 +instance running in an specified host and port. The name for node is a
 +canonical identifier which is used as I<plugin instance>. It is limited to
 +64E<nbsp>characters in length.
 +
 +=item B<Host> I<Hostname>
 +
 +The B<Host> option is the hostname or IP-address where the I<Redis> instance is
 +running on.
 +
 +=item B<Port> I<Port>
 +
 +The B<Port> option is the TCP port on which the Redis instance accepts
 +connections. Either a service name of a port number may be given. Please note
 +that numerical port numbers must be given as a string, too.
 +
 +=item B<Timeout> I<Timeout in miliseconds>
 +
 +The B<Timeout> option sets the socket connection timeout, in milliseconds.
 +
 +=back
 +
  =head2 Plugin C<write_riemann>
  
  The I<write_riemann plugin> will send values to I<Riemann>, a powerful stream
@@@ -7347,26 -7019,7 +7363,26 @@@ Service name or port number to connect 
  =item B<Protocol> B<UDP>|B<TCP>
  
  Specify the protocol to use when communicating with I<Riemann>. Defaults to
 -B<UDP>.
 +B<TCP>.
 +
 +=item B<Batch> B<true>|B<false>
 +
 +If set to B<true> and B<Protocol> is set to B<TCP>,
 +events will be batched in memory and flushed at
 +regular intervals or when B<BatchMaxSize> is exceeded.
 +
 +Notifications are not batched and sent as soon as possible.
 +
 +When enabled, it can occur that events get processed by the Riemann server
 +close to or after their expiration time. Tune the B<TTLFactor> and
 +B<BatchMaxSize> settings according to the amount of values collected, if this
 +is an issue.
 +
 +Defaults to true
 +
 +=item B<BatchMaxSize> I<size>
 +
 +Maximum payload size for a riemann packet. Defaults to 8192
  
  =item B<StoreRates> B<true>|B<false>
  
@@@ -7424,31 -7077,6 +7440,31 @@@ attribute for each metric being sent ou
  
  =back
  
 +=head2 Plugin C<zookeeper>
 +
 +The I<zookeeper plugin> will collect statistics from a I<Zookeeper> server
 +using the mntr command.  It requires Zookeeper 3.4.0+ and access to the
 +client port.
 +
 +B<Synopsis:>
 +
 + <Plugin "zookeeper">
 +   Host "127.0.0.1"
 +   Port "2181"
 + </Plugin>
 +
 +=over 4
 +
 +=item B<Host> I<Address>
 +
 +Hostname or address to connect to. Defaults to C<localhost>.
 +
 +=item B<Port> I<Service>
 +
 +Service name or port number to connect to. Defaults to C<2181>.
 +
 +=back
 +
  =head1 THRESHOLD CONFIGURATION
  
  Starting with version C<4.3.0> collectd has support for B<monitoring>. By that
diff --combined src/write_http.c
  # define WRITE_HTTP_DEFAULT_BUFFER_SIZE 4096
  #endif
  
+ #define WH_DEFAULT_LOW_LIMIT_BYTES_PER_SEC 100
  /*
   * Private variables
   */
  struct wh_callback_s
  {
 -        char *location;
 +        char *name;
  
 +        char *location;
          char *user;
          char *pass;
          char *credentials;
          char *clientcert;
          char *clientkeypass;
          long sslversion;
 -        _Bool store_rates; 
 +        _Bool store_rates;
+         _Bool abort_on_slow;
+         int   low_limit_bytes;
+         time_t interval;
+         int post_timeout;
  
  #define WH_FORMAT_COMMAND 0
  #define WH_FORMAT_JSON    1
@@@ -121,6 -125,16 +126,16 @@@ static int wh_callback_init (wh_callbac
                  return (-1);
          }
  
 -        if(cb->abort_on_slow && cb->interval > 0)
++        if (cb->abort_on_slow && cb->interval > 0)
+         {
 -            curl_easy_setopt(cb->curl, CURLOPT_LOW_SPEED_LIMIT, (cb->low_limit_bytes?cb->low_limit_bytes:WH_DEFAULT_LOW_LIMIT_BYTES_PER_SEC));
 -            curl_easy_setopt(cb->curl, CURLOPT_LOW_SPEED_TIME, cb->interval);
 -        }
 -        if(cb->post_timeout >0)
 -        {
 -           curl_easy_setopt(cb->curl, CURLOPT_TIMEOUT, cb->post_timeout);
++                curl_easy_setopt (cb->curl, CURLOPT_LOW_SPEED_LIMIT,
++                                  (cb->low_limit_bytes ? cb->low_limit_bytes : WH_DEFAULT_LOW_LIMIT_BYTES_PER_SEC));
++                curl_easy_setopt (cb->curl, CURLOPT_LOW_SPEED_TIME, cb->interval);
+         }
++        if (cb->post_timeout > 0)
++                curl_easy_setopt (cb->curl, CURLOPT_TIMEOUT, cb->post_timeout);
++
          curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L);
          curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
  
  
          curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf);
          curl_easy_setopt (cb->curl, CURLOPT_URL, cb->location);
 +        curl_easy_setopt (cb->curl, CURLOPT_FOLLOWLOCATION, 1L);
 +        curl_easy_setopt (cb->curl, CURLOPT_MAXREDIRS, 50L);
  
          if (cb->user != NULL)
          {
 +#ifdef HAVE_CURLOPT_USERNAME
 +                curl_easy_setopt (cb->curl, CURLOPT_USERNAME, cb->user);
 +                curl_easy_setopt (cb->curl, CURLOPT_PASSWORD,
 +                        (cb->pass == NULL) ? "" : cb->pass);
 +#else
                  size_t credentials_size;
  
                  credentials_size = strlen (cb->user) + 2;
                  ssnprintf (cb->credentials, credentials_size, "%s:%s",
                                  cb->user, (cb->pass == NULL) ? "" : cb->pass);
                  curl_easy_setopt (cb->curl, CURLOPT_USERPWD, cb->credentials);
 +#endif
                  curl_easy_setopt (cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
          }
  
@@@ -298,7 -304,6 +313,7 @@@ static void wh_callback_free (void *dat
                  curl_easy_cleanup (cb->curl);
                  cb->curl = NULL;
          }
 +        sfree (cb->name);
          sfree (cb->location);
          sfree (cb->user);
          sfree (cb->pass);
@@@ -361,6 -366,7 +376,7 @@@ static int wh_write_command (const data
  
          if (cb->curl == NULL)
          {
+                 cb->interval = CDTIME_T_TO_TIME_T(vl->interval);
                  status = wh_callback_init (cb);
                  if (status != 0)
                  {
@@@ -404,11 -410,13 +420,13 @@@ static int wh_write_json (const data_se
                  wh_callback_t *cb)
  {
          int status;
 -              
 +
          pthread_mutex_lock (&cb->send_lock);
  
          if (cb->curl == NULL)
          {
+                 cb->interval = CDTIME_T_TO_TIME_T(vl->interval);
                  status = wh_callback_init (cb);
                  if (status != 0)
                  {
@@@ -501,12 -509,11 +519,12 @@@ static int config_set_format (wh_callba
          return (0);
  } /* }}} int config_set_format */
  
 -static int wh_config_url (oconfig_item_t *ci) /* {{{ */
 +static int wh_config_node (oconfig_item_t *ci) /* {{{ */
  {
          wh_callback_t *cb;
          int buffer_size = 0;
          user_data_t user_data;
 +        char callback_name[DATA_MAX_NAME_LEN];
          int i;
  
          cb = malloc (sizeof (*cb));
          cb->verify_host = 1;
          cb->format = WH_FORMAT_COMMAND;
          cb->sslversion = CURL_SSLVERSION_DEFAULT;
+         cb->low_limit_bytes = WH_DEFAULT_LOW_LIMIT_BYTES_PER_SEC;
+         cb->post_timeout = 0;
  
          pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
  
 -        cf_util_get_string (ci, &cb->location);
 -        if (cb->location == NULL)
 -                return (-1);
 +        cf_util_get_string (ci, &cb->name);
 +
 +        /* FIXME: Remove this legacy mode in version 6. */
 +        if (strcasecmp ("URL", ci->key) == 0)
 +                cf_util_get_string (ci, &cb->location);
  
          for (i = 0; i < ci->children_num; i++)
          {
                  oconfig_item_t *child = ci->children + i;
  
 -                if (strcasecmp ("User", child->key) == 0)
 +                if (strcasecmp ("URL", child->key) == 0)
 +                        cf_util_get_string (child, &cb->location);
 +                else if (strcasecmp ("User", child->key) == 0)
                          cf_util_get_string (child, &cb->user);
                  else if (strcasecmp ("Password", child->key) == 0)
                          cf_util_get_string (child, &cb->pass);
                          cf_util_get_boolean (child, &cb->store_rates);
                  else if (strcasecmp ("BufferSize", child->key) == 0)
                          cf_util_get_int (child, &buffer_size);
+                 else if (strcasecmp ("LowSpeedLimit", child->key) == 0)
+                         cf_util_get_boolean (child,&cb->abort_on_slow);
+                 else if (strcasecmp ("LowLimitBytesPerSec", child->key) == 0)
+                         cf_util_get_int (child, &cb->low_limit_bytes);
+                 else if (strcasecmp ("PostTimeoutSec", child->key) == 0)
+                         cf_util_get_int (child, &cb->post_timeout);
                  else
                  {
                          ERROR ("write_http plugin: Invalid configuration "
                  }
          }
  
 -        if(cb->abort_on_slow)
 -        {
 -              cb->interval = CDTIME_T_TO_TIME_T(plugin_get_interval());
 -        }
 -        if(cb->post_timeout == 0)
 +        if (cb->location == NULL)
          {
 -              //setting default timeout to plugin interval.
 -              cb->post_timeout = CDTIME_T_TO_TIME_T(plugin_get_interval());
 +                ERROR ("write_http plugin: no URL defined for instance '%s'",
 +                        cb->name);
 +                wh_callback_free (cb);
 +                return (-1);
          }
  
++        if (cb->abort_on_slow)
++                cb->interval = CDTIME_T_TO_TIME_T(plugin_get_interval());
++
++        if (cb->post_timeout == 0)
++                //setting default timeout to plugin interval.
++                cb->post_timeout = CDTIME_T_TO_TIME_T(plugin_get_interval());
++
          /* Determine send_buffer_size. */
          cb->send_buffer_size = WRITE_HTTP_DEFAULT_BUFFER_SIZE;
          if (buffer_size >= 1024)
          /* Nulls the buffer and sets ..._free and ..._fill. */
          wh_reset_buffer (cb);
  
 -        DEBUG ("write_http: Registering write callback with URL %s",
 -                        cb->location);
 +        ssnprintf (callback_name, sizeof (callback_name), "write_http/%s",
 +                        cb->name);
 +        DEBUG ("write_http: Registering write callback '%s' with URL '%s'",
 +                        callback_name, cb->location);
  
          memset (&user_data, 0, sizeof (user_data));
          user_data.data = cb;
          user_data.free_func = NULL;
 -        plugin_register_flush ("write_http", wh_flush, &user_data);
 +        plugin_register_flush (callback_name, wh_flush, &user_data);
  
          user_data.free_func = wh_callback_free;
 -        plugin_register_write ("write_http", wh_write, &user_data);
 +        plugin_register_write (callback_name, wh_write, &user_data);
  
          return (0);
 -} /* }}} int wh_config_url */
 +} /* }}} int wh_config_node */
  
  static int wh_config (oconfig_item_t *ci) /* {{{ */
  {
          {
                  oconfig_item_t *child = ci->children + i;
  
 -                if (strcasecmp ("URL", child->key) == 0)
 -                        wh_config_url (child);
 +                if (strcasecmp ("Node", child->key) == 0)
 +                        wh_config_node (child);
 +                /* FIXME: Remove this legacy mode in version 6. */
 +                else if (strcasecmp ("URL", child->key) == 0) {
 +                        WARNING ("write_http plugin: Legacy <URL> block found. "
 +                                "Please use <Node> instead.");
 +                        wh_config_node (child);
 +                }
                  else
                  {
                          ERROR ("write_http plugin: Invalid configuration "