1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#
# 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.
# Christian Schnidrig <christian.schnidrig@bluewin.ch>
# Torrus collector module for combining multiple datasources into one
package Torrus::Collector::CDef;
use strict;
use warnings;
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::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'}} )
{
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 );
}
}
}
return;
}
1;
|