Merge branch 'collectd-5.4' into collectd-5.5
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 12 Jan 2016 08:03:09 +0000 (09:03 +0100)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 12 Jan 2016 08:03:09 +0000 (09:03 +0100)
1  2 
src/collectd.conf.in
src/collectd.conf.pod
src/curl_json.c
src/email.c
src/libcollectdclient/network.c
src/openvpn.c
src/perl.c
src/snmp.c

diff --combined src/collectd.conf.in
  #AutoLoadPlugin false
  
  #----------------------------------------------------------------------------#
 +# When enabled, internal statistics are collected, using "collectd" as the   #
 +# plugin name.                                                               #
 +# Disabled by default.                                                       #
 +#----------------------------------------------------------------------------#
 +#CollectInternalStats false
 +
 +#----------------------------------------------------------------------------#
  # Interval at which to query values. This may be overwritten on a per-plugin #
  # base by using the 'Interval' option of the LoadPlugin block:               #
  #   <LoadPlugin foo>                                                         #
  #----------------------------------------------------------------------------#
  #Interval     10
  
 -#Timeout      2
 -#ReadThreads  5
 -#WriteThreads 5
 +#MaxReadInterval 86400
 +#Timeout         2
 +#ReadThreads     5
 +#WriteThreads    5
  
  # Limit the size of the write queue. Default is no limit. Setting up a limit is
  # recommended for servers handling a high volume of traffic.
@@@ -60,7 -52,6 +60,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>
  #@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_CEPH_TRUE@LoadPlugin ceph
 +#@BUILD_PLUGIN_CGROUPS_TRUE@LoadPlugin cgroups
  #@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
  #@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch
 -#@BUILD_PLUGIN_CGROUPS_TRUE@LoadPlugin cgroups
  @BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
  #@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
  @LOAD_PLUGIN_CSV@LoadPlugin csv
  #@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_EXEC_TRUE@LoadPlugin exec
 +#@BUILD_PLUGIN_FHCOUNT_TRUE@LoadPlugin fhcount
  #@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
  #@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
  #@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
  #@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
  @BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
 -#@BUILD_PLUGIN_IPTABLES_TRUE@LoadPlugin iptables
 +#@BUILD_PLUGIN_IPC_TRUE@@BUILD_PLUGIN_IPC_TRUE@LoadPlugin ipc
  #@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
 +#@BUILD_PLUGIN_IPTABLES_TRUE@LoadPlugin iptables
  #@BUILD_PLUGIN_IPVS_TRUE@LoadPlugin ipvs
  #@BUILD_PLUGIN_IRQ_TRUE@LoadPlugin irq
  #@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
 -#@BUILD_PLUGIN_LIBVIRT_TRUE@LoadPlugin libvirt
  @BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
  #@BUILD_PLUGIN_LPAR_TRUE@LoadPlugin lpar
  #@BUILD_PLUGIN_LVM_TRUE@LoadPlugin lvm
  #@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
  #@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
  @BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
 +#@BUILD_PLUGIN_MIC_TRUE@LoadPlugin mic
  #@BUILD_PLUGIN_MODBUS_TRUE@LoadPlugin modbus
  #@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
  #@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
  #@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
  #@BUILD_PLUGIN_OLSRD_TRUE@LoadPlugin olsrd
  #@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
 +#@BUILD_PLUGIN_OPENLDAP_TRUE@LoadPlugin openldap
  #@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
  #@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
  #@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
  #@BUILD_PLUGIN_SENSORS_TRUE@LoadPlugin sensors
  #@BUILD_PLUGIN_SERIAL_TRUE@LoadPlugin serial
  #@BUILD_PLUGIN_SIGROK_TRUE@LoadPlugin sigrok
 +#@BUILD_PLUGIN_SMART_TRUE@LoadPlugin smart
  #@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
  #@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
  #@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
  #@BUILD_PLUGIN_TED_TRUE@LoadPlugin ted
  #@BUILD_PLUGIN_THERMAL_TRUE@LoadPlugin thermal
  #@BUILD_PLUGIN_TOKYOTYRANT_TRUE@LoadPlugin tokyotyrant
 +#@BUILD_PLUGIN_TURBOSTAT_TRUE@LoadPlugin turbostat
  #@BUILD_PLUGIN_UNIXSOCK_TRUE@LoadPlugin unixsock
  #@BUILD_PLUGIN_UPTIME_TRUE@LoadPlugin uptime
  #@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
  #@BUILD_PLUGIN_UUID_TRUE@LoadPlugin uuid
  #@BUILD_PLUGIN_VARNISH_TRUE@LoadPlugin varnish
 -#@BUILD_PLUGIN_MIC_TRUE@LoadPlugin mic
 +#@BUILD_PLUGIN_VIRT_TRUE@LoadPlugin virt
  #@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
  #@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
  #@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_LOG_TRUE@LoadPlugin write_log
  #@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_SENSU_TRUE@LoadPlugin write_sensu
 +#@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb
  #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
  #@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
 +#@BUILD_PLUGIN_ZOOKEEPER_TRUE@LoadPlugin zookeeper
  
  ##############################################################################
  # Plugin configuration                                                       #
  # 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"
  #    RoutingKey "collectd"
  #    Persistent false
  #    StoreRates false
 +#    ConnectionRetryDelay 0
  #  </Publish>
  #</Plugin>
  
  #     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 "battery">
 +#  ValuesPercentage false
 +#  ReportDegraded false
 +#</Plugin>
 +
  #<Plugin "bind">
  #  URL "http://localhost:8053/"
  #  ParseTime       false
  #  </View>
  #</Plugin>
  
 +#<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>
 +
  #<Plugin cgroups>
  #  CGroup "libvirt"
  #  IgnoreSelected false
  #</Plugin>
  
 +#<Plugin cpu>
 +#  ReportByCpu true
 +#  ReportByState 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>
  #     NotificationExec "user:group" "/path/to/exec"
  #</Plugin>
  
 +#<Plugin fhcount>
 +#     ValuesAbsolute true
 +#     ValuesPercentage false
 +#</Plugin>
 +
  #<Plugin filecount>
  #     <Directory "/path/to/dir">
  #             Instance "foodir"
  #     </Directory>
  #</Plugin>
  
 -#<Plugin "gmond">
 +#<Plugin gmond>
  #  MCReceiveFrom "239.2.11.71" "8649"
  #  <Metric "swap_total">
  #    Type "swap"
  
  #<Plugin iptables>
  #     Chain table chain
+ #     Chain6 table chain
  #</Plugin>
  
  #<Plugin irq>
  #     IgnoreSelected true
  #</Plugin>
  
 -#<Plugin "java">
 +#<Plugin java>
  #     JVMArg "-verbose:jni"
  #     JVMArg "-Djava.class.path=@prefix@/share/collectd/java/collectd-api.jar"
  #
  #     </Plugin>
  #</Plugin>
  
 -#<Plugin libvirt>
 -#     Connection "xen:///"
 -#     RefreshInterval 60
 -#     Domain "name"
 -#     BlockDevice "name:device"
 -#     InterfaceDevice "name:device"
 -#     IgnoreSelected false
 -#     HostnameFormat name
 -#     InterfaceFormat name
 +#<Plugin load>
 +#        ReportRelative true
  #</Plugin>
  
  #<Plugin lpar>
  #     </Instance>
  #</Plugin>
  
 +#<Plugin memory>
 +#     ValuesAbsolute true
 +#     ValuesPercentage false
 +#</Plugin>
 +
  #<Plugin modbus>
  #     <Data "data_name">
  #             RegisterBase 1234
 +#             RegisterCmd ReadHolding
  #             RegisterType float
  #             Type gauge
  #             Instance "..."
  #             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
  #             Username "user"
  #             Password "secret"
  #             Interface "eth0"
 +#             ResolveInterval 14400
  @LOAD_PLUGIN_NETWORK@ </Server>
  #     TimeToLive 128
  #
  #     IgnoreSelected false
  #</Plugin>
  
 +#<Plugin openldap>
 +#  <Instance "localhost">
 +#    URL "ldap://localhost:389"
 +#    StartTLS false
 +#    VerifyHost true
 +#    CACert "/path/to/ca.crt"
 +#    Timeout -1
 +#    Version 3
 +#  </Instance>
 +#</Plugin>
 +
  #<Plugin openvpn>
  #     StatusFile "/etc/openvpn/openvpn-status.log"
  #     ImprovedNamingSchema false
  #  </Device>
  #</Plugin>
  
 +#<Plugin smart>
 +#  Disk "/^[hs]d[a-f][0-9]?$/"
 +#  IgnoreSelected false
 +#</Plugin>
 +
  #<Plugin snmp>
  #   <Data "powerplus_voltge_input">
  #       Type "voltage"
  #  TimerCount     false
  #</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"
  
  #<Plugin tcpconns>
  #     ListeningPorts false
 +#     AllPortsSummary false
  #     LocalPort "25"
  #     RemotePort "25"
  #</Plugin>
  #     Port "1978"
  #</Plugin>
  
 +#<Plugin turbostat>
 +##    None of the following option should be set manually
 +##    This plugin automatically detect most optimal options
 +##    Only set values here if:
 +##    - The module ask you to
 +##    - You want to disable the collection of some data
 +##    - Your (intel) CPU is not supported (yet) by the module
 +##    - The module generate a lot of errors 'MSR offset 0x... read failed'
 +##    In the last two cases, please open a bug request
 +#
 +#     TCCActivationTemp "100"
 +#     CoreCstates "392"
 +#     PackageCstates "396"
 +#     SystemManagementInterrupt true
 +#     DigitalTemperatureSensor true
 +#     PackageThermalManagement true
 +#     RunningAveragePowerLimit "7"    
 +#</Plugin>
 +
  #<Plugin unixsock>
  #     SocketFile "@prefix@/var/run/@PACKAGE_NAME@-unixsock"
  #     SocketGroup "collectd"
  #   If you prefer defining another instance you can do
  #   so by using <Instance "myinstance">
  #   <Instance>
 -#      CollectCache true
  #      CollectBackend true
 -#      CollectBan false           # Varnish 3 only
 +#      CollectBan false           # Varnish 3 and above
 +#      CollectCache true
  #      CollectConnections true
  #      CollectDirectorDNS false   # Varnish 3 only
 -#      CollectSHM true
  #      CollectESI false
  #      CollectFetch false
  #      CollectHCB false
  #      CollectObjects false
  #      CollectPurge false         # Varnish 2 only
  #      CollectSession false
 +#      CollectSHM true
  #      CollectSMA false           # Varnish 2 only
  #      CollectSMS false
  #      CollectSM false            # Varnish 2 only
  #      CollectStruct false
  #      CollectTotals false
 -#      CollectUptime false
 +#      CollectUptime false        # Varnish 3 and above
  #      CollectVCL false
 +#      CollectVSM false           # Varnish 4 only
  #      CollectWorkers false
  #   </Instance>
  #</Plugin>
  
 +#<Plugin virt>
 +#     Connection "xen:///"
 +#     RefreshInterval 60
 +#     Domain "name"
 +#     BlockDevice "name:device"
 +#     InterfaceDevice "name:device"
 +#     IgnoreSelected false
 +#     HostnameFormat name
 +#     InterfaceFormat name
 +#     PluginInstanceFormat name
 +#</Plugin>
 +
  #<Plugin vmem>
  #     Verbose false
  #</Plugin>
  #</Plugin>
  
  #<Plugin write_http>
 -#     <URL "http://example.com/collectd-post">
 +#     <Node "example">
 +#             URL "http://example.com/collectd-post"
  #             User "collectd"
  #             Password "weCh3ik0"
  #             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
 -#     </URL>
 +#             BufferSize 4096
 +#             LowSpeedLimit 0
 +#             Timeout 0
 +#     </Node>
 +#</Plugin>
 +
 +#<Plugin write_kafka>
 +#  Property "metadata.broker.list" "localhost:9092"
 +#  <Topic "collectd">
 +#    Format JSON
 +#  </Topic>
  #</Plugin>
  
  #<Plugin write_mongodb>
  #     <Node "example">
  #             Host "localhost"
  #             Port 5555
 -#             Protocol UDP
 +#             Protocol TCP
 +#             Batch true
 +#             BatchMaxSize 8192
  #             StoreRates true
  #             AlwaysAppendDS false
  #             TTLFactor 2.0
 +#             Notifications true
 +#             CheckThresholds false
 +#             EventServicePrefix ""
 +#     </Node>
 +#     Tag "foobar"
 +#     Attribute "foo" "bar"
 +#</Plugin>
 +
 +#<Plugin write_sensu>
 +#     <Node "example">
 +#             Host "localhost"
 +#             Port 3030
 +#             StoreRates true
 +#             AlwaysAppendDS false
 +#             Notifications true
 +#             Metrics true
 +#             EventServicePrefix ""
 +#             MetricHandler "influx"
 +#             MetricHandler "default"
 +#             NotificationHandler "flapjack"
 +#             NotificationHandler "howling_monkey"
  #     </Node>
  #     Tag "foobar"
 +#     Attribute "foo" "bar"
 +#</Plugin>
 +
 +#<Plugin write_tsdb>
 +#     <Node>
 +#             Host "localhost"
 +#             Port "4242"
 +#             HostTags "status=production"
 +#             StoreRates false
 +#             AlwaysAppendDS false
 +#     </Node>
 +#</Plugin>
 +
 +#<Plugin zookeeper>
 +#    Host "localhost"
 +#    Port "2181"
  #</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
@@@ -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"
@@@ -145,33 -145,6 +145,33 @@@ B<E<lt>PluginE<nbsp>...E<gt>> block act
  B<LoadPlugin> statement. B<LoadPlugin> statements are still required for
  plugins that don't provide any configuration, e.g. the I<Load plugin>.
  
 +=item B<CollectInternalStats> B<false>|B<true>
 +
 +When set to B<true>, various statistics about the I<collectd> daemon will be
 +collected, with "collectd" as the I<plugin name>. Defaults to B<false>.
 +
 +The following metrics are reported:
 +
 +=over 4
 +
 +=item C<collectd-write_queue/queue_length>
 +
 +The number of metrics currently in the write queue. You can limit the queue
 +length with the B<WriteQueueLimitLow> and B<WriteQueueLimitHigh> options.
 +
 +=item C<collectd-write_queue/derive-dropped>
 +
 +The number of metrics dropped due to a queue length limitation.
 +If this value is non-zero, your system can't handle all incoming metrics and
 +protects itself against overload by dropping metrics.
 +
 +=item C<collectd-cache/cache_size>
 +
 +The number of elements in the metric cache (the cache you can interact with
 +using L<collectd-unixsock(5)>).
 +
 +=back
 +
  =item B<Include> I<Path> [I<pattern>]
  
  If I<Path> points to a file, includes that file. If I<Path> points to a
@@@ -244,14 -217,6 +244,14 @@@ B<Warning:> You should set this once an
  I<you will have to delete all your RRD files> or know some serious RRDtool
  magic! (Assuming you're using the I<RRDtool> or I<RRDCacheD> plugin.)
  
 +=item B<MaxReadInterval> I<Seconds>
 +
 +Read plugin doubles interval between queries after each failed attempt
 +to get data.
 +
 +This options limits the maximum value of the interval. The default value is
 +B<86400>.
 +
  =item B<Timeout> I<Iterations>
  
  Consider a value list "missing" when no update has been read or received for
@@@ -302,11 -267,8 +302,11 @@@ If B<WriteQueueLimitHigh> is set to non
  unset, the latter will default to half of B<WriteQueueLimitHigh>.
  
  If you do not want to randomly drop values when the queue size is between
 -I<LowNum> and I<HighNum>, set If B<WriteQueueLimitHigh> and
 -B<WriteQueueLimitLow> to same value.
 +I<LowNum> and I<HighNum>, set B<WriteQueueLimitHigh> and B<WriteQueueLimitLow>
 +to the same value.
 +
 +Enabling the B<CollectInternalStats> option is of great help to figure out the
 +values to set B<WriteQueueLimitHigh> and B<WriteQueueLimitLow> to.
  
  =item B<Hostname> I<Name>
  
@@@ -384,10 -346,10 +384,10 @@@ The full example configuration looks li
     <Aggregation>
       Plugin "cpu"
       Type "cpu"
 -     
 +
       GroupBy "Host"
       GroupBy "TypeInstance"
 -     
 +
       CalculateSum true
       CalculateAverage true
     </Aggregation>
@@@ -463,13 -425,13 +463,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>
@@@ -533,7 -495,6 +533,7 @@@ possibly filtering or messages
   #   ExchangeType "fanout"
   #   RoutingKey "collectd"
   #   Persistent false
 + #   ConnectionRetryDelay 0
   #   Format "command"
   #   StoreRates false
   #   GraphitePrefix "collectd."
       Exchange "amq.fanout"
   #   ExchangeType "fanout"
   #   Queue "queue_name"
 + #   QueueDurable false
 + #   QueueAutoDelete true
   #   RoutingKey "collectd.#"
 + #   ConnectionRetryDelay 0
     </Subscribe>
   </Plugin>
  
@@@ -607,23 -565,9 +607,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
@@@ -646,13 -590,6 +646,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
@@@ -789,18 -726,6 +789,18 @@@ 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<SSLCiphers> I<list of ciphers>
 +
 +Specifies which ciphers to use in the connection. The list of ciphers
 +must specify valid ciphers. See
 +L<http://www.openssl.org/docs/apps/ciphers.html> for details.
 +
 +=item B<Timeout> I<Milliseconds>
 +
 +The B<Timeout> option sets the overall timeout for HTTP requests to B<URL>, in
 +milliseconds. By default, the configured B<Interval> is used to set the
 +timeout.
 +
  =back
  
  =head2 Plugin C<apcups>
@@@ -889,204 -814,6 +889,204 @@@ 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<Timeout> I<Milliseconds>
 +
 +The B<Timeout> option sets the overall timeout for HTTP requests to B<URL>, in
 +milliseconds. By default, the configured B<Interval> is used to set the
 +timeout.
 +
 +=back
 +
 +=head2 Plugin C<barometer>
 +
 +This plugin reads absolute air pressure using digital barometer sensor on a I2C
 +bus. Supported sensors are:
 +
 +=over 5
 +
 +=item I<MPL115A2> from Freescale,
 +see L<http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPL115A>.
 +
 +
 +=item I<MPL3115> from Freescale
 +see L<http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPL3115A2>.
 +
 +
 +=item I<BMP085> from Bosch Sensortec
 +
 +=back
 +
 +The sensor type - one of the above - is detected automatically by the plugin
 +and indicated in the plugin_instance (you will see subdirectory
 +"barometer-mpl115" or "barometer-mpl3115", or "barometer-bmp085"). The order of
 +detection is BMP085 -> MPL3115 -> MPL115A2, the first one found will be used
 +(only one sensor can be used by the plugin).
 +
 +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 (depending
 +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>
 +
 +The only mandatory configuration parameter.
 +
 +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>
 +
 +Optional parameter controlling the oversampling/accuracy. Default value
 +is 1 providing fastest and least accurate reading.
 +
 +For I<MPL115> this is the size of the averaging window. To filter out sensor
 +noise a simple averaging using floating window of this 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 I<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.
 +
 +For I<BMP085> 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. Any other value is adjusted by the plugin to
 +the closest supported one.
 +
 +=item B<PressureOffset> I<offset>
 +
 +Optional parameter for MPL3115 only.
 +
 +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>
 +
 +Optional parameter for MPL3115 only.
 +
 +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>
 +
 +Optional parameter, default value is 0.
 +
 +Normalization method - what approximation/model is used to compute the 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 pressure 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
 +L<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 L<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(s) which should be used as a reference when normalizing the
 +pressure using C<Normalization> method 2.
 +When specified more sensors a minumum is found and used 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<battery>
 +
 +The I<battery plugin> reports the remaining capacity, power and voltage of
 +laptop batteries.
 +
 +=over 4
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +When enabled, remaining capacity is reported as a percentage, e.g. "42%
 +capacity remaining". Otherwise the capacity is stored as reported by the
 +battery, most likely in "Wh". This option does not work with all input methods,
 +in particular when only C</proc/pmu> is available on an old Linux system.
 +Defaults to B<false>.
 +
 +=item B<ReportDegraded> B<false>|B<true>
 +
 +Typical laptop batteries degrade over time, meaning the capacity decreases with
 +recharge cycles. The maximum charge of the previous charge cycle is tracked as
 +"last full capacity" and used to determine that a battery is "fully charged".
 +
 +When this option is set to B<false>, the default, the I<battery plugin> will
 +only report the remaining capacity. If the B<ValuesPercentage> option is
 +enabled, the relative remaining capacity is calculated as the ratio of the
 +"remaining capacity" and the "last full capacity". This is what most tools,
 +such as the status bar of desktop environments, also do.
 +
 +When set to B<true>, the battery plugin will report three values: B<charged>
 +(remaining capacity), B<discharged> (difference between "last full capacity"
 +and "remaining capacity") and B<degraded> (difference between "design capacity"
 +and "last full capacity").
 +
  =back
  
  =head2 Plugin C<bind>
@@@ -1115,17 -842,17 +1115,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>
@@@ -1192,12 -919,6 +1192,12 @@@ Collect global memory statistics
  
  Default: Enabled.
  
 +=item B<Timeout> I<Milliseconds>
 +
 +The B<Timeout> option sets the overall timeout for HTTP requests to B<URL>, in
 +milliseconds. By default, the configured B<Interval> is used to set the
 +timeout.
 +
  =item B<View> I<Name>
  
  Collect statistics about a specific I<"view">. BIND can behave different,
@@@ -1249,74 -970,6 +1249,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
@@@ -1340,68 -993,6 +1340,68 @@@ 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. By default, CPU usage is reported
 +as Jiffies, using the C<cpu> type. Two aggregations are available:
 +
 +=over 4
 +
 +=item
 +
 +Sum, per-state, over all CPUs installed in the system; and
 +
 +=item
 +
 +Sum, per-CPU, over all non-idle states of a CPU, creating an "active" state.
 +
 +=back
 +
 +The two aggregations can be combined, leading to I<collectd> only emitting a
 +single "active" metric for the entire system. As soon as one of these
 +aggregations (or both) is enabled, the I<cpu plugin> will report a percentage,
 +rather than Jiffies. In addition, you can request individual, per-state,
 +per-CPU metrics to be reported as percentage.
 +
 +The following configuration options are available:
 +
 +=over 4
 +
 +=item B<ReportByState> B<true>|B<false>
 +
 +When set to B<true>, the default, reports per-state metrics, e.g. "system",
 +"user" and "idle".
 +When set to B<false>, aggregates (sums) all I<non-idle> states into one
 +"active" metric.
 +
 +=item B<ReportByCpu> B<true>|B<false>
 +
 +When set to B<true>, the default, reports per-CPU (per-core) metrics.
 +When set to B<false>, instead of reporting metrics for individual CPUs, only a
 +global sum of CPU states is emitted.
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +This option is only considered when both, B<ReportByCpu> and B<ReportByState>
 +are set to B<true>. In this case, by default, metrics will be reported as
 +Jiffies. By setting this option to B<true>, you can request percentage values
 +in the un-aggregated (per-CPU, per-state) mode as well.
 +
 +=back
 +
  =head2 Plugin C<cpufreq>
  
  This plugin doesn't have any options. It reads
@@@ -1444,16 -1035,6 +1444,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"
@@@ -1485,10 -1066,6 +1485,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
@@@ -1526,35 -1103,13 +1526,35 @@@ 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.
  
 +Beware that requests will get aborted if they take too long to complete. Adjust
 +B<Timeout> accordingly if you expect B<MeasureResponseTime> to report such slow
 +requests.
 +
 +=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.
 +
 +=item B<Timeout> I<Milliseconds>
 +
 +The B<Timeout> option sets the overall timeout for HTTP requests to B<URL>, in
 +milliseconds. By default, the configured B<Interval> is used to set the
 +timeout. Prior to version 5.5.0, there was no timeout and requests could hang
 +indefinitely. This legacy behaviour can be achieved by setting the value of
 +B<Timeout> to 0.
 +
 +If B<Timeout> is 0 or bigger than the B<Interval>, keep in mind that each slow
 +network connection will stall one read thread. Adjust the B<ReadThreads> global
 +setting accordingly to prevent this from blocking other plugins.
  
  =back
  
@@@ -1621,29 -1176,14 +1621,29 @@@ 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>
  
 +=item B<Timeout> I<Milliseconds>
 +
  These options behave exactly equivalent to the appropriate options of the
  I<cURL> plugin. Please see there for a detailed description.
  
@@@ -1679,8 -1219,6 +1679,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"
@@@ -1732,8 -1270,6 +1732,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>
  
  =item B<Post> I<Body>
  
 +=item B<Timeout> I<Milliseconds>
 +
  These options behave exactly equivalent to the appropriate options of the
  I<cURL plugin>. Please see there for a detailed description.
  
@@@ -1975,16 -1509,6 +1975,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
@@@ -2099,17 -1623,17 +2099,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
  
@@@ -2145,20 -1669,6 +2145,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>
@@@ -2279,27 -1789,6 +2279,27 @@@ expected from them. This is documented 
  
  =back
  
 +=head2 Plugin C<fhcount>
 +
 +The C<fhcount> plugin provides statistics about used, unused and total number of
 +file handles on Linux.
 +
 +The I<fhcount plugin> provides the following configuration options:
 +
 +=over 4
 +
 +=item B<ValuesAbsolute> B<true>|B<false>
 +
 +Enables or disables reporting of file handles usage in absolute numbers,
 +e.g. file handles used. Defaults to B<true>.
 +
 +=item B<ValuesPercentage> B<false>|B<true>
 +
 +Enables or disables reporting of file handles usage in percentages, e.g.
 +percent of file handles used. Defaults to B<false>.
 +
 +=back
 +
  =head2 Plugin C<filecount>
  
  The C<filecount> plugin counts the number of files in a certain directory (and
@@@ -2553,9 -2042,13 +2553,13 @@@ a notification is sent
  
  =item B<Chain> I<Table> I<Chain> [I<Comment|Number> [I<Name>]]
  
- Select the rules to count. If only I<Table> and I<Chain> are given, this plugin
- will collect the counters of all rules which have a comment-match. The comment
- is then used as type-instance.
+ =item B<Chain6> I<Table> I<Chain> [I<Comment|Number> [I<Name>]]
+ Select the iptables/ip6tables filter rules to count packets and bytes from.
+ If only I<Table> and I<Chain> are given, this plugin will collect the counters
+ of all rules which have a comment-match. The comment is then used as
+ type-instance.
  
  If I<Comment> or I<Number> is given, only the rule with the matching comment or
  the I<n>th rule will be collected. Again, the comment (or the number) will be
@@@ -2643,63 -2136,94 +2647,63 @@@ independent from the I<JavaClass> argum
  
  =back
  
 -=head2 Plugin C<libvirt>
 +=head2 Plugin C<load>
  
 -This plugin allows CPU, disk and network load to be collected for virtualized
 -guests on the machine. This means that these characteristics can be collected
 -for guest systems without installing any software on them - collectd only runs
 -on the hosting system. The statistics are collected through libvirt
 -(L<http://libvirt.org/>).
 +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.
  
 -Only I<Connection> is required.
 +The following configuration options are available:
  
  =over 4
  
 -=item B<Connection> I<uri>
 -
 -Connect to the hypervisor given by I<uri>. For example if using Xen use:
 +=item B<ReportRelative> B<false>|B<true>
  
 - Connection "xen:///"
 +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.
  
 -Details which URIs allowed are given at L<http://libvirt.org/uri.html>.
 +=back
  
 -=item B<RefreshInterval> I<seconds>
  
 -Refresh the list of domains and devices every I<seconds>. The default is 60
 -seconds. Setting this to be the same or smaller than the I<Interval> will cause
 -the list of domains and devices to be refreshed on every iteration.
 +=head2 Plugin C<logfile>
  
 -Refreshing the devices in particular is quite a costly operation, so if your
 -virtualization setup is static you might consider increasing this. If this
 -option is set to 0, refreshing is disabled completely.
 +=over 4
  
 -=item B<Domain> I<name>
 +=item B<LogLevel> B<debug|info|notice|warning|err>
  
 -=item B<BlockDevice> I<name:dev>
 +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.
  
 -=item B<InterfaceDevice> I<name:dev>
 +Please note that B<debug> is only available if collectd has been compiled with
 +debugging support.
  
 -=item B<IgnoreSelected> I<true>|I<false>
 +=item B<File> I<File>
  
 -Select which domains and devices are collected.
 -
 -If I<IgnoreSelected> is not given or I<false> then only the listed domains and
 -disk/network devices are collected.
 -
 -If I<IgnoreSelected> is I<true> then the test is reversed and the listed
 -domains and disk/network devices are ignored, while the rest are collected.
 -
 -The domain name and device names may use a regular expression, if the name is
 -surrounded by I</.../> and collectd was compiled with support for regexps.
 -
 -The default is to collect statistics for all domains and all their devices.
 -
 -Example:
 -
 - BlockDevice "/:hdb/"
 - IgnoreSelected "true"
 -
 -Ignore all I<hdb> devices on any domain, but other block devices (eg. I<hda>)
 -will be collected.
 -
 -=item B<HostnameFormat> B<name|uuid|hostname|...>
 -
 -When the libvirt 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>.
 +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.
  
 -B<uuid> means use the guest's UUID. This is useful if you want to track the
 -same guest across migrations.
 +=item B<Timestamp> B<true>|B<false>
  
 -B<hostname> means to use the global B<Hostname> setting, which is probably not
 -useful on its own because all guests will appear to have the same name.
 +Prefix all lines printed by the current time. Defaults to B<true>.
  
 -You can also specify combinations of these fields. For example B<name uuid>
 -means to concatenate the guest name and UUID (with a literal colon character
 -between, thus I<"foo:1234-1234-1234-1234">).
 +=item B<PrintSeverity> B<true>|B<false>
  
 -=item B<InterfaceFormat> B<name>|B<address>
 +When enabled, all lines are prefixed by the severity of the log message, for
 +example "warning". Defaults to B<false>.
  
 -When the libvirt 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>.
 +=back
  
 -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.
 +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.
  
 -=back
 +=head2 Plugin C<log_logstash>
  
 -=head2 Plugin C<logfile>
 +The I<log logstash plugin> behaves like the logfile plugin but formats
 +messages as JSON events for logstash to parse and input.
  
  =over 4
  
@@@ -2718,6 -2242,15 +2722,6 @@@ B<stderr> can be used to write to the s
  channels, respectively. This, of course, only makes much sense when I<collectd>
  is running in foreground- or non-daemon-mode.
  
 -=item B<Timestamp> B<true>|B<false>
 -
 -Prefix all lines printed by the current time. Defaults to B<true>.
 -
 -=item B<PrintSeverity> B<true>|B<false>
 -
 -When enabled, all lines are prefixed by the severity of the log message, for
 -example "warning". Defaults to B<false>.
 -
  =back
  
  B<Note>: There is no need to notify the daemon after moving or removing the
@@@ -2897,7 -2430,7 +2901,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>
  
@@@ -2963,7 -2496,7 +2967,7 @@@ Fan I
  
  =item fout
  
 -Fan Out 
 +Fan Out
  
  =item vccp
  
@@@ -3004,11 -2537,11 +3008,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
  
@@@ -3016,61 -2549,40 +3020,61 @@@ 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>
  
 -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).
  
@@@ -3079,32 -2591,22 +3083,32 @@@ 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"
     Interval 60
 -   
 +
     <Slave 1>
       Instance "power-supply"
       Collect  "voltage-input-1"
     </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
@@@ -3146,11 -2637,6 +3150,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
@@@ -3176,25 -2662,15 +3180,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>
  
@@@ -3203,7 -2679,7 +3207,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.
  
@@@ -3261,11 -2737,9 +3265,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
@@@ -3280,11 -2754,6 +3284,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>.
@@@ -3323,11 -2792,6 +3327,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>
@@@ -3341,10 -2805,6 +3345,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. Defaults to B<false>.
  
 +=item B<ConnectTimeout> I<Seconds>
 +
 +Sets the connect timeout for the MySQL client.
 +
  =back
  
  =head2 Plugin C<netapp>
@@@ -3379,7 -2839,7 +3383,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
@@@ -3981,7 -3441,7 +3985,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">
@@@ -4044,12 -3504,6 +4048,12 @@@ behavior is to let the kernel choose th
  that the manual selection of an interface for unicast traffic is only
  necessary in rare cases.
  
 +=item B<ResolveInterval> I<Seconds>
 +
 +Sets the interval at which to re-resolve the DNS for the I<Host>. This is
 +useful to force a regular DNS lookup to support a high availability setup. If
 +not specified, re-resolves are never attempted.
 +
  =back
  
  =item B<E<lt>Listen> I<Host> [I<Port>]B<E<gt>>
@@@ -4194,12 -3648,6 +4198,12 @@@ 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<Timeout> I<Milliseconds>
 +
 +The B<Timeout> option sets the overall timeout for HTTP requests to B<URL>, in
 +milliseconds. By default, the configured B<Interval> is used to set the
 +timeout.
 +
  =back
  
  =head2 Plugin C<notify_desktop>
@@@ -4382,36 -3830,13 +4386,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>
@@@ -4432,23 -3857,14 +4436,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
@@@ -4456,8 -3872,6 +4460,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
@@@ -4476,70 -3890,6 +4480,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
@@@ -5200,10 -4550,6 +5204,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
@@@ -5229,13 -4575,6 +5233,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
@@@ -5575,10 -4914,6 +5579,10 @@@ which configures the connection paramet
          Host "localhost"
          Port "6379"
          Timeout 2000
 +        <Query "LLEN myqueue">
 +          Type "queue_length"
 +          Instance "myqueue"
 +        <Query>
      </Node>
    </Plugin>
  
@@@ -5616,22 -4951,6 +5620,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>
@@@ -5973,40 -5292,6 +5977,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
@@@ -6097,19 -5382,6 +6101,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>
@@@ -6245,7 -5517,6 +6249,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"
@@@ -6272,9 -5543,6 +6276,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:
  
@@@ -6330,8 -5598,6 +6334,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>
@@@ -6340,8 -5606,6 +6344,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>
@@@ -6561,11 -5825,6 +6565,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>
@@@ -6623,79 -5882,6 +6627,79 @@@ Default: B<1978
  
  =back
  
 +=head2 Plugin C<turbostat>
 +
 +The I<Turbostat plugin> reads CPU frequency and C-state residency on modern
 +Intel processors by using the new Model Specific Registers.
 +
 +=over 4
 +
 +=item B<CoreCstates> I<Bitmask(Integer)>
 +
 +Bitmask of the list of core C states supported by the processor.
 +This option should only be used if the automated detection fails.
 +Default value extracted from the cpu model and family.
 +
 +Currently supported C-states (by this plugin): 3, 6, 7
 +
 +Example: (1<<3)+(1<<6)+(1<<7) = 392 for all states
 +
 +=item B<PackageCstates> I<Bitmask(Integer)>
 +
 +Bitmask of the list of pacages C states supported by the processor.
 +This option should only be used if the automated detection fails.
 +Default value extracted from the cpu model and family.
 +
 +Currently supported C-states (by this plugin): 2, 3, 6, 7, 8, 9, 10
 +
 +Example: (1<<2)+(1<<3)+(1<<6)+(1<<7) = 396 for states 2, 3, 6 and 7
 +
 +=item B<SystemManagementInterrupt> I<true>|I<false>
 +
 +Boolean enabling the collection of the I/O System-Management Interrupt
 +counter'. This option should only be used if the automated detection
 +fails or if you want to disable this feature.
 +
 +=item B<DigitalTemperatureSensor> I<true>|I<false>
 +
 +Boolean enabling the collection of the temperature of each core.
 +This option should only be used if the automated detectionfails or 
 +if you want to disable this feature.
 +
 +=item B<DigitalTemperatureSensor> I<true>|I<false>
 +
 +Boolean enabling the collection of the temperature of each package.
 +This option should only be used if the automated detectionfails or 
 +if you want to disable this feature.
 +
 +=item B<TCCActivationTemp> I<Temperature>
 +
 +Thermal Control Circuit Activation Temperature of the installed
 +CPU. This temperature is used when collecting the temperature of
 +cores or packages. This option should only be used if the automated
 +detection fails. Default value extracted from B<MSR_IA32_TEMPERATURE_TARGET>
 +
 +=item B<RunningAveragePowerLimit> I<Bitmask(Integer)>
 +
 +Bitmask of the list of elements to be thermally monitored. This option
 +should only be used if the automated detection fails or if you want to
 +disable some collections. The different bits of this bitmask accepted
 +by this plugin are:
 +
 +=over 4
 +
 +=item 0 ('1'): Package
 +
 +=item 1 ('2'): DRAM
 +
 +=item 2 ('4'): Cores
 +
 +=item 3 ('8'): Embedded graphic device
 +
 +=back
 +
 +=back
 +
  =head2 Plugin C<unixsock>
  
  =over 4
@@@ -6768,35 -5954,22 +6772,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>
@@@ -6810,29 -5983,34 +6814,29 @@@ 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<CollectDirectorDNS> B<true>|B<false>
 +=item B<CollectCache> B<true>|B<false>
  
 -DNS director lookup cache statistics. Only available with Varnish 3.x. False by
 -default.
 +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>
 +
 +DNS director lookup cache statistics. Only available with Varnish 3.x. False by
 +default.
  
  =item B<CollectESI> B<true>|B<false>
  
@@@ -6861,14 -6039,7 +6865,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>
  
@@@ -6899,126 -6070,18 +6903,126 @@@ 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.
  
  =back
  
 +=head2 Plugin C<virt>
 +
 +This plugin allows CPU, disk and network load to be collected for virtualized
 +guests on the machine. This means that these metrics can be collected for guest
 +systems without installing any software on them - I<collectd> only runs on the
 +host system. The statistics are collected through libvirt
 +(L<http://libvirt.org/>).
 +
 +Only I<Connection> is required.
 +
 +=over 4
 +
 +=item B<Connection> I<uri>
 +
 +Connect to the hypervisor given by I<uri>. For example if using Xen use:
 +
 + Connection "xen:///"
 +
 +Details which URIs allowed are given at L<http://libvirt.org/uri.html>.
 +
 +=item B<RefreshInterval> I<seconds>
 +
 +Refresh the list of domains and devices every I<seconds>. The default is 60
 +seconds. Setting this to be the same or smaller than the I<Interval> will cause
 +the list of domains and devices to be refreshed on every iteration.
 +
 +Refreshing the devices in particular is quite a costly operation, so if your
 +virtualization setup is static you might consider increasing this. If this
 +option is set to 0, refreshing is disabled completely.
 +
 +=item B<Domain> I<name>
 +
 +=item B<BlockDevice> I<name:dev>
 +
 +=item B<InterfaceDevice> I<name:dev>
 +
 +=item B<IgnoreSelected> B<true>|B<false>
 +
 +Select which domains and devices are collected.
 +
 +If I<IgnoreSelected> is not given or B<false> then only the listed domains and
 +disk/network devices are collected.
 +
 +If I<IgnoreSelected> is B<true> then the test is reversed and the listed
 +domains and disk/network devices are ignored, while the rest are collected.
 +
 +The domain name and device names may use a regular expression, if the name is
 +surrounded by I</.../> and collectd was compiled with support for regexps.
 +
 +The default is to collect statistics for all domains and all their devices.
 +
 +Example:
 +
 + BlockDevice "/:hdb/"
 + IgnoreSelected "true"
 +
 +Ignore all I<hdb> devices on any domain, but other block devices (eg. I<hda>)
 +will be collected.
 +
 +=item B<HostnameFormat> B<name|uuid|hostname|...>
 +
 +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>.
 +
 +B<uuid> means use the guest's UUID. This is useful if you want to track the
 +same guest across migrations.
 +
 +B<hostname> means to use the global B<Hostname> setting, which is probably not
 +useful on its own because all guests will appear to have the same name.
 +
 +You can also specify combinations of these fields. For example B<name uuid>
 +means to concatenate the guest name and UUID (with a literal colon character
 +between, thus I<"foo:1234-1234-1234-1234">).
 +
 +At the moment of writing (collectd-5.5), hostname string is limited to 62
 +characters. In case when combination of fields exceeds 62 characters,
 +hostname will be truncated without a warning.
 +
 +=item B<InterfaceFormat> B<name>|B<address>
 +
 +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>.
 +
 +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 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>.
 +
 +B<uuid> means use the guest's UUID.
 +
 +You can also specify combinations of these fields. For example B<name uuid>
 +means to concatenate the guest name and UUID (with a literal colon character
 +between, thus I<"foo:1234-1234-1234-1234">).
 +
 +=back
 +
  =head2 Plugin C<vmem>
  
  The C<vmem> plugin collects information about the usage of virtual memory.
@@@ -7135,59 -6198,6 +7139,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
@@@ -7243,31 -6253,25 +7247,31 @@@ 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
 -have one B<URL> block, within which the destination can be configured further,
 -for example by specifying authentication data.
 +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)>.
  
  Synopsis:
  
   <Plugin "write_http">
 -   <URL "http://example.com/post-collectd">
 +   <Node "example">
 +     URL "http://example.com/post-collectd"
       User "collectd"
       Password "weCh3ik0"
 -   </URL>
 +     Format JSON
 +   </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.
@@@ -7295,33 -6299,6 +7299,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
@@@ -7333,143 -6310,8 +7337,143 @@@ 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>.
 +
 +=item B<LowSpeedLimit> I<Bytes per Second>
 +
 +Sets the minimal transfer rate in I<Bytes per Second> below which the
 +connection with the HTTP server will be considered too slow and aborted. All
 +the data submitted over this connection will probably be lost. Defaults to 0,
 +which means no minimum transfer rate is enforced.
 +
 +=item B<Timeout> I<Timeout>
 +
 +Sets the maximum time in milliseconds given for HTTP POST operations to
 +complete. When this limit is reached, the POST operation will be aborted, and
 +all the data in the current send buffer will probably be lost. Defaults to 0,
 +which means the connection never times out.
 +
 +The C<write_http> plugin regularly submits the collected values to the HTTP
 +server. How frequently this happens depends on how much data you are collecting
 +and the size of B<BufferSize>. The optimal value to set B<Timeout> to is
 +slightly below this interval, which you can estimate by monitoring the network
 +traffic between collectd and the HTTP server.
 +
 +=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
  
@@@ -7489,7 -6331,7 +7493,7 @@@ Synopsis
  
  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
 +C<ZRANGEBYSCORE> I<Redis> command. Additionally, 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
@@@ -7507,9 -6349,9 +7511,9 @@@ options are available
  =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
 +instance running on a specified host and port. The node name is a
  canonical identifier which is used as I<plugin instance>. It is limited to
 -64E<nbsp>characters in length.
 +51E<nbsp>characters in length.
  
  =item B<Host> I<Hostname>
  
@@@ -7530,7 -6372,7 +7534,7 @@@ The B<Timeout> option sets the socket c
  
  =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.
  
@@@ -7546,7 -6388,6 +7550,7 @@@ Synopsis
       TTLFactor 2.0
     </Node>
     Tag "foobar"
 +   Attribute "foo" "bar"
   </Plugin>
  
  The following options are understood by the I<write_riemann plugin>:
@@@ -7573,26 -6414,7 +7577,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>
  
@@@ -7619,23 -6441,6 +7623,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
 +
 +=head2 Plugin C<write_sensu>
 +
 +The I<write_sensu plugin> will send values to I<Sensu>, a powerful stream
 +aggregation and monitoring system. The plugin sends I<JSON> encoded data to
 +a local I<Sensu> client using a TCP socket.
 +
 +At the moment, the I<write_sensu plugin> does not send over a collectd_host
 +parameter so it is not possible to use one collectd instance as a gateway for
 +others. Each collectd host must pair with one I<Sensu> client.
 +
 +Synopsis:
 +
 + <Plugin "write_sensu">
 +   <Node "example">
 +     Host "localhost"
 +     Port "3030"
 +     StoreRates true
 +     AlwaysAppendDS false
 +     MetricHandler "influx"
 +     MetricHandler "default"
 +     NotificationHandler "flapjack"
 +     NotificationHandler "howling_monkey"
 +     Notifications true
 +   </Node>
 +   Tag "foobar"
 +   Attribute "foo" "bar"
 + </Plugin>
 +
 +The following options are understood by the I<write_sensu plugin>:
 +
 +=over 4
 +
 +=item E<lt>B<Node> I<Name>E<gt>
 +
 +The plugin's configuration consists of one or more B<Node> blocks. Each block
 +is given a unique I<Name> and specifies one connection to an instance of
 +I<Sensu>. Inside the B<Node> block, the following per-connection options are
 +understood:
 +
 +=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<3030>.
 +
 +=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<collectd_data_source_type> tag: If
 +B<StoreRates> is enabled, converted values will have "rate" appended to the
 +data source type, e.g.  C<collectd_data_source_type:derive:rate>.
 +
 +=item B<AlwaysAppendDS> B<false>|B<true>
 +
 +If set the B<true>, append the name of the I<Data Source> (DS) to the
 +"service", i.e. the field that, together with the "host" field, uniquely
 +identifies a metric in I<Sensu>. If set to B<false> (the default), this is
 +only done when there is more than one DS.
 +
 +=item B<Notifications> B<false>|B<true>
 +
 +If set to B<true>, create I<Sensu> events for notifications. This is B<false>
 +by default. At least one of B<Notifications> or B<Metrics> should be enabled.
 +
 +=item B<Metrics> B<false>|B<true>
 +
 +If set to B<true>, create I<Sensu> events for metrics. This is B<false>
 +by default. At least one of B<Notifications> or B<Metrics> should be enabled.
 +
 +
 +=item B<Separator> I<String>
 +
 +Sets the separator for I<Sensu> metrics name or checks. Defaults to "/".
 +
 +=item B<MetricHandler> I<String>
 +
 +Add a handler that will be set when metrics are sent to I<Sensu>. You can add
 +several of them, one per line. Defaults to no handler.
 +
 +=item B<NotificationHandler> I<String>
 +
 +Add a handler that will be set when notifications are sent to I<Sensu>. You can
 +add several of them, one per line. Defaults to no handler.
 +
 +=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<Sensu>.
 +
 +=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<Sensu>.
 +
 +=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
@@@ -8454,7 -7119,7 +8458,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
@@@ -8636,7 -7301,7 +8640,7 @@@ Example
   <Target "replace">
     # Replace "example.net" with "example.com"
     Host "\\<example.net\\>" "example.com"
 - 
 +
     # Strip "www." from hostnames
     Host "\\<www\\." ""
   </Target>
@@@ -8719,6 -7384,6 +8723,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_json.c
@@@ -71,14 -71,11 +71,14 @@@ struct cj_s /* {{{ *
    char *user;
    char *pass;
    char *credentials;
 +  _Bool digest;
    _Bool verify_peer;
    _Bool verify_host;
    char *cacert;
    struct curl_slist *headers;
    char *post_body;
 +  cdtime_t interval;
 +  int timeout;
  
    CURL *curl;
    char curl_errbuf[CURL_ERROR_SIZE];
@@@ -132,17 -129,11 +132,11 @@@ static size_t cj_curl_callback (void *b
      return (len);
  #endif
  
-   if (status != yajl_status_ok)
-   {
-     unsigned char *msg =
-       yajl_get_error(db->yajl, /* verbose = */ 1,
-           /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
-     ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
-     yajl_free_error(db->yajl, msg);
-     return (0); /* abort write callback */
-   }
-   return (len);
+   unsigned char *msg = yajl_get_error(db->yajl, /* verbose = */ 1,
+         /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
+   ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
+   yajl_free_error(db->yajl, msg);
+   return (0); /* abort write callback */
  } /* }}} size_t cj_curl_callback */
  
  static int cj_get_type (cj_key_t *key)
@@@ -232,7 -223,7 +226,7 @@@ static int cj_cb_number (void *ctx
    buffer[sizeof (buffer) - 1] = 0;
  
    if ((key == NULL) || !CJ_IS_KEY (key)) {
 -    if (key != NULL)
 +    if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/)
        NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects"
                " a map.", buffer);
      cj_cb_inc_array_index (ctx, /* update_key = */ 1);
@@@ -603,19 -594,13 +597,19 @@@ static int cj_init_curl (cj_t *db) /* {
    curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cj_curl_callback);
    curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db);
 -  curl_easy_setopt (db->curl, CURLOPT_USERAGENT,
 -                    PACKAGE_NAME"/"PACKAGE_VERSION);
 +  curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
    curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf);
    curl_easy_setopt (db->curl, CURLOPT_URL, db->url);
 +  curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L);
 +  curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L);
  
    if (db->user != NULL)
    {
 +#ifdef HAVE_CURLOPT_USERNAME
 +    curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user);
 +    curl_easy_setopt (db->curl, CURLOPT_PASSWORD,
 +        (db->pass == NULL) ? "" : db->pass);
 +#else
      size_t credentials_size;
  
      credentials_size = strlen (db->user) + 2;
      ssnprintf (db->credentials, credentials_size, "%s:%s",
                 db->user, (db->pass == NULL) ? "" : db->pass);
      curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials);
 +#endif
 +
 +    if (db->digest)
 +      curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
    }
  
    curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer);
    if (db->post_body != NULL)
      curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body);
  
 +#ifdef HAVE_CURLOPT_TIMEOUT_MS
 +  if (db->timeout >= 0)
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout);
 +  else if (db->interval > 0)
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
 +        CDTIME_T_TO_MS(db->timeout));
 +  else
 +    curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
 +        CDTIME_T_TO_MS(plugin_get_interval()));
 +#endif
 +
    return (0);
  } /* }}} int cj_init_curl */
  
@@@ -684,8 -654,6 +678,8 @@@ static int cj_config_add_url (oconfig_i
    }
    memset (db, 0, sizeof (*db));
  
 +  db->timeout = -1;
 +
    if (strcasecmp ("URL", ci->key) == 0)
      status = cf_util_get_string (ci, &db->url);
    else if (strcasecmp ("Sock", ci->key) == 0)
        status = cf_util_get_string (child, &db->user);
      else if (db->url && strcasecmp ("Password", child->key) == 0)
        status = cf_util_get_string (child, &db->pass);
 +    else if (strcasecmp ("Digest", child->key) == 0)
 +      status = cf_util_get_boolean (child, &db->digest);
      else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0)
        status = cf_util_get_boolean (child, &db->verify_peer);
      else if (db->url && strcasecmp ("VerifyHost", child->key) == 0)
        status = cf_util_get_string (child, &db->post_body);
      else if (strcasecmp ("Key", child->key) == 0)
        status = cj_config_add_key (db, child);
 +    else if (strcasecmp ("Interval", child->key) == 0)
 +      status = cf_util_get_cdtime(child, &db->interval);
 +    else if (strcasecmp ("Timeout", child->key) == 0)
 +      status = cf_util_get_int (child, &db->timeout);
      else
      {
        WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);
    {
      user_data_t ud;
      char *cb_name;
 +    struct timespec interval = { 0, 0 };
 +
 +    CDTIME_T_TO_TIMESPEC (db->interval, &interval);
  
      if (db->instance == NULL)
        db->instance = strdup("default");
      cb_name = ssnprintf_alloc ("curl_json-%s-%s",
                 db->instance, db->url ? db->url : db->sock);
  
 -    plugin_register_complex_read (/* group = */ "curl_json", cb_name, cj_read,
 -                                  /* interval = */ NULL, &ud);
 +    plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
 +                                  /* interval = */ (db->interval > 0) ? &interval : NULL,
 +                                  &ud);
      sfree (cb_name);
    }
    else
@@@ -851,10 -809,11 +845,10 @@@ static void cj_submit (cj_t *db, cj_key
  
    if (key->instance == NULL)
    {
 -    if ((db->depth == 0) || (strcmp ("", db->state[db->depth-1].name) == 0))
 -      sstrncpy (vl.type_instance, db->state[db->depth].name, sizeof (vl.type_instance));
 -    else
 -      ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
 -          db->state[db->depth-1].name, db->state[db->depth].name);
 +    int i, len = 0;
 +    for (i = 0; i < db->depth; i++)
 +      len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len,
 +                       i ? "-%s" : "%s", db->state[i+1].name);
    }
    else
      sstrncpy (vl.type_instance, key->instance, sizeof (vl.type_instance));
    sstrncpy (vl.plugin_instance, db->instance, sizeof (vl.plugin_instance));
    sstrncpy (vl.type, key->type, sizeof (vl.type));
  
 +  if (db->interval > 0)
 +    vl.interval = db->interval;
 +
    plugin_dispatch_values (&vl);
  } /* }}} int cj_submit */
  
diff --combined src/email.c
@@@ -2,25 -2,20 +2,25 @@@
   * collectd - src/email.c
   * Copyright (C) 2006-2008  Sebastian Harl
   *
 - * 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.
   *
 - * Author:
 + * Authors:
   *   Sebastian Harl <sh at tokkee.org>
   **/
  
@@@ -539,7 -534,7 +539,7 @@@ static void *open_connection (void __at
                }
  
                connection = malloc (sizeof (*connection));
-               if (connection != NULL)
+               if (connection == NULL)
                {
                        close (remote);
                        continue;
@@@ -1,7 -1,6 +1,7 @@@
  /**
   * collectd - src/libcollectdclient/network.c
 - * Copyright (C) 2005-2012  Florian octo Forster
 + * Copyright (C) 2005-2015  Florian Forster
 + * Copyright (C) 2010       Max Henkel
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
@@@ -22,8 -21,7 +22,8 @@@
   * DEALINGS IN THE SOFTWARE.
   *
   * Authors:
 - *   Florian octo Forster <octo at collectd.org>
 + *   Florian Forster <octo at collectd.org>
 + *   Max Henkel <henkel at gmx.at>
   **/
  
  #include "collectd.h"
  # include <netinet/in.h>
  #endif
  
 +#if HAVE_NET_IF_H
 +# include <net/if.h>
 +#endif
 +
  #include "collectd/network.h"
  #include "collectd/network_buffer.h"
  
@@@ -89,6 -83,7 +89,7 @@@ static int server_close_socket (lcc_ser
      return (0);
  
    close (srv->fd);
+   srv->fd = -1;
    free (srv->sa);
    srv->sa = NULL;
    srv->sa_len = 0;
@@@ -107,12 -102,6 +108,6 @@@ static void int_server_destroy (lcc_ser
  
    next = srv->next;
  
-   if (srv->fd >= 0)
-   {
-     close (srv->fd);
-     srv->fd = -1;
-   }
    free (srv->node);
    free (srv->service);
    free (srv->username);
@@@ -223,13 -212,7 +218,13 @@@ static int server_send_buffer (lcc_serv
    memset (buffer, 0, sizeof (buffer));
    buffer_size = sizeof (buffer);
  
 -  lcc_network_buffer_finalize (srv->buffer);
 +  status = lcc_network_buffer_finalize (srv->buffer);
 +  if (status != 0)
 +  {
 +    lcc_network_buffer_initialize (srv->buffer);
 +    return (status);
 +  }
 +
    status = lcc_network_buffer_get (srv->buffer, buffer, &buffer_size);
    lcc_network_buffer_initialize (srv->buffer);
  
@@@ -395,81 -378,6 +390,81 @@@ int lcc_server_set_ttl (lcc_server_t *s
    return (0);
  } /* }}} int lcc_server_set_ttl */
  
 +int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ */
 +{
 +  int if_index;
 +  int status;
 +
 +  if ((srv == NULL) || (interface == NULL))
 +    return (EINVAL);
 +
 +  if_index = if_nametoindex (interface);
 +  if (if_index == 0)
 +    return (ENOENT);
 +
 +  /* IPv4 multicast */
 +  if (srv->sa->sa_family == AF_INET)
 +  {
 +    struct sockaddr_in *addr = (struct sockaddr_in *) srv->sa;
 +
 +    if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr)))
 +    {
 +#if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
 +      /* If possible, use the "ip_mreqn" structure which has
 +       * an "interface index" member. Using the interface
 +       * index is preferred here, because of its similarity
 +       * to the way IPv6 handles this. Unfortunately, it
 +       * appears not to be portable. */
 +      struct ip_mreqn mreq;
 +
 +      memset (&mreq, 0, sizeof (mreq));
 +      mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
 +      mreq.imr_address.s_addr = ntohl (INADDR_ANY);
 +      mreq.imr_ifindex = if_index;
 +#else
 +      struct ip_mreq mreq;
 +
 +      memset (&mreq, 0, sizeof (mreq));
 +      mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
 +      mreq.imr_interface.s_addr = ntohl (INADDR_ANY);
 +#endif
 +
 +      status = setsockopt (srv->fd, IPPROTO_IP, IP_MULTICAST_IF,
 +          &mreq, sizeof (mreq));
 +      if (status != 0)
 +        return (status);
 +
 +      return (0);
 +    }
 +  }
 +
 +  /* IPv6 multicast */
 +  if (srv->sa->sa_family == AF_INET6)
 +  {
 +    struct sockaddr_in6 *addr = (struct sockaddr_in6 *) srv->sa;
 +
 +    if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr))
 +    {
 +      status = setsockopt (srv->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
 +          &if_index, sizeof (if_index));
 +      if (status != 0)
 +        return (status);
 +
 +      return (0);
 +    }
 +  }
 +
 +  /* else: Not a multicast interface. */
 +#if defined(SO_BINDTODEVICE)
 +  status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE,
 +      interface, strlen (interface) + 1);
 +  if (status != 0)
 +    return (-1);
 +#endif
 +
 +  return (0);
 +} /* }}} int lcc_server_set_interface */
 +
  int lcc_server_set_security_level (lcc_server_t *srv, /* {{{ */
      lcc_security_level_t level,
      const char *username, const char *password)
diff --combined src/openvpn.c
@@@ -32,7 -32,6 +32,7 @@@
  #define V1STRING "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n"
  #define V2STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)\n"
  #define V3STRING "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes Received Bytes Sent Connected Since Connected Since (time_t)\n"
 +#define V4STRING "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n"
  #define VSSTRING "OpenVPN STATISTICS\n"
  
  
@@@ -44,7 -43,6 +44,7 @@@ struct vpn_status_
                MULTI1 = 1, /* status-version 1 */
                MULTI2,     /* status-version 2 */
                MULTI3,     /* status-version 3 */
 +              MULTI4,     /* status-version 4 */
                SINGLE = 10 /* currently no versions for single mode, maybe in the future */
        } version;
        char *name;
@@@ -450,70 -448,6 +450,70 @@@ static int multi3_read (char *name, FIL
        return (read);
  } /* int multi3_read */
  
 +/* for reading status version 4 */
 +static int multi4_read (char *name, FILE *fh)
 +{
 +      char buffer[1024];
 +      char *fields[11];
 +      const int max_fields = STATIC_ARRAY_SIZE (fields);
 +      int  fields_num, read = 0;
 +      long long sum_users    = 0;
 +
 +      while (fgets (buffer, sizeof (buffer), fh) != NULL)
 +      {
 +              fields_num = openvpn_strsplit (buffer, fields, max_fields);
 +
 +              /* status file is generated by openvpn/multi.c:multi_print_status()
 +               * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
 +               *
 +               * The line we're expecting has 9 fields. We ignore all lines
 +               *  with more or less fields.
 +               */
 +              if (fields_num != 9)
 +                      continue;
 +
 +
 +              if (strcmp (fields[0], "CLIENT_LIST") != 0)
 +                      continue;
 +
 +
 +              if (collect_user_count)
 +                      /* If so, sum all users, ignore the individuals*/
 +              {
 +                      sum_users += 1;
 +              }
 +              if (collect_individual_users)
 +              {
 +                      if (new_naming_schema)
 +                      {
 +                              /* plugin inst = file name, type inst = fields[1] */
 +                              iostats_submit (name,               /* vpn instance */
 +                                              fields[1],          /* "Common Name" */
 +                                              atoll (fields[4]),  /* "Bytes Received" */
 +                                              atoll (fields[5])); /* "Bytes Sent" */
 +                      }
 +                      else
 +                      {
 +                              /* plugin inst = fields[1], type inst = "" */
 +                              iostats_submit (fields[1],          /* "Common Name" */
 +                                              NULL,               /* unused when in multimode */
 +                                              atoll (fields[4]),  /* "Bytes Received" */
 +                                              atoll (fields[5])); /* "Bytes Sent" */
 +                      }
 +              }
 +
 +              read = 1;
 +      }
 +
 +      if (collect_user_count)
 +      {
 +              numusers_submit(name, name, sum_users);
 +              read = 1;
 +      }
 +
 +      return (read);
 +} /* int multi4_read */
 +
  /* read callback */
  static int openvpn_read (void)
  {
        /* call the right read function for every status entry in the list */
        for (i = 0; i < vpn_num; i++)
        {
 +              int vpn_read = 0;
 +
                fh = fopen (vpn_list[i]->file, "r");
                if (fh == NULL)
                {
                switch (vpn_list[i]->version)
                {
                        case SINGLE:
 -                              read = single_read(vpn_list[i]->name, fh);
 +                              vpn_read = single_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI1:
 -                              read = multi1_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi1_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI2:
 -                              read = multi2_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi2_read(vpn_list[i]->name, fh);
                                break;
  
                        case MULTI3:
 -                              read = multi3_read(vpn_list[i]->name, fh);
 +                              vpn_read = multi3_read(vpn_list[i]->name, fh);
 +                              break;
 +
 +                      case MULTI4:
 +                              vpn_read = multi4_read(vpn_list[i]->name, fh);
                                break;
                }
  
                fclose (fh);
 +              read += vpn_read;
        }
  
        return (read ? 0 : -1);
@@@ -618,13 -545,6 +618,13 @@@ static int version_detect (const char *
                        version = MULTI3;
                        break;
                }
 +              /* searching for multi version 4 */
 +              else if (strcmp (buffer, V4STRING) == 0)
 +              {
 +                      DEBUG ("openvpn plugin: found status file version MULTI4");
 +                      version = MULTI4;
 +                      break;
 +              }
        }
  
        if (version == 0)
@@@ -697,6 -617,14 +697,14 @@@ static int openvpn_config (const char *
  
                /* create a new vpn element since file, version and name are ok */
                temp = (vpn_status_t *) malloc (sizeof (vpn_status_t));
+               if (temp == NULL)
+               {
+                       char errbuf[1024];
+                       ERROR ("openvpn plugin: malloc failed: %s",
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       sfree (status_file);
+                       return (1);
+               }
                temp->file = status_file;
                temp->version = status_version;
                temp->name = status_name;
                if (vpn_list == NULL)
                {
                        char errbuf[1024];
-                       ERROR ("openvpn plugin: malloc failed: %s",
+                       ERROR ("openvpn plugin: realloc failed: %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
  
                        sfree (temp->file);
diff --combined src/perl.c
@@@ -2,25 -2,20 +2,25 @@@
   * collectd - src/perl.c
   * Copyright (C) 2007-2009  Sebastian Harl
   *
 - * 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.
   *
 - * Author:
 + * Authors:
   *   Sebastian Harl <sh at tokkee.org>
   **/
  
@@@ -46,7 -41,6 +46,7 @@@
  #include <perl.h>
  
  #if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__
 +# undef sprintf
  # pragma GCC poison sprintf
  #endif
  
@@@ -1208,7 -1202,10 +1208,10 @@@ static void c_ithread_destructor (void 
  
        /* the ithread no longer exists */
        if (NULL == t)
+       {
+               pthread_mutex_unlock (&perl_threads->mutex);
                return;
+       }
  
        c_ithread_destroy (ithread);
  
diff --combined src/snmp.c
@@@ -2,23 -2,18 +2,23 @@@
   * collectd - src/snmp.c
   * Copyright (C) 2007-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>
@@@ -34,8 -29,6 +34,8 @@@
  #include <net-snmp/net-snmp-config.h>
  #include <net-snmp/net-snmp-includes.h>
  
 +#include <fnmatch.h>
 +
  /*
   * Private data structes
   */
@@@ -57,7 -50,7 +57,7 @@@ struct data_definition_
  {
    char *name; /* used to reference this from the `Collect' option */
    char *type; /* used to find the data_set */
 -  int is_table;
 +  _Bool is_table;
    instance_t instance;
    char *instance_prefix;
    oid_t *values;
@@@ -65,9 -58,6 +65,9 @@@
    double scale;
    double shift;
    struct data_definition_s *next;
 +  char **ignores;
 +  size_t ignores_len;
 +  int invert_match;
  };
  typedef struct data_definition_s data_definition_t;
  
@@@ -75,22 -65,8 +75,22 @@@ struct host_definition_
  {
    char *name;
    char *address;
 -  char *community;
    int version;
 +
 +  /* snmpv1/2 options */
 +  char *community;
 +
 +  /* snmpv3 security options */
 +  char *username;
 +  oid *auth_protocol;
 +  size_t auth_protocol_len;
 +  char *auth_passphrase;
 +  oid *priv_protocol;
 +  size_t priv_protocol_len;
 +  char *priv_passphrase;
 +  int security_level;
 +  char *context;
 +
    void *sess_handle;
    c_complain_t complaint;
    cdtime_t interval;
@@@ -207,10 -183,6 +207,10 @@@ static void csnmp_host_definition_destr
    sfree (hd->name);
    sfree (hd->address);
    sfree (hd->community);
 +  sfree (hd->username);
 +  sfree (hd->auth_passphrase);
 +  sfree (hd->priv_passphrase);
 +  sfree (hd->context);
    sfree (hd->data_list);
  
    sfree (hd);
   *  csnmp_config
   *  +-> call_snmp_init_once
   *  +-> csnmp_config_add_data
 - *  !   +-> csnmp_config_add_data_type
 - *  !   +-> csnmp_config_add_data_table
   *  !   +-> csnmp_config_add_data_instance
   *  !   +-> csnmp_config_add_data_instance_prefix
   *  !   +-> csnmp_config_add_data_values
   *  +-> csnmp_config_add_host
 - *      +-> csnmp_config_add_host_address
 - *      +-> csnmp_config_add_host_community
   *      +-> csnmp_config_add_host_version
   *      +-> csnmp_config_add_host_collect
 + *      +-> csnmp_config_add_host_auth_protocol
 + *      +-> csnmp_config_add_host_priv_protocol
 + *      +-> csnmp_config_add_host_security_level
   */
  static void call_snmp_init_once (void)
  {
    have_init = 1;
  } /* void call_snmp_init_once */
  
 -static int csnmp_config_add_data_type (data_definition_t *dd, oconfig_item_t *ci)
 -{
 -  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: `Type' needs exactly one string argument.");
 -    return (-1);
 -  }
 -
 -  sfree (dd->type);
 -  dd->type = strdup (ci->values[0].value.string);
 -  if (dd->type == NULL)
 -    return (-1);
 -
 -  return (0);
 -} /* int csnmp_config_add_data_type */
 -
 -static int csnmp_config_add_data_table (data_definition_t *dd, oconfig_item_t *ci)
 -{
 -  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN))
 -  {
 -    WARNING ("snmp plugin: `Table' needs exactly one boolean argument.");
 -    return (-1);
 -  }
 -
 -  dd->is_table = ci->values[0].value.boolean ? 1 : 0;
 -
 -  return (0);
 -} /* int csnmp_config_add_data_table */
 -
  static int csnmp_config_add_data_instance (data_definition_t *dd, oconfig_item_t *ci)
  {
 -  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: `Instance' needs exactly one string argument.");
 -    return (-1);
 -  }
 +  char buffer[DATA_MAX_NAME_LEN];
 +  int status;
 +
 +  status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer));
 +  if (status != 0)
 +    return status;
  
    if (dd->is_table)
    {
      /* Instance is an OID */
      dd->instance.oid.oid_len = MAX_OID_LEN;
  
 -    if (!read_objid (ci->values[0].value.string,
 +    if (!read_objid (buffer,
            dd->instance.oid.oid, &dd->instance.oid.oid_len))
      {
 -      ERROR ("snmp plugin: read_objid (%s) failed.",
 -          ci->values[0].value.string);
 +      ERROR ("snmp plugin: read_objid (%s) failed.", buffer);
        return (-1);
      }
    }
    else
    {
      /* Instance is a simple string */
 -    sstrncpy (dd->instance.string, ci->values[0].value.string,
 +    sstrncpy (dd->instance.string, buffer,
          sizeof (dd->instance.string));
    }
  
  static int csnmp_config_add_data_instance_prefix (data_definition_t *dd,
      oconfig_item_t *ci)
  {
 -  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: `InstancePrefix' needs exactly one string argument.");
 -    return (-1);
 -  }
 +  int status;
  
    if (!dd->is_table)
    {
      return (-1);
    }
  
 -  sfree (dd->instance_prefix);
 -  dd->instance_prefix = strdup (ci->values[0].value.string);
 -  if (dd->instance_prefix == NULL)
 -    return (-1);
 -
 -  return (0);
 +  status = cf_util_get_string(ci, &dd->instance_prefix);
 +  return status;
  } /* int csnmp_config_add_data_instance_prefix */
  
  static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci)
    return (0);
  } /* int csnmp_config_add_data_instance */
  
 -static int csnmp_config_add_data_shift (data_definition_t *dd, oconfig_item_t *ci)
 +static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t *ci)
  {
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
 +  int i;
 +
 +  if (ci->values_num < 1)
 +    return (0);
 +
 +  for (i = 0; i < ci->values_num; i++)
    {
 -    WARNING ("snmp plugin: The `Shift' config option needs exactly one number argument.");
 -    return (-1);
 +    if (ci->values[i].type != OCONFIG_TYPE_STRING)
 +    {
 +      WARNING ("snmp plugin: `Ignore' needs only string argument.");
 +      return (-1);
 +    }
    }
  
 -  dd->shift = ci->values[0].value.number;
 +  dd->ignores_len = 0;
 +  dd->ignores = NULL;
  
 -  return (0);
 -} /* int csnmp_config_add_data_shift */
 +  for (i = 0; i < ci->values_num; ++i)
 +  {
 +    if (strarray_add(&(dd->ignores), &(dd->ignores_len), ci->values[i].value.string) != 0)
 +    {
 +      ERROR("snmp plugin: Can't allocate memory");
 +      strarray_free(dd->ignores, dd->ignores_len);
 +      return (ENOMEM);
 +    }
 +  }
 +  return 0;
 +} /* int csnmp_config_add_data_blacklist */
  
 -static int csnmp_config_add_data_scale (data_definition_t *dd, oconfig_item_t *ci)
 +static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd, oconfig_item_t *ci)
  {
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
 +  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN))
    {
 -    WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument.");
 +    WARNING ("snmp plugin: `InvertMatch' needs exactly one boolean argument.");
      return (-1);
    }
  
 -  dd->scale = ci->values[0].value.number;
 +  dd->invert_match = ci->values[0].value.boolean ? 1 : 0;
  
    return (0);
 -} /* int csnmp_config_add_data_scale */
 +} /* int csnmp_config_add_data_blacklist_match_inverted */
  
  static int csnmp_config_add_data (oconfig_item_t *ci)
  {
    int status = 0;
    int i;
  
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: The `Data' config option needs exactly one string argument.");
 -    return (-1);
 -  }
 -
    dd = (data_definition_t *) malloc (sizeof (data_definition_t));
    if (dd == NULL)
      return (-1);
    memset (dd, '\0', sizeof (data_definition_t));
  
 -  dd->name = strdup (ci->values[0].value.string);
 -  if (dd->name == NULL)
 +  status = cf_util_get_string(ci, &dd->name);
 +  if (status != 0)
    {
      free (dd);
      return (-1);
    }
 +
    dd->scale = 1.0;
    dd->shift = 0.0;
  
      oconfig_item_t *option = ci->children + i;
  
      if (strcasecmp ("Type", option->key) == 0)
 -      status = csnmp_config_add_data_type (dd, option);
 +      status = cf_util_get_string(option, &dd->type);
      else if (strcasecmp ("Table", option->key) == 0)
 -      status = csnmp_config_add_data_table (dd, option);
 +      status = cf_util_get_boolean(option, &dd->is_table);
      else if (strcasecmp ("Instance", option->key) == 0)
        status = csnmp_config_add_data_instance (dd, option);
      else if (strcasecmp ("InstancePrefix", option->key) == 0)
      else if (strcasecmp ("Values", option->key) == 0)
        status = csnmp_config_add_data_values (dd, option);
      else if (strcasecmp ("Shift", option->key) == 0)
 -      status = csnmp_config_add_data_shift (dd, option);
 +      status = cf_util_get_double(option, &dd->shift);
      else if (strcasecmp ("Scale", option->key) == 0)
 -      status = csnmp_config_add_data_scale (dd, option);
 +      status = cf_util_get_double(option, &dd->scale);
 +    else if (strcasecmp ("Ignore", option->key) == 0)
 +      status = csnmp_config_add_data_blacklist(dd, option);
 +    else if (strcasecmp ("InvertMatch", option->key) == 0)
 +      status = csnmp_config_add_data_blacklist_match_inverted(dd, option);
      else
      {
        WARNING ("snmp plugin: Option `%s' not allowed here.", option->key);
      sfree (dd->name);
      sfree (dd->instance_prefix);
      sfree (dd->values);
 +    sfree (dd->ignores);
      sfree (dd);
      return (-1);
    }
    return (0);
  } /* int csnmp_config_add_data */
  
 -static int csnmp_config_add_host_address (host_definition_t *hd, oconfig_item_t *ci)
 -{
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: The `Address' config option needs exactly one string argument.");
 -    return (-1);
 -  }
 -
 -  if (hd->address == NULL)
 -    free (hd->address);
 -
 -  hd->address = strdup (ci->values[0].value.string);
 -  if (hd->address == NULL)
 -    return (-1);
 -
 -  DEBUG ("snmp plugin: host = %s; host->address = %s;",
 -      hd->name, hd->address);
 -
 -  return (0);
 -} /* int csnmp_config_add_host_address */
 -
 -static int csnmp_config_add_host_community (host_definition_t *hd, oconfig_item_t *ci)
 -{
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: The `Community' config option needs exactly one string argument.");
 -    return (-1);
 -  }
 -
 -  if (hd->community == NULL)
 -    free (hd->community);
 -
 -  hd->community = strdup (ci->values[0].value.string);
 -  if (hd->community == NULL)
 -    return (-1);
 -
 -  DEBUG ("snmp plugin: host = %s; host->community = %s;",
 -      hd->name, hd->community);
 -
 -  return (0);
 -} /* int csnmp_config_add_host_community */
 -
  static int csnmp_config_add_host_version (host_definition_t *hd, oconfig_item_t *ci)
  {
    int version;
    }
  
    version = (int) ci->values[0].value.number;
 -  if ((version != 1) && (version != 2))
 +  if ((version < 1) || (version > 3))
    {
 -    WARNING ("snmp plugin: `Version' must either be `1' or `2'.");
 +    WARNING ("snmp plugin: `Version' must either be `1', `2', or `3'.");
      return (-1);
    }
  
@@@ -550,92 -589,6 +550,92 @@@ static int csnmp_config_add_host_collec
    return (0);
  } /* int csnmp_config_add_host_collect */
  
 +static int csnmp_config_add_host_auth_protocol (host_definition_t *hd, oconfig_item_t *ci)
 +{
 +  char buffer[4];
 +  int status;
 +
 +  status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer));
 +  if (status != 0)
 +    return status;
 +
 +  if (strcasecmp("MD5", buffer) == 0) {
 +    hd->auth_protocol = usmHMACMD5AuthProtocol;
 +    hd->auth_protocol_len = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
 +  }
 +  else if (strcasecmp("SHA", buffer) == 0) {
 +    hd->auth_protocol = usmHMACSHA1AuthProtocol;
 +    hd->auth_protocol_len = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid);
 +  }
 +  else
 +  {
 +    WARNING ("snmp plugin: The `AuthProtocol' config option must be `MD5' or `SHA'.");
 +    return (-1);
 +  }
 +
 +  DEBUG ("snmp plugin: host = %s; host->auth_protocol = %s;",
 +      hd->name, hd->auth_protocol == usmHMACMD5AuthProtocol ? "MD5" : "SHA");
 +
 +  return (0);
 +} /* int csnmp_config_add_host_auth_protocol */
 +
 +static int csnmp_config_add_host_priv_protocol (host_definition_t *hd, oconfig_item_t *ci)
 +{
 +  char buffer[4];
 +  int status;
 +
 +  status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer));
 +  if (status != 0)
 +    return status;
 +
 +  if (strcasecmp("AES", buffer) == 0)
 +  {
 +    hd->priv_protocol = usmAESPrivProtocol;
 +    hd->priv_protocol_len = sizeof(usmAESPrivProtocol)/sizeof(oid);
 +  }
 +  else if (strcasecmp("DES", buffer) == 0) {
 +    hd->priv_protocol = usmDESPrivProtocol;
 +    hd->priv_protocol_len = sizeof(usmDESPrivProtocol)/sizeof(oid);
 +  }
 +  else
 +  {
 +    WARNING ("snmp plugin: The `PrivProtocol' config option must be `AES' or `DES'.");
 +    return (-1);
 +  }
 +
 +  DEBUG ("snmp plugin: host = %s; host->priv_protocol = %s;",
 +      hd->name, hd->priv_protocol == usmAESPrivProtocol ? "AES" : "DES");
 +
 +  return (0);
 +} /* int csnmp_config_add_host_priv_protocol */
 +
 +static int csnmp_config_add_host_security_level (host_definition_t *hd, oconfig_item_t *ci)
 +{
 +  char buffer[16];
 +  int status;
 +
 +  status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer));
 +  if (status != 0)
 +    return status;
 +
 +  if (strcasecmp("noAuthNoPriv", buffer) == 0)
 +    hd->security_level = SNMP_SEC_LEVEL_NOAUTH;
 +  else if (strcasecmp("authNoPriv", buffer) == 0)
 +    hd->security_level = SNMP_SEC_LEVEL_AUTHNOPRIV;
 +  else if (strcasecmp("authPriv", buffer) == 0)
 +    hd->security_level = SNMP_SEC_LEVEL_AUTHPRIV;
 +  else
 +  {
 +    WARNING ("snmp plugin: The `SecurityLevel' config option must be `noAuthNoPriv', `authNoPriv', or `authPriv'.");
 +    return (-1);
 +  }
 +
 +  DEBUG ("snmp plugin: host = %s; host->security_level = %d;",
 +      hd->name, hd->security_level);
 +
 +  return (0);
 +} /* int csnmp_config_add_host_security_level */
 +
  static int csnmp_config_add_host (oconfig_item_t *ci)
  {
    host_definition_t *hd;
    user_data_t cb_data;
    struct timespec cb_interval;
  
 -  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
 -  {
 -    WARNING ("snmp plugin: `Host' needs exactly one string argument.");
 -    return (-1);
 -  }
 -
    hd = (host_definition_t *) malloc (sizeof (host_definition_t));
    if (hd == NULL)
      return (-1);
    hd->version = 2;
    C_COMPLAIN_INIT (&hd->complaint);
  
 -  hd->name = strdup (ci->values[0].value.string);
 -  if (hd->name == NULL)
 +  status = cf_util_get_string(ci, &hd->name);
 +  if (status != 0)
    {
 -    free (hd);
 -    return (-1);
 +    sfree (hd);
 +    return status;
    }
  
    hd->sess_handle = NULL;
      status = 0;
  
      if (strcasecmp ("Address", option->key) == 0)
 -      status = csnmp_config_add_host_address (hd, option);
 +      status = cf_util_get_string(option, &hd->address);
      else if (strcasecmp ("Community", option->key) == 0)
 -      status = csnmp_config_add_host_community (hd, option);
 +      status = cf_util_get_string(option, &hd->community);
      else if (strcasecmp ("Version", option->key) == 0)
        status = csnmp_config_add_host_version (hd, option);
      else if (strcasecmp ("Collect", option->key) == 0)
        csnmp_config_add_host_collect (hd, option);
      else if (strcasecmp ("Interval", option->key) == 0)
        cf_util_get_cdtime (option, &hd->interval);
 +    else if (strcasecmp ("Username", option->key) == 0)
 +      status = cf_util_get_string(option, &hd->username);
 +    else if (strcasecmp ("AuthProtocol", option->key) == 0)
 +      status = csnmp_config_add_host_auth_protocol (hd, option);
 +    else if (strcasecmp ("PrivacyProtocol", option->key) == 0)
 +      status = csnmp_config_add_host_priv_protocol (hd, option);
 +    else if (strcasecmp ("AuthPassphrase", option->key) == 0)
 +      status = cf_util_get_string(option, &hd->auth_passphrase);
 +    else if (strcasecmp ("PrivacyPassphrase", option->key) == 0)
 +      status = cf_util_get_string(option, &hd->priv_passphrase);
 +    else if (strcasecmp ("SecurityLevel", option->key) == 0)
 +      status = csnmp_config_add_host_security_level (hd, option);
 +    else if (strcasecmp ("Context", option->key) == 0)
 +      status = cf_util_get_string(option, &hd->context);
      else
      {
        WARNING ("snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", option->key);
        status = -1;
        break;
      }
 -    if (hd->community == NULL)
 +    if (hd->community == NULL && hd->version < 3)
      {
        WARNING ("snmp plugin: `Community' not given for host `%s'", hd->name);
        status = -1;
        break;
      }
 +    if (hd->version == 3)
 +    {
 +      if (hd->username == NULL)
 +      {
 +        WARNING ("snmp plugin: `Username' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      if (hd->security_level == 0)
 +      {
 +        WARNING ("snmp plugin: `SecurityLevel' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      if (hd->security_level == SNMP_SEC_LEVEL_AUTHNOPRIV || hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV)
 +      {
 +      if (hd->auth_protocol == NULL)
 +      {
 +        WARNING ("snmp plugin: `AuthProtocol' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      if (hd->auth_passphrase == NULL)
 +      {
 +        WARNING ("snmp plugin: `AuthPassphrase' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      }
 +      if (hd->security_level == SNMP_SEC_LEVEL_AUTHPRIV)
 +      {
 +      if (hd->priv_protocol == NULL)
 +      {
 +        WARNING ("snmp plugin: `PrivacyProtocol' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      if (hd->priv_passphrase == NULL)
 +      {
 +        WARNING ("snmp plugin: `PrivacyPassphrase' not given for host `%s'", hd->name);
 +        status = -1;
 +        break;
 +      }
 +      }
 +    }
  
      break;
    } /* while (status == 0) */
@@@ -823,75 -723,15 +823,75 @@@ static int csnmp_config (oconfig_item_
  static void csnmp_host_open_session (host_definition_t *host)
  {
    struct snmp_session sess;
 +  int error;
  
    if (host->sess_handle != NULL)
      csnmp_host_close_session (host);
  
    snmp_sess_init (&sess);
    sess.peername = host->address;
 -  sess.community = (u_char *) host->community;
 -  sess.community_len = strlen (host->community);
 -  sess.version = (host->version == 1) ? SNMP_VERSION_1 : SNMP_VERSION_2c;
 +  switch (host->version)
 +  {
 +    case 1:
 +      sess.version = SNMP_VERSION_1;
 +      break;
 +    case 3:
 +      sess.version = SNMP_VERSION_3;
 +      break;
 +    default:
 +      sess.version = SNMP_VERSION_2c;
 +      break;
 +  }
 +
 +  if (host->version == 3)
 +  {
 +    sess.securityName = host->username;
 +    sess.securityNameLen = strlen (host->username);
 +    sess.securityLevel = host->security_level;
 +
 +    if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV)
 +    {
 +      sess.securityAuthProto = host->auth_protocol;
 +      sess.securityAuthProtoLen = host->auth_protocol_len;
 +      sess.securityAuthKeyLen = USM_AUTH_KU_LEN;
 +      error = generate_Ku (sess.securityAuthProto,
 +          sess.securityAuthProtoLen,
 +          (u_char *) host->auth_passphrase,
 +          strlen(host->auth_passphrase),
 +          sess.securityAuthKey,
 +          &sess.securityAuthKeyLen);
 +      if (error != SNMPERR_SUCCESS) {
 +      ERROR ("snmp plugin: host %s: Error generating Ku from auth_passphrase. (Error %d)", host->name, error);
 +      }
 +    }
 +
 +    if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV)
 +    {
 +      sess.securityPrivProto = host->priv_protocol;
 +      sess.securityPrivProtoLen = host->priv_protocol_len;
 +      sess.securityPrivKeyLen = USM_PRIV_KU_LEN;
 +      error = generate_Ku (sess.securityAuthProto,
 +          sess.securityAuthProtoLen,
 +          (u_char *) host->priv_passphrase,
 +          strlen(host->priv_passphrase),
 +          sess.securityPrivKey,
 +          &sess.securityPrivKeyLen);
 +      if (error != SNMPERR_SUCCESS) {
 +      ERROR ("snmp plugin: host %s: Error generating Ku from priv_passphrase. (Error %d)", host->name, error);
 +      }
 +    }
 +
 +    if (host->context != NULL)
 +    {
 +      sess.contextName = host->context;
 +      sess.contextNameLen = strlen (host->context);
 +    }
 +  }
 +  else /* SNMPv1/2 "authenticates" with community string */
 +  {
 +    sess.community = (u_char *) host->community;
 +    sess.community_len = strlen (host->community);
 +  }
  
    /* snmp_sess_open will copy the `struct snmp_session *'. */
    host->sess_handle = snmp_sess_open (&sess);
@@@ -994,8 -834,7 +994,8 @@@ static value_t csnmp_value_list_to_valu
        status = parse_value (string, &ret, type);
        if (status != 0)
        {
 -        ERROR ("snmp plugin: csnmp_value_list_to_value: Parsing string as %s failed: %s",
 +        ERROR ("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string as %s failed: %s",
 +            (host_name != NULL) ? host_name : "UNKNOWN",
              DS_TYPE_TO_STRING (type), string);
        }
      }
@@@ -1130,8 -969,6 +1130,8 @@@ static int csnmp_instance_list_add (csn
    struct variable_list *vb;
    oid_t vb_name;
    int status;
 +  uint32_t i;
 +  uint32_t is_matched;
  
    /* Set vb on the last variable */
    for (vb = res->variables;
      char *ptr;
  
      csnmp_strvbcopy (il->instance, vb, sizeof (il->instance));
 -
 +    is_matched = 0;
 +    for (i = 0; i < dd->ignores_len; i++)
 +    {
 +      status = fnmatch(dd->ignores[i], il->instance, 0);
 +      if (status == 0)
 +      {
 +        if (dd->invert_match == 0)
 +        {
 +          sfree(il);
 +          return 0;
 +        }
 +      else
 +      {
 +          is_matched = 1;
 +        break;
 +      }
 +      }
 +    }
 +    if (dd->invert_match != 0 && is_matched == 0)
 +    {
 +      sfree(il);
 +      return 0;
 +    }
      for (ptr = il->instance; *ptr != '\0'; ptr++)
      {
        if ((*ptr > 0) && (*ptr < 32))
@@@ -1379,7 -1194,7 +1379,7 @@@ static int csnmp_dispatch_table (host_d
  static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
  {
    struct snmp_pdu *req;
-   struct snmp_pdu *res;
+   struct snmp_pdu *res = NULL;
    struct variable_list *vb;
  
    const data_set_t *ds;
          if (csnmp_instance_list_add (&instance_list_head, &instance_list_tail,
                res, host, data) != 0)
          {
 -          ERROR ("snmp plugin: csnmp_instance_list_add failed.");
 +          ERROR ("snmp plugin: host %s: csnmp_instance_list_add failed.",
 +              host->name);
            status = -1;
            break;
          }
@@@ -1848,7 -1662,6 +1848,7 @@@ static int csnmp_shutdown (void
      sfree (data_this->name);
      sfree (data_this->type);
      sfree (data_this->values);
 +    sfree (data_this->ignores);
      sfree (data_this);
  
      data_this = data_next;