bury all dead whitespace, better off to just do it in one command. i wonder why ss...
[torrus-plus.git] / src / lib / Torrus / ReportGenerator / MonthlySrvUsage.pm
blobccd643a1692b49190461cdbd49a1e93375dc462f
1 # Copyright (C) 2005 Stanislav Sinyagin
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17 # Stanislav Sinyagin <ssinyagin@yahoo.com>
19 # For all service IDs available, build monthly usage figures:
20 # Average, Maximum, and Percentile (default 95th percentile)
23 package Torrus::ReportGenerator::MonthlySrvUsage;
25 use strict;
26 use warnings;
28 use base 'Torrus::ReportGenerator';
30 use POSIX qw(floor);
31 use Date::Parse;
32 use Math::BigFloat;
34 use Torrus::Log;
35 use Torrus::ServiceID;
38 our $VERSION = 1.0;
40 sub isMonthly
42 return 1;
45 sub usesSrvExport
47 return 1;
51 sub generate
53 my $self = shift;
55 my $percentile = $self->{'options'}->{'Percentile'};
56 if( not defined( $percentile ) )
58 $percentile = 95;
61 my $step = $self->{'options'}->{'Step'};
62 if( not defined( $step ) )
64 $step = 300;
67 my $srvIDParams = Torrus::ServiceID->new();
69 my $srvIDs = $self->{'srvexport'}->getServiceIDs();
70 for my $serviceid ( @{$srvIDs} )
72 &Torrus::DB::checkInterrupted();
74 my $data = $self->{'srvexport'}->getIntervalData
75 ( $self->{'StartDate'}, $self->{'EndDate'}, $serviceid );
77 &Torrus::DB::checkInterrupted();
79 next if scalar( @{$data} ) == 0;
80 Debug('MonthlySrvUsage: Generating report for ' . $serviceid);
82 my $params = $srvIDParams->getParams( $serviceid );
84 my @aligned = ();
85 $#aligned = floor( $self->{'RangeSeconds'} / $step );
86 my $nDatapoints = scalar( @aligned );
88 # Fill in the aligned array. For each interval by modulo(step),
89 # we take the maximum value from the available data
91 my $maxVal = 0;
93 for my $row ( @{$data} )
95 my $rowtime = str2time( $row->{'srv_date'} . 'T' .
96 $row->{'srv_time'} );
97 my $pos = floor( ($rowtime - $self->{'StartUnixTime'}) / $step );
98 my $value = Math::BigFloat->new( $row->{'value'} );
99 if( $value->is_nan() )
101 $value->bzero();
102 $row->{'value'} = 0;
105 if( ( not defined( $aligned[$pos] ) ) or
106 $aligned[$pos] < $value )
108 $aligned[$pos] = $value;
109 if( $value > $maxVal )
111 $maxVal = $value;
116 &Torrus::DB::checkInterrupted();
118 # Set undefined values to zero and calculate the average
120 my $sum = Math::BigFloat->new(0);
121 my $unavailCount = 0;
122 for my $pos ( 0 .. $#aligned )
124 if( not defined( $aligned[$pos] ) )
126 $aligned[$pos] = 0;
127 $unavailCount++;
129 else
131 $sum += $aligned[$pos];
135 &Torrus::DB::checkInterrupted();
137 my $avgVal = $sum / $nDatapoints;
139 # Calculate the percentile
141 my @sorted = sort {$a <=> $b} @aligned;
142 my $pcPos = floor( $nDatapoints * $percentile / 100 );
143 my $pcVal = $sorted[$pcPos];
145 # Calculate the total volume if it's a counter
146 my $volume = Math::BigFloat->new(0);
147 my $volumeDefined = 0;
148 if( not defined( $params->{'dstype'} ) or
149 $params->{'dstype'} =~ /^COUNTER/o )
151 $volumeDefined = 1;
152 for my $row ( @{$data} )
154 $volume += $row->{'value'} * $row->{'intvl'};
158 # Adjust units and scale
160 my $usageUnits = '';
161 my $volumeUnits = '';
162 if( not defined( $params->{'units'} ) or
163 $params->{'units'} eq 'bytes' )
165 # Adjust bytes into megabit per second
166 $usageUnits = 'Mbps';
167 $maxVal *= 8e-6;
168 $avgVal *= 8e-6;
169 $pcVal *= 8e-6;
171 # Adjust volume bytes into megabytes
172 $volumeUnits = 'GB';
173 $volume /= 1073741824;
176 $self->{'backend'}->addField( $self->{'reportId'}, {
177 'name' => 'MAX',
178 'serviceid' => $serviceid,
179 'value' => $maxVal,
180 'units' => $usageUnits });
182 $self->{'backend'}->addField( $self->{'reportId'}, {
183 'name' => 'AVG',
184 'serviceid' => $serviceid,
185 'value' => $avgVal,
186 'units' => $usageUnits });
188 $self->{'backend'}->addField( $self->{'reportId'}, {
189 'name' => sprintf('%s%s', $percentile, 'TH_PERCENTILE'),
190 'serviceid' => $serviceid,
191 'value' => $pcVal,
192 'units' => $usageUnits });
194 $self->{'backend'}->addField( $self->{'reportId'}, {
195 'name' => 'UNAVAIL',
196 'serviceid' => $serviceid,
197 'value' => ($unavailCount*100)/$nDatapoints,
198 'units' => '%' });
200 if( $volumeDefined )
202 $self->{'backend'}->addField( $self->{'reportId'}, {
203 'name' => 'VOLUME',
204 'serviceid' => $serviceid,
205 'value' => $volume,
206 'units' => $volumeUnits });
210 &Torrus::DB::checkInterrupted();
212 $self->{'backend'}->finalize( $self->{'reportId'} );
213 return;
221 # Local Variables:
222 # mode: perl
223 # indent-tabs-mode: nil
224 # perl-indent-level: 4
225 # End: