# # 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 # 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;