File Coverage

blib/lib/Xymon/Server/History.pm
Criterion Covered Total %
statement 57 127 44.8
branch 4 26 15.3
condition 4 27 14.8
subroutine 11 14 78.5
pod 3 4 75.0
total 79 198 39.9


line stmt bran cond sub pod time code
1             package Xymon::Server::History;
2              
3 1     1   47271 use Xymon::Server;
  1         643  
  1         63  
4 1     1   7 use File::Find;
  1         2  
  1         81  
5 1     1   2508 use Time::Local;
  1         2249  
  1         88  
6 1     1   1688 use Data::Dumper;
  1         12479  
  1         91  
7 1     1   964 use Time::Business;
  1         1290  
  1         71  
8              
9 1     1   8 use strict;
  1         2  
  1         33  
10              
11             BEGIN {
12 1     1   6 use Exporter ();
  1         1  
  1         25  
13             use vars
14 1     1   5 qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $month $week $weekday $bustime);
  1         2  
  1         146  
15 1     1   3 $VERSION = '0.20';
16 1         15 @ISA = qw(Exporter);
17              
18             #Give a hoot don't pollute, do not export more than needed by default
19 1         2 @EXPORT = qw();
20 1         2 @EXPORT_OK = qw();
21 1         1676 %EXPORT_TAGS = ();
22             }
23              
24             sub new {
25 1     1 1 19 my ( $class, $param ) = @_;
26 1   33     11 my $self = bless( {}, ref($class) || $class );
27            
28            
29            
30 1         12 my $xymon = Xymon::Server->new( { HOME => $param->{HOME} } );
31              
32 1         97 $bustime = Time::Business->new(
33             {
34             WORKDAYS => $param->{WORKDAYS},
35             STARTTIME => $param->{STARTTIME},
36             ENDTIME => $param->{ENDTIME},
37             }
38             );
39            
40 1   50     55 $self->{RANGESTART} = $param->{RANGESTART} || 0;
41 1   50     12 $self->{RANGEEND} = $param->{RANGEEND} || 9999999999;
42 1   50     8 $self->{MINSECS} = $param->{MINSECS} || 0;
43            
44 1         3 $self->{datadir} = $xymon->{BBVAR};
45 1         11 $month = {
46             Jan => 0,
47             Feb => 1,
48             Mar => 2,
49             Apr => 3,
50             May => 4,
51             Jun => 5,
52             Jul => 6,
53             Aug => 7,
54             Sep => 8,
55             Oct => 9,
56             Nov => 10,
57             Dec => 11
58             };
59 1         8 $week =
60             { Sun => 0, Mon => 1, Tue => 2, Wed => 3, Thu => 4, Fri => 5, Sat => 6 };
61 1         9 $weekday = {
62             0 => 'Sun',
63             1 => 'Mon',
64             2 => 'Tue',
65             3 => 'Wed',
66             4 => 'Thu',
67             5 => 'Fri',
68             6 => 'Sat'
69             };
70 1         5 $self->allEvents($param);
71              
72 1         12 return $self;
73             }
74              
75             sub allEvents {
76              
77 1     1 1 3 my $self = shift;
78 1         3 my $param = shift;
79              
80 1 50       2 my @srvarray = @{ $param->{SERVERS} || [] };
  1         27  
81 1 50       2 my @tests = @{ $param->{TESTS} || [] };
  1         7  
82              
83 1         2 my $count = 0;
84              
85             #
86             # setup hash of servers for faster find comparison
87             #
88 1         3 my $servers = {};
89 1 50       11 if ( @srvarray > 0 ) {
90 0         0 foreach my $server (@srvarray) {
91 0         0 $servers->{$server} = 1;
92             }
93             }
94              
95             #
96             # setup hash of tests for faster find comparison
97             #
98 1         3 my $tests = {};
99 1 50       5 if ( @tests > 0 ) {
100 0         0 foreach my $test (@tests) {
101 0         0 $tests->{$test} = 1;
102             }
103             }
104              
105 1         6 my @dirdepth = split /\//, "$self->{datadir}/histlogs";
106 1         4 my $depth = @dirdepth;
107            
108             find(
109             sub {
110              
111 0     0   0 my $t = $File::Find::name;
112            
113            
114 0         0 my @words = split /\//, $t;
115 0         0 my $length = @words;
116              
117 0 0       0 if ( $length > $depth + 2 ) {
118            
119 0         0 my $server = $words[$depth];
120 0         0 my $test = $words[ $depth + 1 ];
121 0         0 my $filename = $words[ $depth + 2 ];
122            
123 0 0 0     0 if ( $servers->{$server} == 1 || @srvarray == 0 ) {
124              
125 0 0 0     0 if ( $tests->{$test} == 1 || @tests == 0 ) {
126            
127 0         0 $self->{history}->{$server}->{$test}->{$filename}
128             ->{filename} =
129             $self->{datadir}
130             . "/histlogs/"
131             . $server . "/"
132             . $test . "/"
133             . $filename;
134              
135 0         0 my @dt = split( /_/, $filename );
136 0         0 my @time = split( /:/, $dt[3] );
137              
138 0         0 $self->{history}->{$server}->{$test}->{$filename}
139             ->{day} = $week->{ $dt[0] };
140              
141 0         0 $self->{history}->{$server}->{$test}->{$filename}
142             ->{time} = (
143             timelocal(
144             $time[2], $time[1],
145             $time[0], $dt[2],
146             $month->{ $dt[1] }, $dt[4] - 1900
147             )
148             );
149              
150             }
151             }
152             }
153              
154             },
155 1         279 $self->{datadir} . "/histlogs/"
156             );
157 1         22 return $self->{history};
158             }
159              
160             sub outagelist {
161              
162 0     0 1   my $self = shift;
163 0           my $param = shift;
164              
165 0           $self->{outages} = {};
166              
167 0           my $hist_hashref;
168 0 0         if ( defined $self->{history} ) {
169 0           $hist_hashref = $self->{history};
170             }
171             else {
172 0           $hist_hashref = $self->allEvents($param);
173             }
174              
175 0           my ($hostname,$test,$evtref,$ref,$file);
176 0           foreach $hostname ( keys %{$hist_hashref} ) {
  0            
177 0           my $endtestcolor;
178            
179 0           foreach $test ( keys %{ $hist_hashref->{$hostname} } ) {
  0            
180 0           $ref = $hist_hashref->{$hostname}->{$test};
181              
182 0           my $startcolor;
183             my $endcolor;
184 0           $evtref = {};
185 0           foreach $file ( sort { $ref->{$a}->{time} <=> $ref->{$b}->{time} } keys %{$ref} )
  0            
  0            
186             {
187 0           open( my $evtfile, "<", $ref->{$file}->{filename} );
188 0           my $eventline = <$evtfile>;
189 0           chomp $eventline;
190              
191 0           my $color = ( split / /, $eventline )[0];
192 0           $endtestcolor = $color;
193 0 0 0       if( $test eq "conn" && $hostname eq "oranprodbsirt1" ) {
194 0           print "$ref->{$file}->{time} $hostname $color \n";
195             }
196 0 0 0       if ( $color eq "red" && $startcolor ne "red" ) {
    0 0        
197 0           $startcolor = "red";
198              
199 0           $evtref = $ref->{$file};
200              
201             }
202             elsif ( $color ne "red" && $startcolor eq "red" ) {
203              
204 0           $endcolor = $color;
205              
206             my (
207 0           $sec, $min, $hour, $mday, $mon,
208             $year, $wday, $yday, $isdst
209             ) = localtime( $evtref->{time} );
210 0           my $start24 = $hour * 100 + $min;
211              
212             (
213 0           $sec, $min, $hour, $mday, $mon,
214             $year, $wday, $yday, $isdst
215             ) = localtime( $ref->{$file}->{time} );
216 0           my $end24 = $hour * 100 + $min;
217            
218 0 0 0       if($evtref->{time} >= $self->{RANGESTART} && $evtref->{time} <= $self->{RANGEEND}) {
219              
220 0           add_outage($self,$hostname,$test,$evtref,$ref,$file);
221              
222             }
223            
224 0           $startcolor = "";
225 0           $endcolor = "";
226             }
227              
228            
229 0           close($evtfile);
230              
231             }
232            
233             #
234             # Status is still red, add an outage that extends up until now
235             #
236            
237 0 0         if( $endtestcolor eq "red" ) {
238 0           $ref->{$file}->{time} = time();
239 0           add_outage($self,$hostname,$test,$evtref,$ref,$file,"Still Down");
240            
241             }
242            
243            
244             }
245             }
246            
247            
248 0           return $self->{outages};
249              
250             }
251              
252             #
253             # add an outage to the hashref
254             #
255             sub add_outage {
256            
257 0     0 0   my $self=shift;
258 0           my $hostname = shift;
259 0           my $test = shift;
260 0           my $evtref=shift;
261 0           my $ref=shift;
262 0           my $file=shift;
263 0           my $comment = shift;
264            
265            
266            
267 0           my $bussecs = $bustime->duration( $evtref->{time},$ref->{$file}->{time} );
268            
269 0           $self->{outages}->{ "$hostname.$test.$evtref->{time}" } = {
270            
271             server => $hostname,
272             test => $test,
273             starttime => $evtref->{time},
274             endtime => $ref->{$file}->{time},
275             duration => $ref->{$file}->{time} - $evtref->{time},
276             bussecs => $bussecs,
277             busstring => $bustime->workTimeString($bussecs),
278             filename => $ref->{$file}->{filename},
279             comment => $comment
280            
281             };
282            
283             }
284              
285             =head1 NAME
286              
287             Xymon::Server::History - Return a hash of Xymon events history
288              
289             =head1 SYNOPSIS
290              
291             use Xymon::Server::History;
292            
293             my $history = Xymon::Server::History->new({HOME=>'/home/hobbit'})
294              
295              
296             =head1 DESCRIPTION
297              
298             Various methods for returning differents views of the event data stored
299             in $HOBBITHOME/data/histlogs/
300              
301             Be aware that this can take considerable time to run if there are a large
302             number of servers and events as it has to troll through the histlogs dir
303             and look for events.
304              
305             =head1 METHODS
306              
307             =head2 new({...})
308              
309             Instantiates the object.
310              
311             You must pass it the HOME dir for hobbit. (One level below server).
312              
313             my $history = Xymon::Server::History->new({
314             HOME=>'/home/hobbit/server',
315             SERVERS => ['oranprodsys'],
316             TESTS => ['conn'],
317             STARTTIME => "9:00",
318             ENDTIME => "17:00",
319             WORKDAYS => [1,2,3,4,5],
320             RANGESTART => time()-86400*7,
321             RANGEEND => time(),
322             MINSECS => 300
323             });
324              
325             =head2 allEvents({....})
326              
327             Returns a hash of events with following structure:
328              
329             {
330             server1 => {
331             conn => {
332             "file1"=>{
333             filename => "fullfilename"
334             time => "time in unix format"
335             }
336             "file2" => {
337             filename => "fullfilename"
338             time => "time in unix format"
339             }
340             },
341              
342             server2 => {
343             uptime => "file1"=>{
344             filename => "fullfilename"
345             time => "time in unix format"
346             }
347             "file2" => {
348             filename => "fullfilename"
349             time => "time in unix format"
350             }
351             }
352             }
353              
354             allEvents() will return events for all servers and tests.
355             This may be filter by passing an array of servers,
356             and an array of tests in order to filter the results eg:
357              
358             allEvents({
359             SERVERS => ["servername1","servername2"],
360             TESTS => ["conn","uptime"]
361             })
362              
363             The filename of the event is in the format: Fri_Dec_14_16:56:14_2007
364              
365             =head2 outagelist()
366            
367            
368             Returns a list of outages from red to non-red in the following format
369            
370             'oranprodsys.conn.1265337130' => {
371            
372             'test' => 'conn',
373             'server' => 'hostname',
374             'filename' => '/home/hobbit/data/histlogs/server1/conn/Fri_Feb_5_13:56:05_2010',
375             'starttime' => 1265337130,
376             'busstring' => '0 days 0 hours 23 minutes',
377             'duration' => 1435,
378             'endtime' => 1265338565,
379             'server' => 'server1',
380             'bussecs' => 1435,
381             'comment' => 'Still Down'
382            
383             },
384            
385            
386             =head1 AUTHOR
387              
388             David Peters
389             CPAN ID: DAVIDP
390             davidp@electronf.com
391             http://www.electronf.com
392              
393             =head1 COPYRIGHT
394              
395             This program is free software; you can redistribute
396             it and/or modify it under the same terms as Perl itself.
397              
398             The full text of the license can be found in the
399             LICENSE file included with this module.
400              
401              
402             =head1 SEE ALSO
403              
404             perl(1).
405              
406             =cut
407              
408             #################### main pod documentation end ###################
409              
410             1;
411              
412             # The preceding line will help the module return a true value
413