#!/usr/bin/perl -w

# parse file.alert mon logs and report (up|down)time of services
#
# 2003-09-03 Dobrica Pavlinusic <dpavlin@rot13.org>
#
# Usage: ./parse-log.pl < /var/log/mon/foo.log

use strict;
use POSIX qw(strftime);

my $date_fmt = "%Y-%m-%d %H:%M:%S";

my $debug=0;
$debug++ if (grep(/-v/,@ARGV));
$debug++ if (grep(/-d/,@ARGV));

#
# This option (activated via command switch -r) will reset failure duration
# if repeated failure on same group/service happend.
# If you want honest reporting (or grouped only by group and service),
# you souldn't turn it on :-) However, if you have just failure events in your
# log, this will produce output which will show duration BETWEEN two failures
#
my $rep_reset = 0;
$rep_reset++ if (grep(/-r/,@ARGV));

# pretty format date
sub d {
	my $utime = shift || return "?";
	return strftime($date_fmt,localtime($utime));
}
# pretty format duration
sub dur {
	my $s = shift || return "?";
	my $out = "";

	my $d = int($s/(24*60*60));
	$s = $s % (24*60*60);
	my $h = int($s/(60*60));
	$s = $s % (60*60);
	my $m = int($s/60);
	$s = $s % 60;

	$out .= $d."d " if ($d > 0);
	$out .= sprintf("%02d:%02d:%02d",$h,$m,$s);

	return $out;
}

print "#group/service\tfrom_date\tfrom_time\tto_date\tto_time\tduration\tdescription\n";

my %fail;

while(<STDIN>) {
	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);
		print "# $group/$service $status $date [$desc]\n" if ($debug);
		my $id = "$group/$service";
		if ($status eq "up" && defined($fail{$id})) {
			print "$group/$service\t",d($fail{$id}),"\t",d($utime),"\t",dur($utime - $fail{$id}),"\t$desc\n";
			delete $fail{$id};
		} elsif ($status eq "up") {
			print "$group/$service\tunknown\t",d($utime),"\tunknown\t$desc\n";
			delete $fail{$id};
		} elsif (defined($fail{$id})) {
			if ($rep_reset) {
				print "$group/$service\t",d($fail{$id}),"\t",d($utime),"\t",dur($utime - $fail{$id}),"\t$desc\t[failure again]\n";
				$fail{$id} = $utime;
			}
		} else {
			$fail{$id} = $utime;
		}
	}
}
