import torrus 1.0.9
[freeside.git] / torrus / perllib / Torrus / Collector / CDef.pm
diff --git a/torrus/perllib/Torrus/Collector/CDef.pm b/torrus/perllib/Torrus/Collector/CDef.pm
new file mode 100644 (file)
index 0000000..28dff8a
--- /dev/null
@@ -0,0 +1,120 @@
+#
+#  Copyright (C) 2004-2005  Christian Schnidrig
+#  Copyright (C) 2007  Stanislav Sinyagin
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# $Id: CDef.pm,v 1.1 2010-12-27 00:03:57 ivan Exp $
+# Christian Schnidrig <christian.schnidrig@bluewin.ch>
+
+
+# Torrus collector module for combining multiple datasources into one
+
+package Torrus::Collector::CDef;
+
+use strict;
+
+use Torrus::Collector::CDef_Params;
+use Torrus::ConfigTree;
+use Torrus::Log;
+use Torrus::RPN;
+use Torrus::DataAccess;
+use Torrus::Collector::RRDStorage;
+
+# Register the collector type
+$Torrus::Collector::collectorTypes{'cdef'} = 1;
+
+# List of needed parameters and default values
+$Torrus::Collector::params{'cdef'} = \%Torrus::Collector::CDef_Params::params;
+$Torrus::Collector::initTarget{'cdef'} = \&Torrus::Collector::CDef::initTarget;
+
+
+# get access to the configTree;
+$Torrus::Collector::needsConfigTree{'cdef'}{'runCollector'} = 1;
+
+sub initTarget
+{
+    my $collector = shift;
+    my $token = shift;
+    
+    my $cref = $collector->collectorData( 'cdef' );
+    if( not defined( $cref->{'crefTokens'} ) )
+    {
+        $cref->{'crefTokens'} = [];
+    }
+
+    push( @{$cref->{'crefTokens'}}, $token );
+    
+    return 1;
+}
+
+# This is first executed per target
+$Torrus::Collector::runCollector{'cdef'} =
+    \&Torrus::Collector::CDef::runCollector;
+
+sub runCollector
+{
+    my $collector = shift;
+    my $cref = shift;
+    my $config_tree = $collector->configTree();
+
+    my $now = time();
+    my $da = new Torrus::DataAccess;
+
+    # By default, try to get the data from one period behind
+    my $defaultAccessTime = $now -
+        ( $now % $collector->period() ) + $collector->offset();
+    
+    foreach my $token ( @{$cref->{'crefTokens'}} )
+    {
+        &Torrus::DB::checkInterrupted();
+        
+        my $accessTime = $defaultAccessTime -
+            ( $collector->period() *
+              $collector->param( $token, 'cdef-collector-delay' ) );
+
+        # The RRDtool is non-reentrant, and we need to be careful
+        # when running multiple threads
+        Torrus::Collector::RRDStorage::semaphoreDown();
+        
+        my ($value, $timestamp) =
+            $da->read_RPN( $config_tree, $token,
+                           $collector->param( $token, 'rpn-expr' ),
+                           $accessTime );
+
+        Torrus::Collector::RRDStorage::semaphoreUp();
+
+        if( defined( $value ) )
+        {
+            if ( $timestamp <
+                 ( $accessTime -
+                   ( $collector->period() *
+                     $collector->param( $token, 'cdef-collector-tolerance' ))))
+            {
+                Error( "CDEF: Data is " . ($accessTime-$timestamp) .
+                       " seconds too old for " . $collector->path($token) );
+            }
+            else
+            {
+                $collector->setValue( $token, $value, $timestamp );
+            }
+        }
+    }
+}
+
+
+
+1;
+