contrib/collection3: Add the "DataDir" config option.
[collectd.git] / contrib / collection3 / lib / Collectd / Graph / Common.pm
index ec171da..0deefd6 100644 (file)
@@ -5,9 +5,11 @@ use warnings;
 
 use vars (qw($ColorCanvas $ColorFullBlue $ColorHalfBlue));
 
+use Collectd::Unixsock ();
 use Carp (qw(confess cluck));
 use CGI (':cgi');
 use Exporter;
+use Collectd::Graph::Config (qw(gc_get_scalar));
 
 $ColorCanvas   = 'FFFFFF';
 $ColorFullBlue = '0000FF';
@@ -38,9 +40,10 @@ $ColorHalfBlue = 'B7B7F7';
   sort_idents_by_type_instance
   type_to_module_name
   epoch_to_rfc1123
+  flush_files
 ));
 
-our $DataDir = '/var/lib/collectd/rrd';
+our $DefaultDataDir = '/var/lib/collectd/rrd';
 
 return (1);
 
@@ -143,6 +146,7 @@ sub filename_to_ident
 sub ident_to_filename
 {
   my $ident = shift;
+  my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir);
 
   my $ret = '';
 
@@ -152,7 +156,7 @@ sub ident_to_filename
   }
   else
   {
-    $ret .= "$DataDir/";
+    $ret .= "$data_dir/";
   }
 
   if (!$ident->{'hostname'})
@@ -254,12 +258,13 @@ sub get_all_hosts
 {
   my $dh;
   my @ret = ();
+  my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir);
 
-  opendir ($dh, "$DataDir") or confess ("opendir ($DataDir): $!");
+  opendir ($dh, "$data_dir") or confess ("opendir ($data_dir): $!");
   while (my $entry = readdir ($dh))
   {
     next if ($entry =~ m/^\./);
-    next if (!-d "$DataDir/$entry");
+    next if (!-d "$data_dir/$entry");
     push (@ret, sanitize_hostname ($entry));
   }
   closedir ($dh);
@@ -283,6 +288,7 @@ sub get_all_plugins
   my @hosts = @_;
   my $ret = {};
   my $dh;
+  my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir);
 
   if (!@hosts)
   {
@@ -292,14 +298,14 @@ sub get_all_plugins
   for (@hosts)
   {
     my $host = $_;
-    opendir ($dh, "$DataDir/$host") or next;
+    opendir ($dh, "$data_dir/$host") or next;
     while (my $entry = readdir ($dh))
     {
       my $plugin;
       my $plugin_instance = '';
 
       next if ($entry =~ m/^\./);
-      next if (!-d "$DataDir/$host/$entry");
+      next if (!-d "$data_dir/$host/$entry");
 
       if ($entry =~ m#^([^-]+)-(.+)$#)
       {
@@ -335,7 +341,8 @@ sub get_all_plugins
 sub get_files_for_host
 {
   my $host = sanitize_hostname (shift);
-  return (get_files_from_directory ("$DataDir/$host", 2));
+  my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir);
+  return (get_files_from_directory ("$data_dir/$host", 2));
 } # get_files_for_host
 
 sub _filter_ident
@@ -381,6 +388,7 @@ sub get_files_by_ident
   my $ident = shift;
   my $all_files;
   my @ret = ();
+  my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir);
 
   #if ($ident->{'hostname'})
   #{
@@ -388,7 +396,7 @@ sub get_files_by_ident
   #}
   #else
   #{
-    $all_files = get_files_from_directory ($DataDir, 3);
+    $all_files = get_files_from_directory ($data_dir, 3);
     #}
 
   @ret = grep { _filter_ident ($ident, $_) == 0 } (@$all_files);
@@ -582,4 +590,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 :