Merge branch 'master' into feature-riemann-threshold
authorPierre-Yves Ritschard <pyr@spootnik.org>
Tue, 22 Jul 2014 11:55:49 +0000 (13:55 +0200)
committerPierre-Yves Ritschard <pyr@spootnik.org>
Tue, 22 Jul 2014 11:55:49 +0000 (13:55 +0200)
25 files changed:
contrib/collection.cgi
contrib/examples/myplugin.c
src/amqp.c
src/collectd.conf.in
src/collectd.conf.pod
src/common.c
src/common.h
src/cpu.c
src/curl.c
src/curl_json.c
src/curl_xml.c
src/memcached.c
src/memory.c
src/netlink.c
src/pinba.c
src/redis.c
src/statsd.c
src/syslog.c
src/tail.c
src/tcpconns.c
src/utils_format_graphite.c
src/utils_tail_match.c
src/utils_tail_match.h
src/write_http.c
src/write_riemann.c

index af64fb1..5ff259f 100755 (executable)
@@ -1,4 +1,25 @@
 #!/usr/bin/perl
+# Copyright (c) 2006-2010 Florian Forster <octo at collectd.org>
+# Copyright (c) 2006-2008 Sebastian Harl <sh at tokkee.org>
+# Copyright (c) 2008      Mirko Buffoni <briareos at eswat.org>
+#
+# 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:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# 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.
 
 use strict;
 use warnings;
@@ -507,6 +528,7 @@ sub _custom_sort_arrayref
 {
   my $array_ref = shift;
   my $array_sort = shift;
+  my $unknown_first = shift || 0;
 
   my %elements = map { $_ => 1 } (@$array_ref);
   splice (@$array_ref, 0);
@@ -517,7 +539,12 @@ sub _custom_sort_arrayref
     push (@$array_ref, $_);
     delete ($elements{$_});
   }
-  push (@$array_ref, sort (keys %elements));
+  if ($unknown_first) {
+    unshift (@$array_ref, sort (keys %elements));
+  }
+  else {
+    push (@$array_ref, sort (keys %elements));
+  }
 } # _custom_sort_arrayref
 
 sub action_show_host
@@ -957,9 +984,9 @@ sub load_graph_definitions
 
   $GraphDefs =
   {
-    apache_bytes => ['DEF:min_raw={file}:count:MIN',
-    'DEF:avg_raw={file}:count:AVERAGE',
-    'DEF:max_raw={file}:count:MAX',
+    apache_bytes => ['DEF:min_raw={file}:value:MIN',
+    'DEF:avg_raw={file}:value:AVERAGE',
+    'DEF:max_raw={file}:value:MAX',
     'CDEF:min=min_raw,8,*',
     'CDEF:avg=avg_raw,8,*',
     'CDEF:max=max_raw,8,*',
@@ -976,9 +1003,9 @@ sub load_graph_definitions
     'GPRINT:avg:LAST:%5.1lf%s Last',
     'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l'
     ],
-   apache_connections => ['DEF:min={file}:count:MIN',
-    'DEF:avg={file}:count:AVERAGE',
-    'DEF:max={file}:count:MAX',
+   apache_connections => ['DEF:min={file}:value:MIN',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Connections",
@@ -987,9 +1014,9 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf Max,',
     'GPRINT:avg:LAST:%6.2lf Last'
     ],
-    apache_idle_workers => ['DEF:min={file}:count:MIN',
-    'DEF:avg={file}:count:AVERAGE',
-    'DEF:max={file}:count:MAX',
+    apache_idle_workers => ['DEF:min={file}:value:MIN',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Idle Workers",
@@ -998,9 +1025,9 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf Max,',
     'GPRINT:avg:LAST:%6.2lf Last'
     ],
-    apache_requests => ['DEF:min={file}:count:MIN',
-    'DEF:avg={file}:count:AVERAGE',
-    'DEF:max={file}:count:MAX',
+    apache_requests => ['DEF:min={file}:value:MIN',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Requests/s",
@@ -1009,9 +1036,9 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf Max,',
     'GPRINT:avg:LAST:%6.2lf Last'
     ],
-    apache_scoreboard => ['DEF:min={file}:count:MIN',
-    'DEF:avg={file}:count:AVERAGE',
-    'DEF:max={file}:count:MAX',
+    apache_scoreboard => ['DEF:min={file}:value:MIN',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Processes",
@@ -2676,6 +2703,7 @@ sub load_graph_definitions
   $GraphDefs->{'virt_cpu_total'} = $GraphDefs->{'virt_cpu_total'};
 
   $MetaGraphDefs->{'cpu'} = \&meta_graph_cpu;
+  $MetaGraphDefs->{'df_complex'} = \&meta_graph_df;
   $MetaGraphDefs->{'dns_qtype'} = \&meta_graph_dns;
   $MetaGraphDefs->{'dns_rcode'} = \&meta_graph_dns;
   $MetaGraphDefs->{'if_rx_errors'} = \&meta_graph_if_rx_errors;
@@ -2858,6 +2886,73 @@ sub meta_graph_cpu
   return (meta_graph_generic_stack ($opts, $sources));
 } # meta_graph_cpu
 
+sub meta_graph_df
+{
+  confess ("Wrong number of arguments") if (@_ != 5);
+
+  my $host = shift;
+  my $plugin = shift;
+  my $plugin_instance = shift;
+  my $type = shift;
+  my $type_instances = shift;
+
+  my $opts = {};
+  my $sources = [];
+
+  my $prefix = "$host/$plugin"
+  . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type";
+
+  $opts->{'title'} = "Disk usage $prefix";
+
+  $opts->{'number_format'} = '%5.1lf%s';
+  $opts->{'rrd_opts'} = ['-l', 0, '-b', '1024', '-v', 'Bytes'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    'used'              => 'ff0000',
+    'snap_normal_used'  => 'c10640',
+    'snap_reserve_used' => '820c81',
+    'snap_reserved'     => 'f15aef',
+    'reserved'          => 'ffb000',
+    'free'              => '00ff00',
+    'sis_saved'         => '00e0e0',
+    'dedup_saved'       => '00c1c1',
+    'compression_saved' => '00a2a2'
+  };
+
+  # LVM uses LV names as type-instance; they should sort first
+  _custom_sort_arrayref ($type_instances,
+    [qw(compression_saved dedup_saved sis_saved free reserved snap_reserved
+      snap_reserve_used snap_normal_used used)], 1);
+
+  for (@$type_instances)
+  {
+    my $inst = $_;
+    my $file = '';
+
+    for (@DataDirs)
+    {
+      if (-e "$_/$prefix-$inst.rrd")
+      {
+       $file = "$_/$prefix-$inst.rrd";
+       last;
+      }
+    }
+    confess ("No file found for $prefix") if ($file eq '');
+
+    push (@$sources,
+      {
+       name => $inst,
+       file => $file
+      }
+    );
+  } # for (@$type_instances)
+
+  return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_df
+
 sub meta_graph_dns
 {
   confess ("Wrong number of arguments") if (@_ != 5);
index f68cc1a..9539062 100644 (file)
@@ -100,14 +100,16 @@ static int my_read (void)
        vl.time       = time (NULL);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin));
+
+       /* it is strongly recommended to use a type defined in the types.db file
+        * instead of a custom type */
+       sstrncpy (vl.type, "myplugin", sizeof (vl.plugin));
        /* optionally set vl.plugin_instance and vl.type_instance to reasonable
         * values (default: "") */
 
        /* dispatch the values to collectd which passes them on to all registered
-        * write functions - the first argument is used to lookup the data set
-        * definition (it is strongly recommended to use a type defined in the
-        * types.db file) */
-       plugin_dispatch_values ("myplugin", &vl);
+        * write functions */
+       plugin_dispatch_values (&vl);
 
        /* A return value != 0 indicates an error and the plugin will be skipped
         * for an increasing amount of time. */
@@ -117,7 +119,8 @@ static int my_read (void)
 /*
  * This function is called after values have been dispatched to collectd.
  */
-static int my_write (const data_set_t *ds, const value_list_t *vl)
+static int my_write (const data_set_t *ds, const value_list_t *vl,
+               user_data_t *ud)
 {
        char name[1024] = "";
        int i = 0;
@@ -151,7 +154,7 @@ static int my_write (const data_set_t *ds, const value_list_t *vl)
 /*
  * This function is called when plugin_log () has been used.
  */
-static void my_log (int severity, const char *msg)
+static void my_log (int severity, const char *msg, user_data_t *ud)
 {
        printf ("LOG: %i - %s\n", severity, msg);
        return;
@@ -160,7 +163,7 @@ static void my_log (int severity, const char *msg)
 /*
  * This function is called when plugin_dispatch_notification () has been used.
  */
-static int my_notify (const notification_t *notif)
+static int my_notify (const notification_t *notif, user_data_t *ud)
 {
        char time_str[32] = "";
        struct tm *tm = NULL;
@@ -210,12 +213,13 @@ static int my_shutdown (void)
  */
 void module_register (void)
 {
-       plugin_register_log ("myplugin", my_log);
-       plugin_register_notification ("myplugin", my_notify);
+       plugin_register_log ("myplugin", my_log, /* user data */ NULL);
+       plugin_register_notification ("myplugin", my_notify,
+                       /* user data */ NULL);
        plugin_register_data_set (&ds);
        plugin_register_read ("myplugin", my_read);
        plugin_register_init ("myplugin", my_init);
-       plugin_register_write ("myplugin", my_write);
+       plugin_register_write ("myplugin", my_write, /* user data */ NULL);
        plugin_register_shutdown ("myplugin", my_shutdown);
     return;
 } /* void module_register (void) */
index edd4f74..bdc62b3 100644 (file)
@@ -79,6 +79,8 @@ struct camqp_config_s
     /* subscribe only */
     char   *exchange_type;
     char   *queue;
+    _Bool   queue_durable;
+    _Bool   queue_auto_delete;
 
     amqp_connection_state_t connection;
     pthread_mutex_t lock;
@@ -314,9 +316,9 @@ static int camqp_setup_queue (camqp_config_t *conf) /* {{{ */
             ? amqp_cstring_bytes (conf->queue)
             : AMQP_EMPTY_BYTES,
             /* passive     = */ 0,
-            /* durable     = */ 0,
+            /* durable     = */ conf->queue_durable,
             /* exclusive   = */ 0,
-            /* auto_delete = */ 1,
+            /* auto_delete = */ conf->queue_auto_delete,
             /* arguments   = */ AMQP_EMPTY_TABLE);
     if (qd_ret == NULL)
     {
@@ -741,7 +743,7 @@ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
 {
     camqp_config_t *conf = user_data->data;
     char routing_key[6 * DATA_MAX_NAME_LEN];
-    char buffer[4096];
+    char buffer[8192];
     int status;
 
     if ((ds == NULL) || (vl == NULL) || (conf == NULL))
@@ -885,6 +887,8 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
     /* subscribe only */
     conf->exchange_type = NULL;
     conf->queue = NULL;
+    conf->queue_durable = 0;
+    conf->queue_auto_delete = 1;
     /* general */
     conf->connection = NULL;
     pthread_mutex_init (&conf->lock, /* attr = */ NULL);
@@ -924,6 +928,10 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
             status = cf_util_get_string (child, &conf->exchange_type);
         else if ((strcasecmp ("Queue", child->key) == 0) && !publish)
             status = cf_util_get_string (child, &conf->queue);
+        else if (strcasecmp ("QueueDurable", child->key) == 0)
+            status = cf_util_get_boolean (child, &conf->queue_durable);
+        else if (strcasecmp ("QueueAutoDelete", child->key) == 0)
+            status = cf_util_get_boolean (child, &conf->queue_auto_delete);
         else if (strcasecmp ("RoutingKey", child->key) == 0)
             status = cf_util_get_string (child, &conf->routing_key);
         else if ((strcasecmp ("Persistent", child->key) == 0) && publish)
index 830add9..3e2ddee 100644 (file)
 # ription of those options is available in the collectd.conf(5) manual page. #
 ##############################################################################
 
-#<Plugin "aggregation">
+#<Plugin aggregation>
 #  <Aggregation>
 #    #Host "unspecified"
 #    Plugin "cpu"
 #  </Aggregation>
 #</Plugin>
 
-#<Plugin "amqp">
+#<Plugin amqp>
 #  <Publish "name">
 #    Host "localhost"
 #    Port "5672"
 #      CACert "/etc/ssl/ca.crt"
 #</Plugin>
 
-#<Plugin "bind">
+#<Plugin bind>
 #  URL "http://localhost:8053/"
 #  ParseTime       false
 #  OpCodes         true
 #  IgnoreSelected false
 #</Plugin>
 
+#<Plugin cpu>
+#  ReportActive false
+#  ReportByCpu true
+#  ValuesPercentage false
+#</Plugin>
+#
 #<Plugin csv>
 #      DataDir "@localstatedir@/lib/@PACKAGE_NAME@/csv"
 #      StoreRates false
 #  </URL>
 #</Plugin>
 
-#<Plugin "curl_xml">
+#<Plugin curl_xml>
 #  <URL "http://localhost/stats.xml">
 #    Host "my_host"
 #    Instance "some_instance"
 #      </Directory>
 #</Plugin>
 
-#<Plugin "gmond">
+#<Plugin gmond>
 #  MCReceiveFrom "239.2.11.71" "8649"
 #  <Metric "swap_total">
 #    Type "swap"
 #      IgnoreSelected true
 #</Plugin>
 
-#<Plugin "java">
+#<Plugin java>
 #      JVMArg "-verbose:jni"
 #      JVMArg "-Djava.class.path=@prefix@/share/collectd/java/collectd-api.jar"
 #
 #  TimerPercentile 90.0
 #</Plugin>
 
-#<Plugin "swap">
+#<Plugin swap>
 #      ReportByDevice false
 #      ReportBytes true
 #      ValuesAbsolute true
 #      ValuesPercentage false
 #</Plugin>
 
-#<Plugin "table">
+#<Plugin table>
 #      <Table "/proc/slabinfo">
 #              Instance "slabinfo"
 #              Separator " "
 #      </Table>
 #</Plugin>
 
-#<Plugin "tail">
+#<Plugin tail>
 #  <File "/var/log/exim4/mainlog">
 #    Instance "exim"
+#    Interval 60
 #    <Match>
 #      Regex "S=([1-9][0-9]*)"
 #      DSType "CounterAdd"
 #  </File>
 #</Plugin>
 
-#<Plugin "tail_csv">
+#<Plugin tail_csv>
 #   <Metric "dropped">
 #       Type "percent"
 #       Instance "dropped"
 ##############################################################################
 
 #@BUILD_PLUGIN_THRESHOLD_TRUE@LoadPlugin "threshold"
-#<Plugin "threshold">
+#<Plugin threshold>
 #  <Type "foo">
 #    WarningMin    0.00
 #    WarningMax 1000.00
index 7a3d6a3..a14a8f6 100644 (file)
@@ -9,14 +9,14 @@ collectd.conf - Configuration for the system statistics collection daemon B<coll
   BaseDir "/path/to/data/"
   PIDFile "/path/to/pidfile/collectd.pid"
   Server  "123.123.123.123" 12345
-  
+
   LoadPlugin cpu
   LoadPlugin load
-  
+
   <LoadPlugin df>
     Interval 3600
   </LoadPlugin>
-  
+
   LoadPlugin ping
   <Plugin ping>
     Host "example.org"
@@ -341,10 +341,10 @@ The full example configuration looks like this:
    <Aggregation>
      Plugin "cpu"
      Type "cpu"
-     
+
      GroupBy "Host"
      GroupBy "TypeInstance"
-     
+
      CalculateSum true
      CalculateAverage true
    </Aggregation>
@@ -420,13 +420,13 @@ The following example calculates the average usage of all "even" CPUs:
      Plugin "cpu"
      PluginInstance "/[0,2,4,6,8]$/"
      Type "cpu"
-     
+
      SetPlugin "cpu"
      SetPluginInstance "even-%{aggregation}"
-     
+
      GroupBy "Host"
      GroupBy "TypeInstance"
-     
+
      CalculateAverage true
    </Aggregation>
  </Plugin>
@@ -495,7 +495,7 @@ possibly filtering or messages.
  #   GraphitePrefix "collectd."
  #   GraphiteEscapeChar "_"
    </Publish>
-   
+
    # Receive values from an AMQP broker
    <Subscribe "some_name">
      Host "localhost"
@@ -822,17 +822,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>
@@ -973,6 +973,31 @@ at all, B<all> cgroups are selected.
 
 =back
 
+=head2 Plugin C<cpu>
+
+The I<CPU plugin> collects CPU usage metrics.
+
+The following configuration options are available:
+
+=over 4
+
+=item B<ReportActive> B<false>|B<true>
+
+Reports non-idle CPU usage as the "active" value. Defaults to false.
+
+=item B<ReportByCpu> B<false>|B<true>
+
+When true reports usage for all cores. When false, reports cpu usage
+aggregated over all cores. Implies ValuesPercentage when false.
+Defaults to true.
+
+=item B<ValuesPercentage> B<false>|B<true>
+
+When true report percentage usage instead of tick values. Defaults to false.
+
+=back
+
+
 =head2 Plugin C<cpufreq>
 
 This plugin doesn't have any options. It reads
@@ -1046,6 +1071,10 @@ Username to use if authorization is required to read the page.
 
 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
@@ -1157,11 +1186,19 @@ The following options are valid within B<URL> blocks:
 Sets the plugin instance to I<Instance>.
 
 =item B<User> I<Name>
+
 =item B<Password> I<Password>
+
+=item B<Digest> B<true>|B<false>
+
 =item B<VerifyPeer> B<true>|B<false>
+
 =item B<VerifyHost> B<true>|B<false>
+
 =item B<CACert> I<file>
+
 =item B<Header> I<Header>
+
 =item B<Post> I<Body>
 
 These options behave exactly equivalent to the appropriate options of the
@@ -1250,6 +1287,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>
@@ -2425,12 +2464,12 @@ B<Synopsis:>
    ShowCPU true
    ShowCPUCores true
    ShowMemory true
-   
+
    ShowTemperatures true
    Temperature vddg
    Temperature vddq
    IgnoreSelectedTemperature true
-   
+
    ShowPower true
    Power total0
    Power total1
@@ -2610,19 +2649,19 @@ B<Synopsis:>
    Type voltage
    Instance "input-1"
  </Data>
+
  <Data "voltage-input-2">
    RegisterBase 2
    RegisterType float
    Type voltage
    Instance "input-2"
  </Data>
+
  <Host "modbus.example.com">
    Address "192.168.0.42"
    Port    "502"
    Interval 60
-   
+
    <Slave 1>
      Instance "power-supply"
      Collect  "voltage-input-1"
@@ -2855,7 +2894,7 @@ Required capabilities are documented below.
     User          "username"
     Password      "aef4Aebe"
     Interval      30
-    
+
     <WAFL>
       Interval 30
       GetNameCache   true
@@ -2863,12 +2902,12 @@ Required capabilities are documented below.
       GetBufferCache true
       GetInodeCache  true
     </WAFL>
-    
+
     <Disks>
       Interval 30
       GetBusy true
     </Disks>
-    
+
     <VolumePerf>
       Interval 30
       GetIO      "volume0"
@@ -2878,7 +2917,7 @@ Required capabilities are documented below.
       GetLatency "volume0"
       IgnoreSelectedLatency false
     </VolumePerf>
-    
+
     <VolumeUsage>
       Interval 30
       GetCapacity "vol0"
@@ -2888,15 +2927,15 @@ Required capabilities are documented below.
       GetSnapshot "vol3"
       IgnoreSelectedSnapshot false
     </VolumeUsage>
-    
+
     <Quota>
       Interval 60
     </Quota>
-    
+
     <Snapvault>
       Interval 30
     </Snapvault>
-    
+
     <System>
       Interval 30
       GetCPULoad     true
@@ -3457,7 +3496,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">
@@ -5525,6 +5564,7 @@ user using (extended) regular expressions, as described in L<regex(7)>.
   <Plugin "tail">
     <File "/var/log/exim4/mainlog">
       Instance "exim"
+      Interval 60
       <Match>
         Regex "S=([1-9][0-9]*)"
         DSType "CounterAdd"
@@ -5551,6 +5591,9 @@ This plugin instance is for all B<Match> blocks that B<follow> it, until the
 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:
 
@@ -7061,7 +7104,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
@@ -7243,7 +7286,7 @@ Example:
  <Target "replace">
    # Replace "example.net" with "example.com"
    Host "\\<example.net\\>" "example.com"
+
    # Strip "www." from hostnames
    Host "\\<www\\." ""
  </Target>
index 81142fd..18b5c43 100644 (file)
@@ -650,7 +650,7 @@ int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name)
        char ident[128];
 
        *ksp_ptr = NULL;
-       
+
        if (kc == NULL)
                return (-1);
 
@@ -1236,7 +1236,7 @@ int walk_directory (const char *dir, dirwalk_callback_f callback,
        while ((ent = readdir (dh)) != NULL)
        {
                int status;
-               
+
                if (include_hidden)
                {
                        if ((strcmp (".", ent->d_name) == 0)
@@ -1399,6 +1399,69 @@ int rate_to_value (value_t *ret_value, gauge_t rate, /* {{{ */
        return (0);
 } /* }}} value_t rate_to_value */
 
+int value_to_rate (value_t *ret_rate, derive_t value, /* {{{ */
+               value_to_rate_state_t *state,
+               int ds_type, cdtime_t t)
+{
+       double interval;
+
+       /* Another invalid state: The time is not increasing. */
+       if (t <= state->last_time)
+       {
+               memset (state, 0, sizeof (*state));
+               return (EINVAL);
+       }
+
+       interval = CDTIME_T_TO_DOUBLE(t - state->last_time);
+
+       /* Previous value is invalid. */
+       if (state->last_time == 0) /* {{{ */
+       {
+               if (ds_type == DS_TYPE_DERIVE)
+               {
+                       state->last_value.derive = value;
+               }
+               else if (ds_type == DS_TYPE_COUNTER)
+               {
+                       state->last_value.counter = (counter_t) value;
+               }
+               else if (ds_type == DS_TYPE_ABSOLUTE)
+               {
+                       state->last_value.absolute = (absolute_t) value;
+               }
+               else
+               {
+                       assert (23 == 42);
+               }
+
+               state->last_time = t;
+               return (EAGAIN);
+       } /* }}} */
+
+       if (ds_type == DS_TYPE_DERIVE)
+       {
+               ret_rate->gauge = (value - state->last_value.derive) / interval;
+               state->last_value.derive = value;
+       }
+       else if (ds_type == DS_TYPE_COUNTER)
+       {
+               ret_rate->gauge = (((counter_t)value) - state->last_value.counter) / interval;
+               state->last_value.counter = (counter_t) value;
+       }
+       else if (ds_type == DS_TYPE_ABSOLUTE)
+       {
+               ret_rate->gauge = (((absolute_t)value) - state->last_value.absolute) / interval;
+               state->last_value.absolute = (absolute_t) value;
+       }
+       else
+       {
+               assert (23 == 42);
+       }
+
+        state->last_time = t;
+       return (0);
+} /* }}} value_t rate_to_value */
+
 int service_name_to_port_number (const char *service_name)
 {
        struct addrinfo *ai_list;
index 67f307c..29590ff 100644 (file)
@@ -55,6 +55,13 @@ struct rate_to_value_state_s
 };
 typedef struct rate_to_value_state_s rate_to_value_state_t;
 
+struct value_to_rate_state_s
+{
+  value_t last_value;
+  cdtime_t last_time;
+};
+typedef struct value_to_rate_state_s value_to_rate_state_t;
+
 char *sstrncpy (char *dest, const char *src, size_t n);
 
 __attribute__ ((format(printf,3,4)))
@@ -324,6 +331,9 @@ counter_t counter_diff (counter_t old_value, counter_t new_value);
 int rate_to_value (value_t *ret_value, gauge_t rate,
                rate_to_value_state_t *state, int ds_type, cdtime_t t);
 
+int value_to_rate (value_t *ret_rate, derive_t value,
+               value_to_rate_state_t *state, int ds_type, cdtime_t t);
+
 /* Converts a service name (a string) to a port number
  * (in the range [1-65535]). Returns less than zero on error. */
 int service_name_to_port_number (const char *service_name);
index f1aa4ab..2e225fd 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -1,9 +1,9 @@
 /**
  * collectd - src/cpu.c
  * Copyright (C) 2005-2010  Florian octo Forster
- * Copyright (C) 2008       Oleg King
- * Copyright (C) 2009       Simon Kuhnle
- * Copyright (C) 2009       Manuel Sanmartin
+ * Copyright (C) 2008      Oleg King
+ * Copyright (C) 2009      Simon Kuhnle
+ * Copyright (C) 2009      Manuel Sanmartin
  *
  * 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
@@ -11,7 +11,7 @@
  *
  * 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
 # define CAN_USE_SYSCTL 0
 #endif
 
+#define CPU_SUBMIT_USER 0
+#define CPU_SUBMIT_SYSTEM 1
+#define CPU_SUBMIT_WAIT 2
+#define CPU_SUBMIT_NICE 3
+#define CPU_SUBMIT_SWAP 4
+#define CPU_SUBMIT_INTERRUPT 5
+#define CPU_SUBMIT_SOFTIRQ 6
+#define CPU_SUBMIT_STEAL 7
+#define CPU_SUBMIT_IDLE 8
+#define CPU_SUBMIT_ACTIVE 9
+#define CPU_SUBMIT_MAX 10
+
 #if HAVE_STATGRAB_H
 # include <statgrab.h>
 #endif
 # error "No applicable input method."
 #endif
 
+static const char *cpu_state_names[] = {
+       "user",
+       "system",
+       "wait",
+       "nice",
+       "swap",
+       "interrupt",
+       "softirq",
+       "steal",
+       "idle",
+       "active"
+};
+
 #ifdef PROCESSOR_CPU_LOAD_INFO
 static mach_port_t port_host;
 static processor_port_array_t cpu_list;
@@ -107,8 +132,8 @@ static mach_msg_type_number_t cpu_list_len;
 
 #if PROCESSOR_TEMPERATURE
 static int cpu_temp_retry_counter = 0;
-static int cpu_temp_retry_step    = 1;
-static int cpu_temp_retry_max     = 1;
+static int cpu_temp_retry_step   = 1;
+static int cpu_temp_retry_max    = 1;
 #endif /* PROCESSOR_TEMPERATURE */
 /* #endif PROCESSOR_CPU_LOAD_INFO */
 
@@ -145,6 +170,86 @@ static int numcpu;
 static int pnumcpu;
 #endif /* HAVE_PERFSTAT */
 
+static value_to_rate_state_t *percents = NULL;
+static gauge_t agg_percents[CPU_SUBMIT_MAX] = {
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+
+};
+static int percents_cells = 0;
+static int cpu_count = 0;
+
+
+static _Bool report_by_cpu = 1;
+static _Bool report_percent = 0;
+static _Bool report_active = 0;
+
+static const char *config_keys[] =
+{
+       "ReportByCpu",
+       "ReportActive",
+       "ValuesPercentage"
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+
+static int cpu_config (const char *key, const char *value)
+{
+       if (strcasecmp (key, "ReportByCpu") == 0) {
+               report_by_cpu = IS_TRUE (value) ? 1 : 0;
+               if (!report_by_cpu)
+                       report_percent = 1;
+       }
+       if (strcasecmp (key, "ValuesPercentage") == 0) {
+               report_percent = IS_TRUE (value) ? 1 : 0;
+               if (!report_percent)
+                       report_by_cpu = 1;
+       }
+       if (strcasecmp (key, "ReportActive") == 0)
+               report_active = IS_TRUE (value) ? 1 : 0;
+       return (-1);
+}
+
+static int cpu_states_grow (void)
+{
+  void *tmp;
+  int size;
+  int i;
+
+  size = cpu_count * CPU_SUBMIT_MAX; /* always alloc for all states */
+
+  if (size <= 0)
+         return 0;
+
+  if (percents_cells >= size)
+         return 0;
+
+  if (percents == NULL) {
+         percents = malloc(size * sizeof(*percents));
+         if (percents == NULL)
+                 return -1;
+         for (i = 0; i < size; i++)
+                 memset(&percents[i], 0, sizeof(*percents));
+         percents_cells = size;
+         return 0;
+  }
+
+  tmp = realloc(percents, size * sizeof(*percents));
+
+  if (tmp == NULL) {
+         ERROR ("cpu plugin: could not reserve enough space to hold states");
+         percents = NULL;
+         return -1;
+  }
+
+  for (i = percents_cells; i < size; i++)
+         memset(&percents[i], 0, sizeof(*percents));
+
+  percents = tmp;
+  percents_cells = size;
+  return 0;
+} /* cpu_states_grow */
+
+
 static int init (void)
 {
 #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
@@ -241,40 +346,156 @@ static int init (void)
        return (0);
 } /* int init */
 
-static void submit (int cpu_num, const char *type_instance, derive_t value)
+static void submit_value (int cpu_num, int cpu_state, const char *type, value_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = value;
+       memcpy(&values[0], &value, sizeof(value));
 
        vl.values = values;
        vl.values_len = 1;
+
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin));
-       ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
-                       "%i", cpu_num);
-       sstrncpy (vl.type, "cpu", sizeof (vl.type));
-       sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+       sstrncpy (vl.type, type, sizeof (vl.type));
+       sstrncpy (vl.type_instance, cpu_state_names[cpu_state],
+                 sizeof (vl.type_instance));
 
+       if (cpu_num >= 0) {
+               ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+                          "%i", cpu_num);
+       }
        plugin_dispatch_values (&vl);
 }
 
+static void submit_percent(int cpu_num, int cpu_state, gauge_t percent)
+{
+       value_t value;
+
+       value.gauge = percent;
+       submit_value (cpu_num, cpu_state, "percent", value);
+}
+
+static void submit_derive(int cpu_num, int cpu_state, derive_t derive)
+{
+       value_t value;
+
+       value.derive = derive;
+       submit_value (cpu_num, cpu_state, "cpu", value);
+}
+
+static void submit_flush (void)
+{
+       int i = 0;
+
+       if (report_by_cpu) {
+               cpu_count = 0;
+               return;
+       }
+
+       for (i = 0; i < CPU_SUBMIT_MAX; i++) {
+               if (agg_percents[i] == -1)
+                       continue;
+
+               submit_percent(-1, i, agg_percents[i] / cpu_count);
+               agg_percents[i] = -1;
+       }
+       cpu_count = 0;
+}
+
+static void submit (int cpu_num, derive_t *derives)
+{
+
+       int i = 0;
+
+       if (!report_percent && report_by_cpu) {
+               derive_t cpu_active = 0;
+               for (i = 0; i < CPU_SUBMIT_ACTIVE; i++)
+               {
+                       if (derives[i] == -1)
+                               continue;
+
+                       if (i != CPU_SUBMIT_IDLE)
+                               cpu_active += derives[i];
+
+                       submit_derive(cpu_num, i, derives[i]);
+               }
+               if (report_active)
+                       submit_derive(cpu_num, CPU_SUBMIT_ACTIVE, cpu_active);
+       }
+       else /* we are reporting percents */
+       {
+               cdtime_t cdt;
+               gauge_t percent;
+               gauge_t cpu_total = 0;
+               gauge_t cpu_active = 0;
+               gauge_t local_rates[CPU_SUBMIT_MAX];
+
+               cpu_count++;
+               if (cpu_states_grow())
+                       return;
+
+               memset(local_rates, 0, sizeof(local_rates));
+
+               cdt = cdtime();
+               for (i = 0; i < CPU_SUBMIT_ACTIVE; i++) {
+                       value_t rate;
+                       int index;
+
+                       if (derives[i] == -1)
+                               continue;
+
+                       index = (cpu_num * CPU_SUBMIT_MAX) + i;
+                       if (value_to_rate(&rate, derives[i], &percents[index],
+                                         DS_TYPE_DERIVE, cdt) != 0) {
+                               local_rates[i] = -1;
+                               continue;
+                       }
+
+                       local_rates[i] = rate.gauge;
+                       cpu_total += rate.gauge;
+                       if (i != CPU_SUBMIT_IDLE)
+                               cpu_active += rate.gauge;
+               }
+               if (cpu_total == 0.0)
+                       return;
+
+               if (report_active)
+                       local_rates[CPU_SUBMIT_ACTIVE] = cpu_active;
+
+               for (i = 0; i < CPU_SUBMIT_MAX; i++) {
+                       if (local_rates[i] == -1)
+                               continue;
+
+                       percent = (local_rates[i] / cpu_total) * 100;
+                       if (report_by_cpu)
+                               submit_percent (cpu_num, i, percent);
+                       else {
+                               if (agg_percents[i] == -1)
+                                       agg_percents[i] = percent;
+                               else
+                                       agg_percents[i] += percent;
+                       }
+
+               }
+       }
+}
+
 static int cpu_read (void)
 {
 #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
        int cpu;
 
        kern_return_t status;
-       
+
 #if PROCESSOR_CPU_LOAD_INFO
-       derive_t                       cpu_active;
        processor_cpu_load_info_data_t cpu_info;
-       mach_msg_type_number_t         cpu_info_len;
+       mach_msg_type_number_t         cpu_info_len;
 #endif
 #if PROCESSOR_TEMPERATURE
-       processor_info_data_t          cpu_temp;
-       mach_msg_type_number_t         cpu_temp_len;
+       processor_info_data_t          cpu_temp;
+       mach_msg_type_number_t         cpu_temp_len;
 #endif
 
        host_t cpu_host;
@@ -282,6 +503,10 @@ static int cpu_read (void)
        for (cpu = 0; cpu < cpu_list_len; cpu++)
        {
 #if PROCESSOR_CPU_LOAD_INFO
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+               memset(derives, -1, sizeof(derives));
                cpu_host = 0;
                cpu_info_len = PROCESSOR_BASIC_INFO_COUNT;
 
@@ -299,15 +524,12 @@ static int cpu_read (void)
                        continue;
                }
 
-               submit (cpu, "user", (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]);
-               submit (cpu, "nice", (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]);
-               submit (cpu, "system", (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]);
-               submit (cpu, "idle", (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]);
-               cpu_active = (derive_t) (cpu_info.cpu_ticks[CPU_STATE_USER] +
-                                        cpu_info.cpu_ticks[CPU_STATE_NICE] +
-                                        cpu_info.cpu_ticks[CPU_STATE_SYSTEM]);
-               submit (cpu, "active", cpu_active);
-                                        
+               derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER];
+               derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE];
+               derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM];
+               derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE];
+               submit (cpu, derives);
+
 #endif /* PROCESSOR_CPU_LOAD_INFO */
 #if PROCESSOR_TEMPERATURE
                /*
@@ -344,7 +566,7 @@ static int cpu_read (void)
                if (cpu_temp_len != 1)
                {
                        DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?",
-                                       (int) cpu_temp_len);
+                                       (int) cpu_temp_len);
                        continue;
                }
 
@@ -352,13 +574,11 @@ static int cpu_read (void)
                cpu_temp_retry_step    = 1;
 #endif /* PROCESSOR_TEMPERATURE */
        }
+       submit_flush ();
 /* #endif PROCESSOR_CPU_LOAD_INFO */
 
 #elif defined(KERNEL_LINUX)
        int cpu;
-       derive_t cpu_active;
-       derive_t user, nice, syst, idle;
-       derive_t wait, intr, sitr; /* sitr == soft interrupt */
        FILE *fh;
        char buf[1024];
 
@@ -375,6 +595,10 @@ static int cpu_read (void)
 
        while (fgets (buf, 1024, fh) != NULL)
        {
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+
                if (strncmp (buf, "cpu", 3))
                        continue;
                if ((buf[3] < '0') || (buf[3] > '9'))
@@ -385,42 +609,29 @@ static int cpu_read (void)
                        continue;
 
                cpu = atoi (fields[0] + 3);
-               user = atoll (fields[1]);
-               nice = atoll (fields[2]);
-               syst = atoll (fields[3]);
-               idle = atoll (fields[4]);
-
-               submit (cpu, "user", user);
-               submit (cpu, "nice", nice);
-               submit (cpu, "system", syst);
-               submit (cpu, "idle", idle);
-               cpu_active = user + nice + syst;
+               derives[CPU_SUBMIT_USER] = atoll(fields[1]);
+               derives[CPU_SUBMIT_NICE] = atoll(fields[2]);
+               derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]);
+               derives[CPU_SUBMIT_IDLE] = atoll(fields[4]);
 
                if (numfields >= 8)
                {
-                       wait = atoll (fields[5]);
-                       intr = atoll (fields[6]);
-                       sitr = atoll (fields[7]);
-
-                       submit (cpu, "wait", wait);
-                       submit (cpu, "interrupt", intr);
-                       submit (cpu, "softirq", sitr);
-                       
-                       cpu_active += wait + intr + sitr;
+                       derives[CPU_SUBMIT_WAIT] = atoll(fields[5]);
+                       derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]);
+                       derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]);
 
                        if (numfields >= 9)
-                               cpu_active += (derive_t) atoll (fields[8]);
-                               submit (cpu, "steal", atoll (fields[8]));
+                               derives[CPU_SUBMIT_STEAL] = atoll(fields[8]);
                }
-               submit (cpu, "active", cpu_active);
+               submit(cpu, derives);
        }
+       submit_flush();
 
        fclose (fh);
 /* #endif defined(KERNEL_LINUX) */
 
 #elif defined(HAVE_LIBKSTAT)
        int cpu;
-       derive_t user, syst, idle, wait;
        static cpu_stat_t cs;
 
        if (kc == NULL)
@@ -428,20 +639,21 @@ static int cpu_read (void)
 
        for (cpu = 0; cpu < numcpu; cpu++)
        {
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+
                if (kstat_read (kc, ksp[cpu], &cs) == -1)
                        continue; /* error message? */
 
-               idle = (derive_t) cs.cpu_sysinfo.cpu[CPU_IDLE];
-               user = (derive_t) cs.cpu_sysinfo.cpu[CPU_USER];
-               syst = (derive_t) cs.cpu_sysinfo.cpu[CPU_KERNEL];
-               wait = (derive_t) cs.cpu_sysinfo.cpu[CPU_WAIT];
-
-               submit (ksp[cpu]->ks_instance, "user", user);
-               submit (ksp[cpu]->ks_instance, "system", syst);
-               submit (ksp[cpu]->ks_instance, "idle", idle);
-               submit (ksp[cpu]->ks_instance, "wait", wait);
-               submit (ksp[cpu]->ks_instance, "active", user + syst + wait);
+               memset(derives, -1, sizeof(derives));
+               derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE];
+               derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER];
+               derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL];
+               derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT];
+               submit (ksp[cpu]->ks_instance, derives);
        }
+       submit_flush ();
 /* #endif defined(HAVE_LIBKSTAT) */
 
 #elif CAN_USE_SYSCTL
@@ -500,16 +712,18 @@ static int cpu_read (void)
        }
 
        for (i = 0; i < numcpu; i++) {
-               submit (i, "user",      cpuinfo[i][CP_USER]);
-               submit (i, "nice",      cpuinfo[i][CP_NICE]);
-               submit (i, "system",    cpuinfo[i][CP_SYS]);
-               submit (i, "idle",      cpuinfo[i][CP_IDLE]);
-               submit (i, "interrupt", cpuinfo[i][CP_INTR]);
-               submit (i, "active",    cpuinfo[i][CP_USER] +
-                                       cpuinfo[i][CP_NICE] +
-                                       cpuinfo[i][CP_SYS] +
-                                       cpuinfo[i][CP_INTR]);
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+
+               derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER];
+               derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE];
+               derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS];
+               derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE];
+               derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR];
+               submit(i, derives);
        }
+       submit_flush();
 /* #endif CAN_USE_SYSCTL */
 #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES)
        long cpuinfo[maxcpu][CPUSTATES];
@@ -528,20 +742,26 @@ static int cpu_read (void)
        }
 
        for (i = 0; i < numcpu; i++) {
-               submit (i, "user", cpuinfo[i][CP_USER]);
-               submit (i, "nice", cpuinfo[i][CP_NICE]);
-               submit (i, "system", cpuinfo[i][CP_SYS]);
-               submit (i, "idle", cpuinfo[i][CP_IDLE]);
-               submit (i, "interrupt", cpuinfo[i][CP_INTR]);
-               submit (i, "active", cpuinfo[i][CP_USER] +
-                       cpuinfo[i][CP_NICE] +
-                       cpuinfo[i][CP_SYS] +
-                       cpuinfo[i][CP_INTR]);
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+
+               derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER];
+               derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE];
+               derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS];
+               derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE];
+               derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR];
+               submit(i, derives);
        }
+       submit_flush();
+
 /* #endif HAVE_SYSCTL_KERN_CP_TIMES */
 #elif defined(HAVE_SYSCTLBYNAME)
        long cpuinfo[CPUSTATES];
        size_t cpuinfo_size;
+       derive_t derives[CPU_SUBMIT_MAX] = {
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+       };
 
        cpuinfo_size = sizeof (cpuinfo);
 
@@ -553,19 +773,21 @@ static int cpu_read (void)
                return (-1);
        }
 
-       submit (0, "user", cpuinfo[CP_USER]);
-       submit (0, "nice", cpuinfo[CP_NICE]);
-       submit (0, "system", cpuinfo[CP_SYS]);
-       submit (0, "idle", cpuinfo[CP_IDLE]);
-       submit (0, "interrupt", cpuinfo[CP_INTR]);
-       submit (0, "active", cpuinfo[CP_USER] +
-               cpuinfo[CP_NICE] +
-               cpuinfo[CP_SYS] +
-               cpuinfo[CP_INTR]);
+       derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER];
+       derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS];
+       derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE];
+       derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE];
+       derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR];
+       submit(0, derives);
+       submit_flush();
+
 /* #endif HAVE_SYSCTLBYNAME */
 
 #elif defined(HAVE_LIBSTATGRAB)
        sg_cpu_stats *cs;
+       derive_t derives[CPU_SUBMIT_MAX] = {
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+       };
        cs = sg_get_cpu_stats ();
 
        if (cs == NULL)
@@ -574,18 +796,14 @@ static int cpu_read (void)
                return (-1);
        }
 
-       submit (0, "idle",   (derive_t) cs->idle);
-       submit (0, "nice",   (derive_t) cs->nice);
-       submit (0, "swap",   (derive_t) cs->swap);
-       submit (0, "system", (derive_t) cs->kernel);
-       submit (0, "user",   (derive_t) cs->user);
-       submit (0, "wait",   (derive_t) cs->iowait);
-       submit (0, "active", (derive_t) cs->nice + 
-               cs->swap +
-               cs->kernel +
-               cs->user +
-               cs->iowait +
-               cs->nice);
+       derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle;
+       derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice;
+       derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap;
+       derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel;
+       derives[CPU_SUBMIT_USER] = (derive_t) cs->user;
+       derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait;
+       submit(0, derives);
+       submit_flush();
 /* #endif HAVE_LIBSTATGRAB */
 
 #elif defined(HAVE_PERFSTAT)
@@ -600,10 +818,10 @@ static int cpu_read (void)
                        sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
-       
-       if (pnumcpu != numcpu || perfcpu == NULL) 
+
+       if (pnumcpu != numcpu || perfcpu == NULL)
        {
-               if (perfcpu != NULL) 
+               if (perfcpu != NULL)
                        free(perfcpu);
                perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t));
        }
@@ -618,16 +836,18 @@ static int cpu_read (void)
                return (-1);
        }
 
-       for (i = 0; i < cpus; i++) 
+       for (i = 0; i < cpus; i++)
        {
-               submit (i, "idle",   (derive_t) perfcpu[i].idle);
-               submit (i, "system", (derive_t) perfcpu[i].sys);
-               submit (i, "user",   (derive_t) perfcpu[i].user);
-               submit (i, "wait",   (derive_t) perfcpu[i].wait);
-               submit (i, "active", (derive_t) perfcpu[i].sys +
-                       perfcpu[i].user +
-                       perfcpu[i].wait);
+               derive_t derives[CPU_SUBMIT_MAX] = {
+                       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+               };
+               derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle;
+               derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys;
+               derives[CPU_SUBMIT_USER] = perfcpu[i].user;
+               derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait;
+               submit(i, derives);
        }
+       submit_flush();
 #endif /* HAVE_PERFSTAT */
 
        return (0);
@@ -636,5 +856,6 @@ static int cpu_read (void)
 void module_register (void)
 {
        plugin_register_init ("cpu", init);
+       plugin_register_config ("cpu", cpu_config, config_keys, config_keys_num);
        plugin_register_read ("cpu", cpu_read);
 } /* void module_register */
index ae23834..e189df6 100644 (file)
@@ -58,6 +58,7 @@ struct web_page_s /* {{{ */
   char *user;
   char *pass;
   char *credentials;
+  _Bool digest;
   _Bool verify_peer;
   _Bool verify_host;
   char *cacert;
@@ -388,6 +389,13 @@ static int cc_page_init_curl (web_page_t *wp) /* {{{ */
     ssnprintf (wp->credentials, credentials_size, "%s:%s",
         wp->user, (wp->pass == NULL) ? "" : wp->pass);
     curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials);
+    
+    if (wp->digest)
+    {
+      curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+      curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user);
+      curl_easy_setopt (wp->curl, CURLOPT_PASSWORD, wp->pass);
+    }
   }
 
   curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer);
@@ -425,6 +433,7 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
   page->url = NULL;
   page->user = NULL;
   page->pass = NULL;
+  page->digest = 0;
   page->verify_peer = 1;
   page->verify_host = 1;
   page->response_time = 0;
@@ -450,6 +459,8 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_string (child, &page->user);
     else if (strcasecmp ("Password", child->key) == 0)
       status = cf_util_get_string (child, &page->pass);
+    else if (strcasecmp ("Digest", child->key) == 0)
+      status = cf_util_get_boolean (child, &page->digest);
     else if (strcasecmp ("VerifyPeer", child->key) == 0)
       status = cf_util_get_boolean (child, &page->verify_peer);
     else if (strcasecmp ("VerifyHost", child->key) == 0)
index 36cc468..a9db925 100644 (file)
@@ -71,6 +71,7 @@ struct cj_s /* {{{ */
   char *user;
   char *pass;
   char *credentials;
+  _Bool digest;
   _Bool verify_peer;
   _Bool verify_host;
   char *cacert;
@@ -609,6 +610,13 @@ static int cj_init_curl (cj_t *db) /* {{{ */
     ssnprintf (db->credentials, credentials_size, "%s:%s",
                db->user, (db->pass == NULL) ? "" : db->pass);
     curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials);
+    
+    if (db->digest)
+    {
+      curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+      curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user);
+      curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass);
+    }
   }
 
   curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, (long) db->verify_peer);
@@ -675,6 +683,8 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
       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)
index 8d50561..6d36d29 100644 (file)
@@ -76,6 +76,7 @@ struct cx_s /* {{{ */
   char *user;
   char *pass;
   char *credentials;
+  _Bool digest;
   _Bool verify_peer;
   _Bool verify_host;
   char *cacert;
@@ -860,6 +861,13 @@ static int cx_init_curl (cx_t *db) /* {{{ */
     ssnprintf (db->credentials, credentials_size, "%s:%s",
                db->user, (db->pass == NULL) ? "" : db->pass);
     curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials);
+    
+    if (db->digest)
+    {
+      curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+      curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user);
+      curl_easy_setopt (db->curl, CURLOPT_PASSWORD, db->pass);
+    }
   }
 
   curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L);
@@ -926,6 +934,8 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
       status = cf_util_get_string (child, &db->user);
     else if (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 (strcasecmp ("VerifyPeer", child->key) == 0)
       status = cf_util_get_boolean (child, &db->verify_peer);
     else if (strcasecmp ("VerifyHost", child->key) == 0)
index d739203..e2ccfee 100644 (file)
@@ -387,7 +387,7 @@ static int memcached_read (user_data_t *user_data)
 
     /*
      * For an explanation on these fields please refer to
-     * <http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt>
+     * <https://github.com/memcached/memcached/blob/master/doc/protocol.txt>
      */
 
     /*
@@ -437,6 +437,10 @@ static int memcached_read (user_data_t *user_data)
     {
       submit_gauge ("memcached_connections", "current", atof (fields[2]), st);
     }
+    else if (FIELD_IS ("listen_disabled_num"))
+    {
+      submit_derive ("memcached_connections", "listen_disabled", atof (fields[2]), st);
+    }
 
     /*
      * Commands
index e8ba934..b33c1f8 100644 (file)
@@ -487,6 +487,7 @@ static int memory_read (void) /* {{{ */
        vl.values_len = STATIC_ARRAY_SIZE (v);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "memory", sizeof (vl.plugin));
+       sstrncpy (vl.type, "memory", sizeof (vl.type));
        vl.time = cdtime ();
 
        return (memory_read_internal (&vl));
index 5e670d4..de2de9b 100644 (file)
@@ -310,10 +310,10 @@ static void check_ignorelist_and_submit (const char *dev,
 
 } /* void check_ignorelist_and_submit */
 
-#define COPY_RTNL_LINK_VALUE (dst_stats, src_stats, value_name) \
+#define COPY_RTNL_LINK_VALUE(dst_stats, src_stats, value_name) \
   (dst_stats)->value_name = (src_stats)->value_name
 
-#define COPY_RTNL_LINK_STATS (dst_stats, src_stats) \
+#define COPY_RTNL_LINK_STATS(dst_stats, src_stats) \
   COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_packets); \
   COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_packets); \
   COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_bytes); \
index 6879733..e7bf2aa 100644 (file)
 
 #include "pinba.pb-c.h"
 
+/* AIX doesn't have MSG_DONTWAIT */
+#ifndef MSG_DONTWAIT
+#  define MSG_DONTWAIT MSG_NONBLOCK
+#endif
+
 /*
  * Defines
  */
index 85a8354..92be18f 100644 (file)
@@ -37,6 +37,7 @@
 #define REDIS_DEF_PORT    6379
 #define REDIS_DEF_TIMEOUT 2000
 #define MAX_REDIS_NODE_NAME 64
+#define MAX_REDIS_PASSWD_LENGTH 512
 
 /* Redis plugin configuration example:
  *
@@ -55,7 +56,7 @@ struct redis_node_s
 {
   char name[MAX_REDIS_NODE_NAME];
   char host[HOST_NAME_MAX];
-  char passwd[HOST_NAME_MAX];
+  char passwd[MAX_REDIS_PASSWD_LENGTH];
   int port;
   int timeout;
 
index 72a7779..52dd8f8 100644 (file)
 #include <netdb.h>
 #include <poll.h>
 
+/* AIX doesn't have MSG_DONTWAIT */
+#ifndef MSG_DONTWAIT
+#  define MSG_DONTWAIT MSG_NONBLOCK
+#endif
+
 #ifndef STATSD_DEFAULT_NODE
 # define STATSD_DEFAULT_NODE NULL
 #endif
index 4f5d0c4..1a70fd0 100644 (file)
@@ -48,7 +48,11 @@ static int sl_config (const char *key, const char *value)
        {
                log_level = parse_log_severity (value);
                if (log_level < 0)
+               {
+                       log_level = LOG_INFO;
+                       ERROR ("syslog: invalid loglevel [%s] defauling to 'info'", value);
                        return (1);
+               }
        }
        else if (strcasecmp (key, "NotifyLevel") == 0)
        {
index bcb1572..20f2a9b 100644 (file)
@@ -28,6 +28,7 @@
  *  <Plugin tail>
  *    <File "/var/log/exim4/mainlog">
  *     Instance "exim"
+ *      Interval 60
  *     <Match>
  *       Regex "S=([1-9][0-9]*)"
  *       ExcludeRegex "U=root.*S="
@@ -46,11 +47,13 @@ struct ctail_config_match_s
   int flags;
   char *type;
   char *type_instance;
+  cdtime_t interval;
 };
 typedef struct ctail_config_match_s ctail_config_match_t;
 
 cu_tail_match_t **tail_match_list = NULL;
 size_t tail_match_list_num = 0;
+cdtime_t tail_match_list_intervals[255];
 
 static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
     oconfig_item_t *ci)
@@ -123,7 +126,7 @@ static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
 } /* int ctail_config_add_match_dstype */
 
 static int ctail_config_add_match (cu_tail_match_t *tm,
-    const char *plugin_instance, oconfig_item_t *ci)
+    const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval)
 {
   ctail_config_match_t cm;
   int status;
@@ -190,7 +193,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm,
   if (status == 0)
   {
     status = tail_match_add_match_simple (tm, cm.regex, cm.excluderegex,
-       cm.flags, "tail", plugin_instance, cm.type, cm.type_instance);
+       cm.flags, "tail", plugin_instance, cm.type, cm.type_instance, interval);
 
     if (status != 0)
     {
@@ -209,6 +212,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm,
 static int ctail_config_add_file (oconfig_item_t *ci)
 {
   cu_tail_match_t *tm;
+  cdtime_t interval = 0;
   char *plugin_instance = NULL;
   int num_matches = 0;
   int status;
@@ -233,19 +237,20 @@ static int ctail_config_add_file (oconfig_item_t *ci)
   {
     oconfig_item_t *option = ci->children + i;
 
-    if (strcasecmp ("Match", option->key) == 0)
+    if (strcasecmp ("Instance", option->key) == 0)
+      status = cf_util_get_string (option, &plugin_instance);
+    else if (strcasecmp ("Interval", option->key) == 0)
+      cf_util_get_cdtime (option, &interval);
+    else if (strcasecmp ("Match", option->key) == 0)
     {
-      status = ctail_config_add_match (tm, plugin_instance, option);
+      status = ctail_config_add_match (tm, plugin_instance, option, interval);
       if (status == 0)
        num_matches++;
       /* Be mild with failed matches.. */
       status = 0;
     }
-    else if (strcasecmp ("Instance", option->key) == 0)
-      status = cf_util_get_string (option, &plugin_instance);
     else
     {
-      WARNING ("tail plugin: Option `%s' not allowed here.", option->key);
       status = -1;
     }
 
@@ -275,6 +280,7 @@ static int ctail_config_add_file (oconfig_item_t *ci)
 
     tail_match_list = temp;
     tail_match_list[tail_match_list_num] = tm;
+    tail_match_list_intervals[tail_match_list_num] = interval;
     tail_match_list_num++;
   }
 
@@ -300,41 +306,43 @@ static int ctail_config (oconfig_item_t *ci)
   return (0);
 } /* int ctail_config */
 
-static int ctail_init (void)
+static int ctail_read (user_data_t *ud)
 {
-  if (tail_match_list_num == 0)
+  int status;
+
+  status = tail_match_read ((cu_tail_match_t *)ud->data);
+  if (status != 0)
   {
-    WARNING ("tail plugin: File list is empty. Returning an error.");
+    ERROR ("tail plugin: tail_match_read failed.");
     return (-1);
   }
 
   return (0);
-} /* int ctail_init */
+} /* int ctail_read */
 
-static int ctail_read (void)
+static int ctail_init (void)
 {
-  int success = 0;
+  struct timespec cb_interval;
+  char str[255];
+  user_data_t ud;
   size_t i;
 
-  for (i = 0; i < tail_match_list_num; i++)
+  if (tail_match_list_num == 0)
   {
-    int status;
+    WARNING ("tail plugin: File list is empty. Returning an error.");
+    return (-1);
+  }
 
-    status = tail_match_read (tail_match_list[i]);
-    if (status != 0)
-    {
-      ERROR ("tail plugin: tail_match_read[%zu] failed.", i);
-    }
-    else
-    {
-      success++;
-    }
+  for (i = 0; i < tail_match_list_num; i++)
+  {
+    ud.data = (void *)tail_match_list[i];
+    ssnprintf(str, sizeof(str), "tail-%zu", i);
+    CDTIME_T_TO_TIMESPEC (tail_match_list_intervals[i], &cb_interval);
+    plugin_register_complex_read (NULL, str, ctail_read, &cb_interval, &ud);
   }
 
-  if (success == 0)
-    return (-1);
   return (0);
-} /* int ctail_read */
+} /* int ctail_init */
 
 static int ctail_shutdown (void)
 {
@@ -355,7 +363,6 @@ void module_register (void)
 {
   plugin_register_complex_config ("tail", ctail_config);
   plugin_register_init ("tail", ctail_init);
-  plugin_register_read ("tail", ctail_read);
   plugin_register_shutdown ("tail", ctail_shutdown);
 } /* void module_register */
 
index 765b892..890e07f 100644 (file)
@@ -215,13 +215,13 @@ static const char *tcp_state[] =
   "CLOSED",
   "LISTEN",
   "SYN_SENT",
-  "SYN_RCVD",
+  "SYN_RECV",
   "ESTABLISHED",
   "CLOSE_WAIT",
-  "FIN_WAIT_1",
+  "FIN_WAIT1",
   "CLOSING",
   "LAST_ACK",
-  "FIN_WAIT_2",
+  "FIN_WAIT2",
   "TIME_WAIT"
 };
 
index 8351201..b7d4494 100644 (file)
@@ -29,6 +29,8 @@
 #include "utils_cache.h"
 #include "utils_parse_option.h"
 
+#define GRAPHITE_FORBIDDEN " \t\"\\:!/()\n\r"
+
 /* Utils functions to format data sets in graphite format.
  * Largely taken from write_graphite.c as it remains the same formatting */
 
@@ -169,6 +171,18 @@ static int gr_format_name (char *ret, int ret_len,
     return (0);
 }
 
+static void escape_graphite_string (char *buffer, char escape_char)
+{
+       char *head;
+
+       assert (strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL);
+
+       for (head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
+            *head != '\0';
+            head += strcspn(head, GRAPHITE_FORBIDDEN))
+               *head = escape_char;
+}
+
 int format_graphite (char *buffer, size_t buffer_size,
     data_set_t const *ds, value_list_t const *vl,
     char const *prefix, char const *postfix, char const escape_char,
@@ -204,7 +218,7 @@ int format_graphite (char *buffer, size_t buffer_size,
             return (status);
         }
 
-        escape_string (key, sizeof (key));
+        escape_graphite_string (key, escape_char);
         /* Convert the values to an ASCII representation and put that into
          * `values'. */
         status = gr_format_values (values, sizeof (values), i, ds, vl, rates);
index 8ae2208..13b518b 100644 (file)
@@ -37,6 +37,7 @@ struct cu_tail_match_simple_s
   char plugin_instance[DATA_MAX_NAME_LEN];
   char type[DATA_MAX_NAME_LEN];
   char type_instance[DATA_MAX_NAME_LEN];
+  cdtime_t interval;
 };
 typedef struct cu_tail_match_simple_s cu_tail_match_simple_t;
 
@@ -54,6 +55,7 @@ struct cu_tail_match_s
   int flags;
   cu_tail_t *tail;
 
+  cdtime_t interval;
   cu_tail_match_match_t *matches;
   size_t matches_num;
 };
@@ -88,6 +90,7 @@ static int simple_submit_match (cu_match_t *match, void *user_data)
   sstrncpy (vl.type_instance, data->type_instance,
       sizeof (vl.type_instance));
 
+  vl.interval = data->interval;
   plugin_dispatch_values (&vl);
 
   if (match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE)
@@ -180,6 +183,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match,
   obj->matches = temp;
   obj->matches_num++;
 
+  DEBUG ("tail_match_add_match interval %lf", CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval));
   temp = obj->matches + (obj->matches_num - 1);
 
   temp->match = match;
@@ -193,7 +197,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match,
 int tail_match_add_match_simple (cu_tail_match_t *obj,
     const char *regex, const char *excluderegex, int ds_type,
     const char *plugin, const char *plugin_instance,
-    const char *type, const char *type_instance)
+    const char *type, const char *type_instance, const cdtime_t interval)
 {
   cu_match_t *match;
   cu_tail_match_simple_t *user_data;
@@ -221,6 +225,8 @@ int tail_match_add_match_simple (cu_tail_match_t *obj,
     sstrncpy (user_data->type_instance, type_instance,
        sizeof (user_data->type_instance));
 
+  user_data->interval = interval;
+
   status = tail_match_add_match (obj, match, simple_submit_match,
       user_data, free);
 
index 7659745..abd98b6 100644 (file)
@@ -105,7 +105,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match,
 int tail_match_add_match_simple (cu_tail_match_t *obj,
     const char *regex, const char *excluderegex, int ds_type,
     const char *plugin, const char *plugin_instance,
-    const char *type, const char *type_instance);
+    const char *type, const char *type_instance, const cdtime_t interval);
 
 /*
  * NAME
index 25133c3..ed8d834 100644 (file)
@@ -46,10 +46,10 @@ struct wh_callback_s
         char *user;
         char *pass;
         char *credentials;
-        int   verify_peer;
-        int   verify_host;
+        _Bool verify_peer;
+        _Bool verify_host;
         char *cacert;
-        int   store_rates;
+        _Bool store_rates;
 
 #define WH_FORMAT_COMMAND 0
 #define WH_FORMAT_JSON    1
@@ -433,47 +433,6 @@ static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
         return (status);
 } /* }}} int wh_write */
 
-static int config_set_string (char **ret_string, /* {{{ */
-                oconfig_item_t *ci)
-{
-        char *string;
-
-        if ((ci->values_num != 1)
-                        || (ci->values[0].type != OCONFIG_TYPE_STRING))
-        {
-                WARNING ("write_http plugin: The `%s' config option "
-                                "needs exactly one string argument.", ci->key);
-                return (-1);
-        }
-
-        string = strdup (ci->values[0].value.string);
-        if (string == NULL)
-        {
-                ERROR ("write_http plugin: strdup failed.");
-                return (-1);
-        }
-
-        if (*ret_string != NULL)
-                free (*ret_string);
-        *ret_string = string;
-
-        return (0);
-} /* }}} int config_set_string */
-
-static int config_set_boolean (int *dest, oconfig_item_t *ci) /* {{{ */
-{
-        if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN))
-        {
-                WARNING ("write_http plugin: The `%s' config option "
-                                "needs exactly one boolean argument.", ci->key);
-                return (-1);
-        }
-
-        *dest = ci->values[0].value.boolean ? 1 : 0;
-
-        return (0);
-} /* }}} int config_set_boolean */
-
 static int config_set_format (wh_callback_t *cb, /* {{{ */
                 oconfig_item_t *ci)
 {
@@ -500,7 +459,7 @@ static int config_set_format (wh_callback_t *cb, /* {{{ */
         }
 
         return (0);
-} /* }}} int config_set_string */
+} /* }}} int config_set_format */
 
 static int wh_config_url (oconfig_item_t *ci) /* {{{ */
 {
@@ -527,7 +486,7 @@ static int wh_config_url (oconfig_item_t *ci) /* {{{ */
 
         pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
 
-        config_set_string (&cb->location, ci);
+        cf_util_get_string (ci, &cb->location);
         if (cb->location == NULL)
                 return (-1);
 
@@ -536,19 +495,19 @@ static int wh_config_url (oconfig_item_t *ci) /* {{{ */
                 oconfig_item_t *child = ci->children + i;
 
                 if (strcasecmp ("User", child->key) == 0)
-                        config_set_string (&cb->user, child);
+                        cf_util_get_string (child, &cb->user);
                 else if (strcasecmp ("Password", child->key) == 0)
-                        config_set_string (&cb->pass, child);
+                        cf_util_get_string (child, &cb->pass);
                 else if (strcasecmp ("VerifyPeer", child->key) == 0)
-                        config_set_boolean (&cb->verify_peer, child);
+                        cf_util_get_boolean (child, &cb->verify_peer);
                 else if (strcasecmp ("VerifyHost", child->key) == 0)
-                        config_set_boolean (&cb->verify_host, child);
+                        cf_util_get_boolean (child, &cb->verify_host);
                 else if (strcasecmp ("CACert", child->key) == 0)
-                        config_set_string (&cb->cacert, child);
+                        cf_util_get_string (child, &cb->cacert);
                 else if (strcasecmp ("Format", child->key) == 0)
                         config_set_format (cb, child);
                 else if (strcasecmp ("StoreRates", child->key) == 0)
-                        config_set_boolean (&cb->store_rates, child);
+                        cf_util_get_boolean (child, &cb->store_rates);
                 else
                 {
                         ERROR ("write_http plugin: Invalid configuration "
index 75325cd..2875a01 100644 (file)
@@ -428,6 +428,9 @@ static Msg *riemann_notification_to_protobuf (struct riemann_host *host, /* {{{
                        n->type, n->type_instance);
        event->service = strdup (&service_buffer[1]);
 
+       if (n->message[0] != 0)
+               riemann_event_add_attribute (event, "description", n->message);
+
        /* Pull in values from threshold and add extra attributes */
        for (meta = n->meta; meta != NULL; meta = meta->next)
        {