13 |
use Data::Sorting qw(:arrays); |
use Data::Sorting qw(:arrays); |
14 |
use Time::ParseDate; |
use Time::ParseDate; |
15 |
use Time::Available; |
use Time::Available; |
16 |
|
use Cache::FileCache; |
17 |
|
|
18 |
use Data::Dumper; |
use Data::Dumper; |
19 |
|
|
75 |
$working_days=new Time::Available(start=>$q->param('from_time_interval'),end=>$q->param('to_time_interval'),dayMask=>$dayMask); |
$working_days=new Time::Available(start=>$q->param('from_time_interval'),end=>$q->param('to_time_interval'),dayMask=>$dayMask); |
76 |
} |
} |
77 |
|
|
78 |
|
# init cache and setup expriration |
79 |
|
my $cache = new Cache::FileCache({ default_expires_in => '10 min' }); |
80 |
|
|
81 |
# |
# |
82 |
# This option (activated via command switch -r) will reset failure duration |
# This option (activated via command switch -r) will reset failure duration |
83 |
# if repeated failure on same group/service happend. |
# if repeated failure on same group/service happend. |
122 |
# |
# |
123 |
|
|
124 |
my %fail; |
my %fail; |
125 |
my %downtime; # total downtime |
my $downtime; # total downtime |
126 |
my %sg_filter; # filter for service/group |
my $sg_filter; # filter for service/group |
127 |
my %sg_count; # count number of downtimes |
my $sg_count; # count number of downtimes |
128 |
|
|
129 |
my $log_file="/home/dpavlin/mon-log/sap.log"; |
my $log_file="/var/log/mon/sap.log"; |
130 |
|
|
131 |
my @data; |
my $data; |
132 |
|
|
133 |
open(LOG, $log_file) || die "$log_file: $!"; |
# generate unique key for this data and options |
134 |
|
my $cache_key="monlog".join("",@sg_selected).$print_orphans.$rep_reset; |
135 |
while(<LOG>) { |
|
136 |
chomp; |
if (! $debug) { |
137 |
if (/^(failure|up)\s+(\S+)\s+(\S+)\s+(\d+)\s+\(([^)]+)\)\s+(.+)$/) { |
$data = $cache->get( $cache_key ); |
138 |
my ($status,$group,$service,$utime,$date,$desc) = ($1,$2,$3,$4,$5,$6); |
$downtime = $cache->get("downtime $cache_key"); |
139 |
my $id = "$group/$service"; |
$sg_filter = $cache->get("sg_filter $cache_key"); |
140 |
if ($status eq "up" && defined($fail{$id})) { |
$sg_count = $cache->get("sg_count $cache_key"); |
141 |
if (grep(m;$group/$service;,@sg_selected)) { |
} |
142 |
push @data, { |
|
143 |
'sg'=>"$group/$service", |
if (!$data || !$downtime || !$sg_filter || !$sg_count) { |
144 |
'from'=>$fail{$id}, |
|
145 |
'to'=>$utime, |
open(LOG, $log_file) || die "$log_file: $!"; |
146 |
'dur'=>($utime - $fail{$id}), |
|
147 |
'int'=>$working_days->interval($utime,$fail{$id}), |
while(<LOG>) { |
148 |
'desc'=>$desc }; |
chomp; |
149 |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
if (/^(failure|up)\s+(\S+)\s+(\S+)\s+(\d+)\s+\(([^)]+)\)\s+(.+)$/) { |
150 |
$sg_count{"$group/$service"}++; |
my ($status,$group,$service,$utime,$date,$desc) = ($1,$2,$3,$4,$5,$6); |
151 |
} |
my $id = "$group/$service"; |
152 |
$sg_filter{"$group/$service"}++; |
if ($status eq "up" && defined($fail{$id})) { |
153 |
delete $fail{$id}; |
if (grep(m;$group/$service;,@sg_selected)) { |
154 |
} elsif ($status eq "up") { |
push @$data, { |
155 |
if ($print_orphans && grep(m;$group/$service;,@sg_selected)) { |
'sg'=>"$group/$service", |
156 |
push @data, { |
'from'=>$fail{$id}, |
157 |
'sg'=>"$group/$service", |
'to'=>$utime, |
158 |
'from'=>-1, |
'desc'=>$desc }; |
159 |
'to'=>$utime, |
$downtime->{"$group/$service"} += ($utime - $fail{$id}), |
160 |
'desc'=>$desc }; |
$sg_count->{"$group/$service"}++; |
161 |
$sg_count{"$group/$service"}++; |
} |
162 |
} |
$sg_filter->{"$group/$service"}++; |
163 |
delete $fail{$id}; |
delete $fail{$id}; |
164 |
$sg_filter{"$group/$service"}++; |
} elsif ($status eq "up") { |
165 |
} elsif (defined($fail{$id})) { |
if ($print_orphans && grep(m;$group/$service;,@sg_selected)) { |
166 |
if ($rep_reset && grep(m;$group/$service;,@sg_selected)) { |
push @$data, { |
167 |
push @data, { |
'sg'=>"$group/$service", |
168 |
'sg'=>"$group/$service", |
'from'=>-1, |
169 |
'from'=>$fail{$id}, |
'to'=>$utime, |
170 |
'to'=>$utime, |
'desc'=>$desc }; |
171 |
'dur'=>($utime - $fail{$id}), |
$sg_count->{"$group/$service"}++; |
172 |
'int'=>$working_days->interval($utime,$fail{$id}), |
} |
173 |
'desc'=>'[failure again]'}; |
delete $fail{$id}; |
174 |
$downtime{"$group/$service"} += ($utime - $fail{$id}), |
$sg_filter->{"$group/$service"}++; |
175 |
|
} elsif (defined($fail{$id})) { |
176 |
|
if ($rep_reset && grep(m;$group/$service;,@sg_selected)) { |
177 |
|
push @$data, { |
178 |
|
'sg'=>"$group/$service", |
179 |
|
'from'=>$fail{$id}, |
180 |
|
'to'=>$utime, |
181 |
|
'desc'=>'[failure again]'}; |
182 |
|
$downtime->{"$group/$service"} += ($utime - $fail{$id}), |
183 |
|
$fail{$id} = $utime; |
184 |
|
$sg_count->{"$group/$service"}++; |
185 |
|
} |
186 |
|
$sg_filter->{"$group/$service"}++; |
187 |
|
} else { |
188 |
$fail{$id} = $utime; |
$fail{$id} = $utime; |
|
$sg_count{"$group/$service"}++; |
|
189 |
} |
} |
|
$sg_filter{"$group/$service"}++; |
|
|
} else { |
|
|
$fail{$id} = $utime; |
|
190 |
} |
} |
191 |
} |
} |
192 |
|
close(LOG); |
193 |
|
|
194 |
|
$cache->set($cache_key, $data); |
195 |
|
$cache->set("downtime $cache_key", $downtime); |
196 |
|
$cache->set("sg_filter $cache_key", $sg_filter); |
197 |
|
$cache->set("sg_count $cache_key", $sg_count); |
198 |
|
|
199 |
} |
} |
|
close(LOG); |
|
200 |
|
|
201 |
# generate output |
# generate output |
202 |
# |
# |
210 |
Tr(td( |
Tr(td( |
211 |
em("Show just service/group:"),br, |
em("Show just service/group:"),br, |
212 |
checkbox_group(-name=>'sg_filter', |
checkbox_group(-name=>'sg_filter', |
213 |
-values=>[keys %sg_filter], |
-values=>[keys %$sg_filter], |
214 |
-default=>[keys %sg_filter], |
-default=>[keys %$sg_filter], |
215 |
-linebreak=>'true', |
-linebreak=>'true', |
216 |
), |
), |
217 |
),td( |
),td( |
276 |
|
|
277 |
# sort data |
# sort data |
278 |
# |
# |
279 |
my @sorted = sorted_array(@data, @sort); |
my @sorted = sorted_array(@$data, @sort); |
|
#my @sorted = @data; |
|
280 |
|
|
281 |
print "-- sort: ",Dumper(@sort)," (data: ".@data." sorted: ".@sorted.") --\n",br,"-- dayMask: $dayMask --\n",br if ($debug); |
print "-- sort: ",Dumper(@sort)," (data: ".@$data." sorted: ".@sorted.") --\n",br,"-- dayMask: $dayMask --\n",br,"-- cache_key: $cache_key --\n",br if ($debug); |
282 |
|
|
283 |
print start_table({-border=>1,-cellspacing=>0,-cellpadding=>2,-width=>'100%'}); |
print start_table({-border=>1,-cellspacing=>0,-cellpadding=>2,-width=>'100%'}); |
284 |
|
|
285 |
print Tr( |
print Tr( |
286 |
th("group/service"), |
th("group/service"), |
287 |
th({-bgcolor=>'#f0f0f0'}, |
th({-bgcolor=>'#f0f0f0'},'<nobr>'. |
288 |
&sort_link($q,'from','u').' from '. |
&sort_link($q,'from','u').' from '. |
289 |
&sort_link($q,'from','d'), |
&sort_link($q,'from','d').'</nobr>', |
290 |
br,$from_html |
br,$from_html |
291 |
), |
), |
292 |
th( |
th( '<nobr>'. |
293 |
&sort_link($q,'to','u').' to '. |
&sort_link($q,'to','u').' to '. |
294 |
&sort_link($q,'to','d'), |
&sort_link($q,'to','d').'</nobr>', |
295 |
br,$to_html |
br,$to_html |
296 |
), |
), |
297 |
th({-bgcolor=>'#e0e0e0'}, |
th({-bgcolor=>'#e0e0e0'},'<nobr>'. |
298 |
&sort_link($q,'dur','u').' duration '. |
&sort_link($q,'dur','u').' duration '. |
299 |
&sort_link($q,'dur','d') |
&sort_link($q,'dur','d').'</nobr>' |
300 |
), |
), |
301 |
th("description") |
th("description") |
302 |
) if (scalar @sorted > 0); |
) if (scalar @sorted > 0); |
306 |
my ($from,$dur,$int) = ('unknown','unknown','unknown'); |
my ($from,$dur,$int) = ('unknown','unknown','unknown'); |
307 |
if ($row->{from} != -1 ) { |
if ($row->{from} != -1 ) { |
308 |
$from = d($row->{from}); |
$from = d($row->{from}); |
309 |
$dur = dur($row->{dur}); |
$dur = dur($row->{to} - $row->{from}); |
310 |
$int = dur($row->{int}); |
$int = dur($working_days->interval($row->{to},$row->{from})); |
311 |
} |
} |
312 |
print Tr( |
print Tr( |
313 |
td({-align=>'left',-valign=>'center'},$row->{sg}), |
td({-align=>'left',-valign=>'center'},$row->{sg}), |
322 |
# dump totals |
# dump totals |
323 |
# |
# |
324 |
|
|
325 |
foreach my $sg (keys %downtime) { |
foreach my $sg (keys %$downtime) { |
326 |
print Tr(td({-colspan=>3,-align=>'right'},"total for $sg:"), |
print Tr(td({-colspan=>3,-align=>'right'},"total for $sg:"), |
327 |
td({-bgcolor=>'#e0e0e0',-align=>'right'},dur($downtime{$sg})), |
td({-bgcolor=>'#e0e0e0',-align=>'right'},dur($downtime->{$sg})), |
328 |
td(small("in ".$sg_count{$sg}." failures"))),"\n"; |
td(small("in ".$sg_count->{$sg}." failures"))),"\n"; |
329 |
} |
} |
330 |
|
|
331 |
print end_table, |
print end_table, |