Merge branch 'collectd-4.10' into collectd-5.0
authorFlorian Forster <octo@collectd.org>
Sat, 25 Feb 2012 17:15:36 +0000 (18:15 +0100)
committerFlorian Forster <octo@collectd.org>
Sat, 25 Feb 2012 17:15:36 +0000 (18:15 +0100)
Conflicts:
src/df.c

Change-Id: Ie7c9fd4a20cc356bb53b135bf2ca2d5162a8a953

1  2 
contrib/exec-nagios.px
src/bind.c
src/df.c

diff --combined contrib/exec-nagios.px
@@@ -23,9 -23,9 +23,10 @@@ use Regexp::Common ('number')
  
  our $ConfigFile = '/etc/exec-nagios.conf';
  our $TypeMap = {};
+ our $NRPEMap = {};
  our $Scripts = [];
 -our $Interval = 300;
 +our $Interval = defined ($ENV{'COLLECTD_INTERVAL'}) ? (0 + $ENV{'COLLECTD_INTERVAL'}) : 300;
 +our $Hostname = defined ($ENV{'COLLECTD_HOSTNAME'}) ? $ENV{'COLLECTD_HOSTNAME'} : '';
  
  main ();
  exit (0);
@@@ -41,6 -41,7 +42,7 @@@ config syntax, so it's very similar to 
  
  Here's a short sample config:
  
+   NRPEConfig "/etc/nrpe.cfg"
    Interval 300
    <Script /usr/lib/nagios/check_tcp>
      Arguments -H alice -p 22
@@@ -55,6 -56,18 +57,18 @@@ The options have the following semanti
  
  =over 4
  
+ =item B<NRPEConfig> I<File>
+ Read the NRPE config and add the command definitions to an alias table. After
+ reading the file you can use the NRPE command name rather than the script's
+ filename within B<Script> blocks (see below). If both, the NRPE config and the
+ B<Script> block, define arguments they will be merged by concatenating the
+ arguments together in the order "NRPE-args Script-args".
+ Please note that this option is rather dumb. It does not support "command
+ argument processing" (i.e. replacing C<$ARG1$> and friends), inclusion of other
+ NRPE config files, include directories etc.
  =item B<Interval> I<Seconds>
  
  Sets the interval in which the plugins are executed. This doesn't need to match
@@@ -65,8 -78,9 +79,9 @@@ seconds
  =item E<lt>B<Script> I<File>E<gt>
  
  Adds a script to the list of scripts to be executed once per I<Interval>
- seconds. You can use the following optional arguments to specify the operation
- further:
+ seconds. If the B<NRPEConfig> is given above the B<Script> block, you may use
+ the NRPE command name rather than the script's filename. You can use the
+ following optional arguments to specify the operation further:
  
  =over 4
  
@@@ -93,6 -107,48 +108,48 @@@ with the C<exec-plugin>)
  
  =cut
  
+ sub parse_nrpe_conf
+ {
+   my $file = shift;
+   my $fh;
+   my $status;
+   $status = open ($fh, '<', $file);
+   if (!$status)
+   {
+     print STDERR "Reading NRPE config from \"$file\" failed: $!\n";
+     return;
+   }
+   while (<$fh>)
+   {
+     my $line = $_;
+     chomp ($line);
+     if ($line =~ m/^\s*command\[([^\]]+)\]\s*=\s*(.+)$/)
+     {
+       my $alias = $1;
+       my $script;
+       my $arguments;
+       ($script, $arguments) = split (' ', $2, 2);
+       if ($NRPEMap->{$alias})
+       {
+         print STDERR "Warning: NRPE command \"$alias\" redefined.\n";
+       }
+       $NRPEMap->{$alias} = { script => $script };
+       if ($arguments)
+       {
+         $NRPEMap->{$alias}{'arguments'} = $arguments;
+       }
+     }
+   } # while (<$fh>)
+   close ($fh);
+ } # parse_nrpe_conf
  sub handle_config_addtype
  {
    my $list = shift;
    }
  } # handle_config_addtype
  
+ # Update the script record. This function adds the name of the script /
+ # executable to the hash and merges the configured and NRPE arguments if
+ # required.
+ sub update_script_opts
+ {
+   my $opts = shift;
+   my $script = shift;
+   my $nrpe_args = shift;
+   $opts->{'script'} = $script;
+   if ($nrpe_args)
+   {
+     if ($opts->{'arguments'})
+     {
+       $opts->{'arguments'} = $nrpe_args . ' ' . $opts->{'arguments'};
+     }
+     else
+     {
+       $opts->{'arguments'} = $nrpe_args;
+     }
+   }
+ } # update_script_opts
  sub handle_config_script
  {
    my $scripts = shift;
      my $script = $_;
      my $opts = $scripts->{$script};
  
+     my $nrpe_args = '';
+     # Check if the script exists in the NRPE map. If so, replace the alias name
+     # with the actual script name.
+     if ($NRPEMap->{$script})
+     {
+       if ($NRPEMap->{$script}{'arguments'})
+       {
+         $nrpe_args = $NRPEMap->{$script}{'arguments'};
+       }
+       $script = $NRPEMap->{$script}{'script'};
+     }
+     # Check if the script exists and is executable.
      if (!-e $script)
      {
        print STDERR "Script `$script' doesn't exist.\n";
      }
      else
      {
+       # Add the script to the global @$Script array.
        if (ref ($opts) eq 'ARRAY')
+       {
+         for (@$opts)
          {
-           for (@$opts)
-             {
-               my $opt = $_;
-               $opt->{'script'} = $script;
-               push (@$Scripts, $opt);
-             }
-         }
-           else
-         {
-           $opts->{'script'} = $script;
-           push (@$Scripts, $opts);
+           my $opt = $_;
+           update_script_opts ($opt, $script, $nrpe_args);
+           push (@$Scripts, $opt);
          }
+       }
+       else
+       {
+         update_script_opts ($opts, $script, $nrpe_args);
+         push (@$Scripts, $opts);
+       }
      }
    } # for (keys %$scripts)
  } # handle_config_script
@@@ -148,6 -243,26 +244,26 @@@ sub handle_confi
  {
    my $config = shift;
  
+   if (defined ($config->{'nrpeconfig'}))
+   {
+     if (ref ($config->{'nrpeconfig'}) eq 'ARRAY')
+     {
+       for (@{$config->{'nrpeconfig'}})
+       {
+         parse_nrpe_conf ($_);
+       }
+     }
+     elsif (ref ($config->{'nrpeconfig'}) eq '')
+     {
+       parse_nrpe_conf ($config->{'nrpeconfig'});
+     }
+     else
+     {
+       print STDERR "Cannot handle ref type '"
+       . ref ($config->{'nrpeconfig'}) . "' for option 'NRPEConfig'.\n";
+     }
+   }
    if (defined ($config->{'addtype'}))
    {
      if (ref ($config->{'addtype'}) eq 'ARRAY')
@@@ -236,7 -351,6 +352,7 @@@ sub handle_performance_dat
    my $type = shift;
    my $time = shift;
    my $line = shift;
 +  my $ident = "$host/$plugin-$pinst/$type-$tinst";
  
    my $tinst;
    my $value;
      return;
    }
  
 -  print "PUTVAL $host/$plugin-$pinst/$type-$tinst interval=$Interval ${time}:$value\n";
 +  $ident =~ s/"/\\"/g;
 +
 +  print qq(PUTVAL "$ident" interval=$Interval ${time}:$value\n);
  }
  
  sub execute_script
    my $time = time ();
    my $script = shift;
    my @args = ();
 -  my $host = hostname () || 'localhost';
 +  my $host = $Hostname || hostname () || 'localhost';
  
    my $state = 0;
    my $serviceoutput;
diff --combined src/bind.c
@@@ -1,7 -1,7 +1,7 @@@
  /**
   * collectd - src/bind.c
 - * Copyright (C) 2009  Bruno Prémont
 - * Copyright (C) 2009  Florian Forster
 + * Copyright (C) 2009       Bruno Prémont
 + * Copyright (C) 2009,2010  Florian 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
   *
   * Authors:
   *   Bruno Prémont <bonbons at linux-vserver.org>
 - *   Florian Forster <octo at verplant.org>
 + *   Florian Forster <octo at collectd.org>
   **/
  
  #include "config.h"
  
 -#ifndef _XOPEN_SOURCE
 -# define _XOPEN_SOURCE 600 /* glibc2 needs this for strptime */
 -#endif
 +#if STRPTIME_NEEDS_STANDARDS
 +# ifndef _ISOC99_SOURCE
 +#  define _ISOC99_SOURCE 1
 +# endif
 +# ifndef _POSIX_C_SOURCE
 +#  define _POSIX_C_SOURCE 200112L
 +# endif
 +# ifndef _XOPEN_SOURCE
 +#  define _XOPEN_SOURCE 500
 +# endif
 +#endif /* STRPTIME_NEEDS_STANDARDS */
  
  #include "collectd.h"
  #include "common.h"
@@@ -249,7 -241,7 +249,7 @@@ static void submit (time_t ts, const ch
  
    vl.values = values;
    vl.values_len = 1;
 -  vl.time = ts;
 +  vl.time = TIME_T_TO_CDTIME_T (ts);
    sstrncpy(vl.host, hostname_g, sizeof(vl.host));
    sstrncpy(vl.plugin, "bind", sizeof(vl.plugin));
    if (plugin_instance) {
@@@ -345,31 -337,36 +345,31 @@@ static int bind_xml_list_callback (cons
    return (0);
  } /* }}} int bind_xml_list_callback */
  
 -static int bind_xml_read_counter (xmlDoc *doc, xmlNode *node, /* {{{ */
 -    counter_t *ret_value)
 +static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */
 +    derive_t *ret_value)
  {
 -  char *str_ptr, *end_ptr;
 -  long long int value;
 +  char *str_ptr;
 +  value_t value;
 +  int status;
  
    str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
    if (str_ptr == NULL)
    {
 -    ERROR ("bind plugin: bind_xml_read_counter: xmlNodeListGetString failed.");
 +    ERROR ("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed.");
      return (-1);
    }
  
 -  errno = 0;
 -  value = strtoll (str_ptr, &end_ptr, 10);
 -  xmlFree(str_ptr);
 -  if (str_ptr == end_ptr || errno)
 +  status = parse_value (str_ptr, &value, DS_TYPE_DERIVE);
 +  if (status != 0)
    {
 -    if (errno && (value < 0))
 -      ERROR ("bind plugin: bind_xml_read_counter: strtoll failed with underflow.");
 -    else if (errno && (value > 0))
 -      ERROR ("bind plugin: bind_xml_read_counter: strtoll failed with overflow.");
 -    else
 -      ERROR ("bind plugin: bind_xml_read_counter: strtoll failed.");
 +    ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.",
 +        str_ptr);
      return (-1);
    }
  
 -  *ret_value = value;
 +  *ret_value = value.derive;
    return (0);
 -} /* }}} int bind_xml_read_counter */
 +} /* }}} int bind_xml_read_derive */
  
  static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */
      gauge_t *ret_value)
@@@ -530,7 -527,7 +530,7 @@@ static int bind_parse_generic_name_valu
        if (ds_type == DS_TYPE_GAUGE)
          status = bind_xml_read_gauge (doc, counter, &value.gauge);
        else
 -        status = bind_xml_read_counter (doc, counter, &value.counter);
 +        status = bind_xml_read_derive (doc, counter, &value.derive);
        if (status != 0)
          continue;
  
@@@ -603,7 -600,7 +603,7 @@@ static int bind_parse_generic_value_lis
        if (ds_type == DS_TYPE_GAUGE)
          status = bind_xml_read_gauge (doc, child, &value.gauge);
        else
 -        status = bind_xml_read_counter (doc, child, &value.counter);
 +        status = bind_xml_read_derive (doc, child, &value.derive);
        if (status != 0)
          continue;
  
@@@ -794,7 -791,7 +794,7 @@@ static int bind_xml_stats_handle_view (
      list_info_ptr_t list_info =
      {
        plugin_instance,
-       /* type = */ "dns_qtype_gauge"
+       /* type = */ "dns_qtype"
      };
  
      ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-qtypes",
          doc, path_ctx, current_time, DS_TYPE_COUNTER);
    } /* }}} */
  
+   /* Record types in the cache */
    if (view->cacherrsets != 0) /* {{{ */
    {
      char plugin_instance[DATA_MAX_NAME_LEN];
      list_info_ptr_t list_info =
      {
        plugin_instance,
-       /* type = */ "dns_qtype_gauge"
+       /* type = */ "dns_qtype_cached"
      };
  
      ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets",
diff --combined src/df.c
+++ b/src/df.c
@@@ -62,8 -62,9 +62,8 @@@ static ignorelist_t *il_device = NULL
  static ignorelist_t *il_mountpoint = NULL;
  static ignorelist_t *il_fstype = NULL;
  
 -static _Bool by_device = false;
 -static _Bool report_reserved = false;
 -static _Bool report_inodes = false;
 +static _Bool by_device = 0;
 +static _Bool report_inodes = 0;
  
  static int df_init (void)
  {
@@@ -118,16 -119,25 +118,16 @@@ static int df_config (const char *key, 
        else if (strcasecmp (key, "ReportByDevice") == 0)
        {
                if (IS_TRUE (value))
 -                      by_device = true;
 -
 -              return (0);
 -      }
 -      else if (strcasecmp (key, "ReportReserved") == 0)
 -      {
 -              if (IS_TRUE (value))
 -                      report_reserved = true;
 -              else
 -                      report_reserved = false;
 +                      by_device = 1;
  
                return (0);
        }
        else if (strcasecmp (key, "ReportInodes") == 0)
        {
                if (IS_TRUE (value))
 -                      report_inodes = true;
 +                      report_inodes = 1;
                else
 -                      report_inodes = false;
 +                      report_inodes = 0;
  
                return (0);
        }
        return (-1);
  }
  
 -static void df_submit_two (char *df_name,
 -              const char *type,
 -              gauge_t df_used,
 -              gauge_t df_free)
 -{
 -      value_t values[2];
 -      value_list_t vl = VALUE_LIST_INIT;
 -
 -      values[0].gauge = df_used;
 -      values[1].gauge = df_free;
 -
 -      vl.values = values;
 -      vl.values_len = 2;
 -      sstrncpy (vl.host, hostname_g, sizeof (vl.host));
 -      sstrncpy (vl.plugin, "df", sizeof (vl.plugin));
 -      sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
 -      sstrncpy (vl.type, type, sizeof (vl.type));
 -      sstrncpy (vl.type_instance, df_name, sizeof (vl.type_instance));
 -
 -      plugin_dispatch_values (&vl);
 -} /* void df_submit_two */
 -
  __attribute__ ((nonnull(2)))
  static void df_submit_one (char *plugin_instance,
                const char *type, const char *type_instance,
@@@ -183,9 -215,6 +183,9 @@@ static int df_read (void
        {
                unsigned long long blocksize;
                char disk_name[256];
 +              uint64_t blk_free;
 +              uint64_t blk_reserved;
 +              uint64_t blk_used;
  
                if (ignorelist_match (il_device,
                                        (mnt_ptr->spec_device != NULL)
  
                blocksize = BLOCKSIZE(statbuf);
  
 -              if (report_reserved)
 -              {
 -                      uint64_t blk_free;
 -                      uint64_t blk_reserved;
 -                      uint64_t blk_used;
 -
 -                      /*
 -                       * Sanity-check for the values in the struct
 -                       */
 -                      /* Check for negative "available" byes. For example UFS can
 -                       * report negative free space for user. Notice. blk_reserved
 -                       * will start to diminish after this. */
 +              /*
 +               * Sanity-check for the values in the struct
 +               */
 +              /* Check for negative "available" byes. For example UFS can
 +               * report negative free space for user. Notice. blk_reserved
 +               * will start to diminish after this. */
  #if HAVE_STATVFS
-               /* Cast is needed to avoid compiler warnings.
 -                      /* Cast and temporary variable are needed to avoid
 -                       * compiler warnings.
 -                       * ((struct statvfs).f_bavail is unsigned (POSIX)) */
 -                      int64_t signed_bavail = (int64_t) statbuf.f_bavail;
 -                      if (signed_bavail < 0)
 -                              statbuf.f_bavail = 0;
++              /* Cast and temporary variable are needed to avoid
++               * compiler warnings.
 +               * ((struct statvfs).f_bavail is unsigned (POSIX)) */
-               if (((int64_t) statbuf.f_bavail) < 0)
++              int64_t signed_bavail = (int64_t) statbuf.f_bavail;
++              if (signed_bavail < 0)
 +                      statbuf.f_bavail = 0;
  #elif HAVE_STATFS
 -                      if (statbuf.f_bavail < 0)
 -                              statbuf.f_bavail = 0;
 +              if (statbuf.f_bavail < 0)
 +                      statbuf.f_bavail = 0;
  #endif
 -                      /* Make sure that f_blocks >= f_bfree >= f_bavail */
 -                      if (statbuf.f_bfree < statbuf.f_bavail)
 -                              statbuf.f_bfree = statbuf.f_bavail;
 -                      if (statbuf.f_blocks < statbuf.f_bfree)
 -                              statbuf.f_blocks = statbuf.f_bfree;
 -
 -                      blk_free = (uint64_t) statbuf.f_bavail;
 -                      blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail);
 -                      blk_used = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree);
 -                      
 -                      df_submit_one (disk_name, "df_complex", "free",
 -                                      (gauge_t) (blk_free * blocksize));
 -                      df_submit_one (disk_name, "df_complex", "reserved",
 -                                      (gauge_t) (blk_reserved * blocksize));
 -                      df_submit_one (disk_name, "df_complex", "used",
 -                                      (gauge_t) (blk_used * blocksize));
 -              }
 -              else /* compatibility code */
 -              {
 -                      gauge_t df_free;
 -                      gauge_t df_used;
 -
 -                      df_free = statbuf.f_bfree * blocksize;
 -                      df_used = (statbuf.f_blocks - statbuf.f_bfree) * blocksize;
 -
 -                      df_submit_two (disk_name, "df", df_used, df_free);
 -              }
 +              /* Make sure that f_blocks >= f_bfree >= f_bavail */
 +              if (statbuf.f_bfree < statbuf.f_bavail)
 +                      statbuf.f_bfree = statbuf.f_bavail;
 +              if (statbuf.f_blocks < statbuf.f_bfree)
 +                      statbuf.f_blocks = statbuf.f_bfree;
 +
 +              blk_free     = (uint64_t) statbuf.f_bavail;
 +              blk_reserved = (uint64_t) (statbuf.f_bfree - statbuf.f_bavail);
 +              blk_used     = (uint64_t) (statbuf.f_blocks - statbuf.f_bfree);
 +
 +              df_submit_one (disk_name, "df_complex", "free",
 +                              (gauge_t) (blk_free * blocksize));
 +              df_submit_one (disk_name, "df_complex", "reserved",
 +                              (gauge_t) (blk_reserved * blocksize));
 +              df_submit_one (disk_name, "df_complex", "used",
 +                              (gauge_t) (blk_used * blocksize));
  
                /* inode handling */
                if (report_inodes)