contrib/collection3: Added the ability to `flush' data sets.
authorFlorian Forster <octo@noris.net>
Tue, 19 Aug 2008 14:58:43 +0000 (16:58 +0200)
committerFlorian Forster <octo@noris.net>
Tue, 19 Aug 2008 14:58:43 +0000 (16:58 +0200)
Both, bin/index.cgi and bin/graph.cgi can now send a FLUSH command to
the daemon via the Collectd::Unixsock module. For this to work you will
have to add the path to the UNIX socket of the `unixsock' plugin to the
configuration file `collection.conf'.

The configuration looks like this:
  UnixSockAddr "/var/run/collectd-unixsock"

contrib/collection3/bin/graph.cgi
contrib/collection3/bin/index.cgi
contrib/collection3/etc/collection.conf
contrib/collection3/lib/Collectd/Graph/Common.pm

index 7c29bb0..1524a66 100755 (executable)
@@ -13,7 +13,7 @@ use Collectd::Graph::Config (qw(gc_read_config gc_get_scalar));
 use Collectd::Graph::TypeLoader (qw(tl_load_type));
 
 use Collectd::Graph::Common (qw(sanitize_type get_selected_files
-      epoch_to_rfc1123));
+      epoch_to_rfc1123 flush_files));
 use Collectd::Graph::Type ();
 
 our $Debug = param ('debug');
@@ -134,6 +134,13 @@ elsif ($Begin > $expires)
   $expires = $Begin;
 }
 
+# Send FLUSH command to the daemon if necessary and possible.
+flush_files ($files,
+    begin => $Begin,
+    end => $End,
+    addr => gc_get_scalar ('UnixSockAddr', undef),
+    interval => gc_get_scalar ('Interval', 10));
+
 print STDOUT header (-Content_type => 'image/png',
   -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()),
   -Expires => epoch_to_rfc1123 ($expires));
index d581bfb..be20928 100755 (executable)
@@ -27,11 +27,11 @@ use HTML::Entities ('encode_entities');
 
 use Data::Dumper;
 
-use Collectd::Graph::Config (qw(gc_read_config));
+use Collectd::Graph::Config (qw(gc_read_config gc_get_scalar));
 use Collectd::Graph::TypeLoader (qw(tl_load_type));
 use Collectd::Graph::Common (qw(get_files_from_directory get_all_hosts
       get_timespan_selection get_selected_files get_host_selection
-      get_plugin_selection));
+      get_plugin_selection flush_files));
 use Collectd::Graph::Type ();
 
 our $Debug = param ('debug') ? 1 : 0;
@@ -271,20 +271,28 @@ sub action_show_selection
   start_html ();
   show_selector ();
 
-  my $ident = {};
-
   my $all_files;
+  my $timespan;
+
   my $types = {};
 
   my $id_counter = 0;
 
   $all_files = get_selected_files ();
+  $timespan = get_timespan_selection ();
 
   if ($Debug)
   {
     print "<pre>", Data::Dumper->Dump ([$all_files], ['all_files']), "</pre>\n";
   }
 
+  # Send FLUSH command to the daemon if necessary and possible.
+  flush_files ($all_files,
+      begin => time () - $timespan,
+      end => time (),
+      addr => gc_get_scalar ('UnixSockAddr', undef),
+      interval => gc_get_scalar ('Interval', 10));
+
   for (@$all_files)
   {
     my $file = $_;
@@ -313,8 +321,6 @@ sub action_show_selection
     my $type = $_;
     my $graphs_num = $types->{$type}->getGraphsNum ();
 
-    my $timespan = get_timespan_selection ();
-
     for (my $i = 0; $i < $graphs_num; $i++)
     {
       my $args = $types->{$type}->getGraphArgs ($i);
index 37ea64b..fff3b45 100644 (file)
@@ -1,4 +1,6 @@
 GraphWidth 400
+Interval 10
+UnixSockAddr "/var/run/collectd-unixsock"
 <Type apache_scoreboard>
   Module GenericStacked
   DataSources count
index ec171da..6f26fd8 100644 (file)
@@ -38,6 +38,7 @@ $ColorHalfBlue = 'B7B7F7';
   sort_idents_by_type_instance
   type_to_module_name
   epoch_to_rfc1123
+  flush_files
 ));
 
 our $DataDir = '/var/lib/collectd/rrd';
@@ -582,4 +583,116 @@ sub epoch_to_rfc1123
   return ($string);
 }
 
+sub flush_files
+{
+  my $all_files = shift;
+  my %opts = @_;
+
+  my $begin;
+  my $end;
+  my $addr;
+  my $interval;
+  my $sock;
+  my $now;
+  my $files_to_flush = [];
+  my $status;
+
+  if (!defined $opts{'begin'})
+  {
+    cluck ("begin is not defined");
+    return;
+  }
+  $begin = $opts{'begin'};
+
+  if (!defined $opts{'end'})
+  {
+    cluck ("end is not defined");
+    return;
+  }
+  $end = $opts{'end'};
+
+  if (!$opts{'addr'})
+  {
+    return (1);
+  }
+
+  $interval = $opts{'interval'} || 10;
+
+  if (ref ($all_files) eq 'HASH')
+  {
+    my @tmp = ($all_files);
+    $all_files = \@tmp;
+  }
+
+  $now = time ();
+  # Don't flush anything if the timespan is in the future.
+  if (($end > $now) && ($begin > $now))
+  {
+    return (1);
+  }
+
+  for (@$all_files)
+  {
+    my $file_orig = $_;
+    my $file_name = ident_to_filename ($file_orig);
+    my $file_copy = {};
+    my @statbuf;
+    my $mtime;
+
+    @statbuf = stat ($file_name);
+    if (!@statbuf)
+    {
+      next;
+    }
+    $mtime = $statbuf[9];
+
+    # Skip if file is fresh
+    if (($now - $mtime) <= $interval)
+    {
+      next;
+    }
+    # or $end is before $mtime
+    elsif (($end != 0) && (($end - $mtime) <= 0))
+    {
+      next;
+    }
+
+    $file_copy->{'host'} = $file_orig->{'hostname'};
+    $file_copy->{'plugin'} = $file_orig->{'plugin'};
+    if (exists $file_orig->{'plugin_instance'})
+    {
+      $file_copy->{'plugin_instance'} = $file_orig->{'plugin_instance'}
+    }
+    $file_copy->{'type'} = $file_orig->{'type'};
+    if (exists $file_orig->{'type_instance'})
+    {
+      $file_copy->{'type_instance'} = $file_orig->{'type_instance'}
+    }
+
+    push (@$files_to_flush, $file_copy);
+  } # for (@$all_files)
+
+  if (!@$files_to_flush)
+  {
+    return (1);
+  }
+
+  $sock = Collectd::Unixsock->new ($opts{'addr'});
+  if (!$sock)
+  {
+    return;
+  }
+
+  $status = $sock->flush (plugins => ['rrdtool'], identifier => $files_to_flush);
+  if (!$status)
+  {
+    cluck ("FLUSH failed: " . $sock->{'error'});
+    $sock->destroy ();
+    return;
+  }
+
+  $sock->destroy ();
+  return (1);
+} # flush_files
+
 # vim: set shiftwidth=2 softtabstop=2 tabstop=8 :