12 |
use CGI::Carp qw(fatalsToBrowser); |
use CGI::Carp qw(fatalsToBrowser); |
13 |
use Data::Sorting qw(:arrays); |
use Data::Sorting qw(:arrays); |
14 |
use Time::ParseDate; |
use Time::ParseDate; |
15 |
|
use Time::Available; |
16 |
|
|
17 |
use Data::Dumper; |
use Data::Dumper; |
18 |
|
|
23 |
my $to_date = "now"; |
my $to_date = "now"; |
24 |
|
|
25 |
# working days definition (1-7; mon=1) |
# working days definition (1-7; mon=1) |
26 |
my $wday_start = 1; |
my $dayMask = Time::Available::DAY_WEEKDAY; |
|
my $wday_end = 5; |
|
27 |
# working hours |
# working hours |
28 |
my $whours_start = "7:00"; |
my $from_time_interval = "7:00"; |
29 |
my $whours_end = "17:00"; |
my $to_time_interval = "17:00"; |
30 |
|
|
31 |
my $debug=1; |
my $debug=1; |
32 |
$debug++ if (grep(/-v/,@ARGV)); |
$debug++ if (grep(/-v/,@ARGV)); |
33 |
$debug++ if (grep(/-d/,@ARGV)); |
$debug++ if (grep(/-d/,@ARGV)); |
34 |
|
|
35 |
|
my %days = ( |
36 |
|
Time::Available::DAY_MONDAY=>'Mo', |
37 |
|
Time::Available::DAY_TUESDAY=>'Tu', |
38 |
|
Time::Available::DAY_WEDNESDAY=>'We', |
39 |
|
Time::Available::DAY_THURSDAY=>'Th', |
40 |
|
Time::Available::DAY_FRIDAY=>'Fr', |
41 |
|
Time::Available::DAY_SATURDAY=>'Sa', |
42 |
|
Time::Available::DAY_SUNDAY=>'Su' |
43 |
|
); |
44 |
|
|
45 |
my $q = new CGI; |
my $q = new CGI; |
46 |
|
|
47 |
my $print_orphans = $q->param('print_orphans') || 0; |
my $print_orphans = $q->param('print_orphans') || 0; |
48 |
my $rep_reset = $q->param('rep_reset') || 0; |
my $rep_reset = $q->param('rep_reset') || 0; |
49 |
my @sg_selected = $q->param('sg_filter'); |
my @sg_selected = $q->param('sg_filter'); |
50 |
|
|
51 |
|
# init misc sort parametars |
52 |
my @sort; |
my @sort; |
53 |
my $order; |
my $order; |
54 |
my %sort_param; |
my %sort_param; |
64 |
@sort = ( -compare => 'numeric', -order=>'reverse', $sort_param{'dsort'} ); |
@sort = ( -compare => 'numeric', -order=>'reverse', $sort_param{'dsort'} ); |
65 |
} |
} |
66 |
|
|
67 |
|
# make interval |
68 |
|
my $working_days; |
69 |
|
if ($q->param('use_time_limit')) { |
70 |
|
$dayMask=0; |
71 |
|
foreach my $dm ($q->param('day_interval')) { |
72 |
|
$dayMask |= $dm; |
73 |
|
} |
74 |
|
$working_days=new Time::Available(start=>$q->param('from_time_interval'),end=>$q->param('to_time_interval'),dayMask=>$dayMask); |
75 |
|
} |
76 |
|
|
77 |
# |
# |
78 |
# This option (activated via command switch -r) will reset failure duration |
# This option (activated via command switch -r) will reset failure duration |
79 |
# if repeated failure on same group/service happend. |
# if repeated failure on same group/service happend. |
85 |
# pretty format date |
# pretty format date |
86 |
sub d { |
sub d { |
87 |
my $utime = shift || return "?"; |
my $utime = shift || return "?"; |
88 |
return strftime($date_time_fmt,localtime($utime)); |
if ($debug) { |
89 |
|
return strftime($date_time_fmt." [%s]",localtime($utime)); |
90 |
|
} else { |
91 |
|
return strftime($date_time_fmt,localtime($utime)); |
92 |
|
} |
93 |
} |
} |
94 |
# pretty format duration |
# pretty format duration |
95 |
sub dur { |
sub dur { |
96 |
my $dur = shift || return "?"; |
my $dur = shift || return "0"; |
97 |
my $out = ""; |
my $out = ""; |
98 |
|
|
99 |
my $s = $dur; |
my $s = $dur; |
137 |
if (grep(m;$group/$service;,@sg_selected)) { |
if (grep(m;$group/$service;,@sg_selected)) { |
138 |
push @data, { |
push @data, { |
139 |
'sg'=>"$group/$service", |
'sg'=>"$group/$service", |
140 |
'from_time'=>$fail{$id}, |
'from'=>$fail{$id}, |
141 |
'to_time'=>$utime, |
'to'=>$utime, |
142 |
'dur_time'=>($utime - $fail{$id}), |
'dur'=>($utime - $fail{$id}), |
143 |
'from'=>d($fail{$id}), |
'int'=>$working_days->interval($utime,$fail{$id}), |
|
'to'=>d($utime), |
|
|
'dur'=>dur($utime - $fail{$id}), |
|
144 |
'desc'=>$desc }; |
'desc'=>$desc }; |
145 |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
146 |
$sg_count{"$group/$service"}++; |
$sg_count{"$group/$service"}++; |
151 |
if ($print_orphans && grep(m;$group/$service;,@sg_selected)) { |
if ($print_orphans && grep(m;$group/$service;,@sg_selected)) { |
152 |
push @data, { |
push @data, { |
153 |
'sg'=>"$group/$service", |
'sg'=>"$group/$service", |
154 |
'to_time'=>$utime, |
'from'=>-1, |
155 |
'from'=>'unknown', |
'to'=>$utime, |
|
'to'=>d($utime), |
|
|
'dur'=>'unknown', |
|
156 |
'desc'=>$desc }; |
'desc'=>$desc }; |
157 |
$sg_count{"$group/$service"}++; |
$sg_count{"$group/$service"}++; |
158 |
} |
} |
162 |
if ($rep_reset && grep(m;$group/$service;,@sg_selected)) { |
if ($rep_reset && grep(m;$group/$service;,@sg_selected)) { |
163 |
push @data, { |
push @data, { |
164 |
'sg'=>"$group/$service", |
'sg'=>"$group/$service", |
165 |
'from_time'=>$fail{$id}, |
'from'=>$fail{$id}, |
166 |
'to_time'=>$utime, |
'to'=>$utime, |
167 |
'dur_time'=>($utime - $fail{$id}), |
'dur'=>($utime - $fail{$id}), |
168 |
'from'=>d($fail{$id}), |
'int'=>$working_days->interval($utime,$fail{$id}), |
|
'to'=>d($utime), |
|
|
'dur'=>dur($utime - $fail{$id}), |
|
169 |
'desc'=>'[failure again]'}; |
'desc'=>'[failure again]'}; |
170 |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
171 |
$fail{$id} = $utime; |
$fail{$id} = $utime; |
210 |
$q->textfield(-name=>'to_date',-size=>20,-default=>$to_date), |
$q->textfield(-name=>'to_date',-size=>20,-default=>$to_date), |
211 |
small('Using <a href="http://search.cpan.org/search?mode=module&query=Time::ParseDate">Time::ParseDate</a>'), |
small('Using <a href="http://search.cpan.org/search?mode=module&query=Time::ParseDate">Time::ParseDate</a>'), |
212 |
br, |
br, |
213 |
|
$q->checkbox(-name=>'use_time_limit',-checked=>1, |
214 |
|
-label=>"use time limit for each day:"), |
215 |
|
$q->textfield(-name=>'from_time_interval',-size=>8,-default=>$from_time_interval), |
216 |
|
" to: ", |
217 |
|
$q->textfield(-name=>'to_time_interval',-size=>8,-default=>$to_time_interval), |
218 |
|
br,"Days: ", |
219 |
|
$q->checkbox_group(-name=>'day_interval', |
220 |
|
-values=>[ sort { $a <=> $b } keys %days ], |
221 |
|
-labels=>\%days, |
222 |
|
-defaults=>[ |
223 |
|
Time::Available::DAY_MONDAY, |
224 |
|
Time::Available::DAY_TUESDAY, |
225 |
|
Time::Available::DAY_WEDNESDAY, |
226 |
|
Time::Available::DAY_THURSDAY, |
227 |
|
Time::Available::DAY_FRIDAY, |
228 |
|
] |
229 |
|
), |
230 |
$q->submit(-name=>'show',-value=>'Show report'), |
$q->submit(-name=>'show',-value=>'Show report'), |
231 |
)),end_table; |
)),end_table; |
232 |
|
|
260 |
my @sorted = sorted_array(@data, @sort); |
my @sorted = sorted_array(@data, @sort); |
261 |
#my @sorted = @data; |
#my @sorted = @data; |
262 |
|
|
263 |
print "-- sort: ",Dumper(@sort)," (data: ".@data." sorted: ".@sorted.") --\n",br if ($debug); |
print "-- sort: ",Dumper(@sort)," (data: ".@data." sorted: ".@sorted.") --\n",br,"-- dayMask: $dayMask --\n",br if ($debug); |
264 |
|
|
265 |
print start_table({-border=>1,-cellspacing=>0,-cellpadding=>2,-width=>'100%'}); |
print start_table({-border=>1,-cellspacing=>0,-cellpadding=>2,-width=>'100%'}); |
266 |
|
|
267 |
print Tr( |
print Tr( |
268 |
th("group/service"), |
th("group/service"), |
269 |
th({-bgcolor=>'#f0f0f0'}, |
th({-bgcolor=>'#f0f0f0'}, |
270 |
&sort_link($q,'from_time','u').' from '. |
&sort_link($q,'from','u').' from '. |
271 |
&sort_link($q,'from_time','d'), |
&sort_link($q,'from','d'), |
272 |
br,$from_html |
br,$from_html |
273 |
), |
), |
274 |
th( |
th( |
275 |
&sort_link($q,'to_time','u').' to '. |
&sort_link($q,'to','u').' to '. |
276 |
&sort_link($q,'to_time','d'), |
&sort_link($q,'to','d'), |
277 |
br,$to_html |
br,$to_html |
278 |
), |
), |
279 |
th({-bgcolor=>'#e0e0e0'}, |
th({-bgcolor=>'#e0e0e0'}, |
280 |
&sort_link($q,'dur_time','u').' duration '. |
&sort_link($q,'dur','u').' duration '. |
281 |
&sort_link($q,'dur_time','d') |
&sort_link($q,'dur','d') |
282 |
), |
), |
283 |
th("description") |
th("description") |
284 |
) if (scalar @sorted > 0); |
) if (scalar @sorted > 0); |
285 |
|
|
286 |
foreach my $row (@sorted) { |
foreach my $row (@sorted) { |
287 |
next if ($q->param('use_date_limit') && ($row->{from_time} < $from_time || $row->{to_time} > $to_time)); |
next if ($q->param('use_date_limit') && ($row->{from} < $from_time || $row->{to} > $to_time)); |
288 |
|
my ($from,$dur,$int) = ('unknown','unknown','unknown'); |
289 |
|
if ($row->{from} != -1 ) { |
290 |
|
$from = d($row->{from}); |
291 |
|
$dur = dur($row->{dur}); |
292 |
|
$int = dur($row->{int}); |
293 |
|
} |
294 |
print Tr( |
print Tr( |
295 |
td({-align=>'left',-valign=>'center'},$row->{sg}), |
td({-align=>'left',-valign=>'center'},$row->{sg}), |
296 |
td({-align=>'right',-bgcolor=>'#f0f0f0'},$row->{from}), |
td({-align=>'right',-bgcolor=>'#f0f0f0'},$from), |
297 |
td({-align=>'right'},$row->{to}), |
td({-align=>'right'},d($row->{to})), |
298 |
td({-align=>'center',-bgcolor=>'#e0e0e0'},$row->{dur}), |
td({-align=>'center',-bgcolor=>'#e0e0e0'},$dur), |
299 |
|
td({-align=>'center',-bgcolor=>'#e0e0e0'},$int), |
300 |
td({-align=>'left'},$row->{desc}), |
td({-align=>'left'},$row->{desc}), |
301 |
),"\n"; |
),"\n"; |
302 |
} |
} |