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