summaryrefslogtreecommitdiff
path: root/torrus/perllib/Torrus/Collector/CDef.pm
blob: 28dff8a9a223cd68f3f41bc7234c83de44e0e967 (plain)
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;