--- parse_log.cgi 2003/10/05 22:26:34 1.3
+++ parse_log.cgi 2003/10/06 22:32:06 1.5
@@ -13,11 +13,13 @@
use Data::Sorting qw(:arrays);
use Time::ParseDate;
use Time::Available;
+use Cache::FileCache;
use Data::Dumper;
my $date_fmt = "%Y-%m-%d";
-my $date_time_fmt = "%Y-%m-%d %H:%M:%S";
+#my $date_time_fmt = "%Y-%m-%d %H:%M:%S";
+my $date_time_fmt = "%a %Y-%m-%d %H:%M:%S";
my $from_date = "now - 6 months";
my $to_date = "now";
@@ -28,7 +30,7 @@
my $from_time_interval = "7:00";
my $to_time_interval = "17:00";
-my $debug=1;
+my $debug=0;
$debug++ if (grep(/-v/,@ARGV));
$debug++ if (grep(/-d/,@ARGV));
@@ -49,19 +51,19 @@
my @sg_selected = $q->param('sg_filter');
# init misc sort parametars
-my @sort;
+my @sort_rules;
my $order;
my %sort_param;
my ($usort,$dsort);
if ($q->param('usort')) {
$sort_param{'usort'} = $q->param('usort');
$q->delete('usort');
- @sort = ( -compare => 'numeric', $sort_param{'usort'} );
+ @sort_rules = ( -compare => 'numeric', scalar $sort_param{'usort'} );
}
if ($q->param('dsort')) {
$sort_param{'dsort'} = $q->param('dsort');
$q->delete('dsort');
- @sort = ( -compare => 'numeric', -order=>'reverse', $sort_param{'dsort'} );
+ @sort_rules = ( -compare => 'numeric', -order=>'reverse', scalar $sort_param{'dsort'} );
}
# make interval
@@ -74,6 +76,9 @@
$working_days=new Time::Available(start=>$q->param('from_time_interval'),end=>$q->param('to_time_interval'),dayMask=>$dayMask);
}
+# init cache and setup expriration
+my $cache = new Cache::FileCache({ default_expires_in => '10 min' });
+
#
# This option (activated via command switch -r) will reset failure duration
# if repeated failure on same group/service happend.
@@ -118,66 +123,74 @@
#
my %fail;
-my %downtime; # total downtime
-my %sg_filter; # filter for service/group
-my %sg_count; # count number of downtimes
-
-my $log_file="/home/dpavlin/mon-log/sap.log";
-
-my @data;
-
-open(LOG, $log_file) || die "$log_file: $!";
-
-while() {
- chomp;
- if (/^(failure|up)\s+(\S+)\s+(\S+)\s+(\d+)\s+\(([^)]+)\)\s+(.+)$/) {
- my ($status,$group,$service,$utime,$date,$desc) = ($1,$2,$3,$4,$5,$6);
- my $id = "$group/$service";
- if ($status eq "up" && defined($fail{$id})) {
- if (grep(m;$group/$service;,@sg_selected)) {
- push @data, {
- 'sg'=>"$group/$service",
- 'from'=>$fail{$id},
- 'to'=>$utime,
- 'dur'=>($utime - $fail{$id}),
- 'int'=>$working_days->interval($utime,$fail{$id}),
- 'desc'=>$desc };
- $downtime{"$group/$service"} += ($utime - $fail{$id}),
- $sg_count{"$group/$service"}++;
- }
- $sg_filter{"$group/$service"}++;
- delete $fail{$id};
- } elsif ($status eq "up") {
- if ($print_orphans && grep(m;$group/$service;,@sg_selected)) {
- push @data, {
- 'sg'=>"$group/$service",
- 'from'=>-1,
- 'to'=>$utime,
- 'desc'=>$desc };
- $sg_count{"$group/$service"}++;
- }
- delete $fail{$id};
- $sg_filter{"$group/$service"}++;
- } elsif (defined($fail{$id})) {
- if ($rep_reset && grep(m;$group/$service;,@sg_selected)) {
- push @data, {
- 'sg'=>"$group/$service",
- 'from'=>$fail{$id},
- 'to'=>$utime,
- 'dur'=>($utime - $fail{$id}),
- 'int'=>$working_days->interval($utime,$fail{$id}),
- 'desc'=>'[failure again]'};
- $downtime{"$group/$service"} += ($utime - $fail{$id}),
+my $sg_filter; # filter for service/group
+
+my $log_file="/var/log/mon/sap.log";
+
+my $data;
+
+# generate unique key for this data and options
+my $cache_key="monlog".join("|",@sg_selected)."|".$print_orphans."|".$rep_reset;
+
+# debug disables cache
+if (! $debug) {
+ $data = $cache->get( $cache_key );
+ $sg_filter = $cache->get("sg_filter $cache_key");
+}
+
+if (!$data || !$sg_filter) {
+
+ open(LOG, $log_file) || die "$log_file: $!";
+
+ while() {
+ chomp;
+ if (/^(failure|up)\s+(\S+)\s+(\S+)\s+(\d+)\s+\(([^)]+)\)\s+(.+)$/) {
+ my ($status,$group,$service,$utime,$date,$desc) = ($1,$2,$3,$4,$5,$6);
+ my $id = "$group/$service";
+ if ($status eq "up" && defined($fail{$id})) {
+ if (grep(m;$group/$service;,@sg_selected)) {
+ push @$data, {
+ 'sg'=>"$group/$service",
+ 'from'=>$fail{$id},
+ 'to'=>$utime,
+ 'dur'=>($utime-$fail{id}),
+ 'desc'=>$desc };
+ }
+ $sg_filter->{"$group/$service"}++;
+ delete $fail{$id};
+ } elsif ($status eq "up") {
+ if ($print_orphans && grep(m;$group/$service;,@sg_selected)) {
+ push @$data, {
+ 'sg'=>"$group/$service",
+ 'from'=>-1,
+ 'to'=>$utime,
+ 'dur'=>0,
+ 'desc'=>$desc };
+ }
+ delete $fail{$id};
+ $sg_filter->{"$group/$service"}++;
+ } elsif (defined($fail{$id})) {
+ if ($rep_reset && grep(m;$group/$service;,@sg_selected)) {
+ push @$data, {
+ 'sg'=>"$group/$service",
+ 'from'=>$fail{$id},
+ 'to'=>$utime,
+ 'dur'=>($utime-$fail{id}),
+ 'desc'=>'[failure again]'};
+ $fail{$id} = $utime;
+ }
+ $sg_filter->{"$group/$service"}++;
+ } else {
$fail{$id} = $utime;
- $sg_count{"$group/$service"}++;
}
- $sg_filter{"$group/$service"}++;
- } else {
- $fail{$id} = $utime;
}
}
+ close(LOG);
+
+ $cache->set($cache_key, $data);
+ $cache->set("sg_filter $cache_key", $sg_filter);
+
}
-close(LOG);
# generate output
#
@@ -191,26 +204,26 @@
Tr(td(
em("Show just service/group:"),br,
checkbox_group(-name=>'sg_filter',
- -values=>[keys %sg_filter],
- -default=>[keys %sg_filter],
+ -values=>[keys %$sg_filter],
+ -default=>[keys %$sg_filter],
-linebreak=>'true',
),
),td(
em("Other options:"),br,
- $q->checkbox(-name=>'rep_reset',-checked=>0,
+ $q->checkbox(-name=>'rep_reset',-default=>0,
-label=>"show repeated failures on same service as individual failures"),
br,
- $q->checkbox(-name=>'print_orphans',-checked=>0,
+ $q->checkbox(-name=>'print_orphans',-default=>0,
-label=>"show records which are not complete in this interval"),
br,
- $q->checkbox(-name=>'use_date_limit',-checked=>1,
+ $q->checkbox(-name=>'use_date_limit',-default=>1,
-label=>"use date limit from:"),
$q->textfield(-name=>'from_date',-size=>20,-default=>$from_date),
" to: ",
$q->textfield(-name=>'to_date',-size=>20,-default=>$to_date),
small('Using Time::ParseDate'),
br,
- $q->checkbox(-name=>'use_time_limit',-checked=>1,
+ $q->checkbox(-name=>'use_time_limit',-default=>1,
-label=>"use time limit for each day:"),
$q->textfield(-name=>'from_time_interval',-size=>8,-default=>$from_time_interval),
" to: ",
@@ -233,14 +246,21 @@
# dump report
#
+my %dir_html_entity = (
+# 'u' => '⇑',
+# 'd' => '⇓'
+ 'u' => '▲',
+ 'd' => '▼',
+);
+
sub sort_link {
my $q = shift || return;
my $col = shift || return;
my $dir = lc(shift) || return;
if ($sort_param{$dir.'sort'} && $sort_param{$dir.'sort'} eq $col) {
- return '&'.$dir.'Arr;';
+ return $dir_html_entity{$dir};
} else {
- return '&'.$dir.'Arr;';
+ return ''.$dir_html_entity{$dir}.'';
}
}
@@ -257,46 +277,58 @@
# sort data
#
-my @sorted = sorted_array(@data, @sort);
-#my @sorted = @data;
+my @sorted = sorted_array( @$data, @sort_rules );
-print "-- sort: ",Dumper(@sort)," (data: ".@data." sorted: ".@sorted.") --\n",br,"-- dayMask: $dayMask --\n",br if ($debug);
+print "-- sort: ",Dumper(@sort_rules)," (data: ".@$data." sorted: ".@sorted.") --\n",br,"-- dayMask: $dayMask --\n",br,"-- cache_key: $cache_key --\n",br if ($debug);
print start_table({-border=>1,-cellspacing=>0,-cellpadding=>2,-width=>'100%'});
print Tr(
th("group/service"),
- th({-bgcolor=>'#f0f0f0'},
+ th({-bgcolor=>'#f0f0f0'},''.
&sort_link($q,'from','u').' from '.
- &sort_link($q,'from','d'),
+ &sort_link($q,'from','d').'',
br,$from_html
),
- th(
+ th( ''.
&sort_link($q,'to','u').' to '.
- &sort_link($q,'to','d'),
+ &sort_link($q,'to','d').'',
br,$to_html
),
- th({-bgcolor=>'#e0e0e0'},
+ th({-bgcolor=>'#e0e0e0'},''.
&sort_link($q,'dur','u').' duration '.
- &sort_link($q,'dur','d')
+ &sort_link($q,'dur','d').''
),
th("description")
) if (scalar @sorted > 0);
+my $downtime; # total downtime
+my $downinterval; # total downtime in time interval
+my $sg_count; # count number of downtimes
+
foreach my $row (@sorted) {
next if ($q->param('use_date_limit') && ($row->{from} < $from_time || $row->{to} > $to_time));
my ($from,$dur,$int) = ('unknown','unknown','unknown');
+
if ($row->{from} != -1 ) {
$from = d($row->{from});
- $dur = dur($row->{dur});
- $int = dur($row->{int});
+ $dur = $row->{to} - $row->{from};
+ $downtime->{$row->{sg}} += $dur;
+ if ($q->param('use_time_limit')) {
+ $int = $working_days->interval($row->{from},$row->{to});
+ $dur = dur($int)."
∑ ".dur($dur)."";
+ $downinterval->{$row->{sg}} += $int;
+ } else {
+ $dur = dur($dur);
+ }
}
+ $sg_count->{$row->{sg}}++;
+
print Tr(
td({-align=>'left',-valign=>'center'},$row->{sg}),
td({-align=>'right',-bgcolor=>'#f0f0f0'},$from),
td({-align=>'right'},d($row->{to})),
td({-align=>'center',-bgcolor=>'#e0e0e0'},$dur),
- td({-align=>'center',-bgcolor=>'#e0e0e0'},$int),
td({-align=>'left'},$row->{desc}),
),"\n";
}
@@ -304,10 +336,16 @@
# dump totals
#
-foreach my $sg (keys %downtime) {
-print Tr(td({-colspan=>3,-align=>'right'},"total for $sg:"),
- td({-bgcolor=>'#e0e0e0',-align=>'right'},dur($downtime{$sg})),
- td(small("in ".$sg_count{$sg}." failures"))),"\n";
+foreach my $sg (keys %$downtime) {
+ my $dur;
+ if ($downinterval->{$sg}) {
+ $dur=dur($downinterval->{$sg})."
∑ ".dur($downtime->{$sg})."";
+ } else {
+ $dur=dur($downtime->{sg});
+ }
+ print Tr(td({-colspan=>3,-align=>'right'},"total for $sg:"),
+ td({-bgcolor=>'#e0e0e0',-align=>'right'},$dur),
+ td(small("in ".$sg_count->{$sg}." failures"))),"\n";
}
print end_table,