|
Packit Bot |
ea69bd |
##########################################################################
|
|
Packit Bot |
ea69bd |
# $Id$
|
|
Packit Bot |
ea69bd |
##########################################################################
|
|
Packit Bot |
ea69bd |
#
|
|
Packit Bot |
ea69bd |
# Logwatch service for postgresql error log
|
|
Packit Bot |
ea69bd |
#
|
|
Packit Bot |
ea69bd |
# Processes all messages and summarizes them
|
|
Packit Bot |
ea69bd |
# Each message is given with a timestamp and RMS
|
|
Packit Bot |
ea69bd |
#
|
|
Packit Bot |
ea69bd |
########################################################
|
|
Packit Bot |
ea69bd |
# (C) 2011 by Dalibo - http://www.dalibo.com/
|
|
Packit Bot |
ea69bd |
# written by Gilles Darold.
|
|
Packit Bot |
ea69bd |
#
|
|
Packit Bot |
ea69bd |
# Heavily based on the mysql script by Jeremias Reith
|
|
Packit Bot |
ea69bd |
########################################################
|
|
Packit Bot |
ea69bd |
## Covered under the included MIT/X-Consortium License:
|
|
Packit Bot |
ea69bd |
## http://www.opensource.org/licenses/mit-license.php
|
|
Packit Bot |
ea69bd |
## All modifications and contributions by other persons to
|
|
Packit Bot |
ea69bd |
## this script are assumed to have been donated to the
|
|
Packit Bot |
ea69bd |
## Logwatch project and thus assume the above copyright
|
|
Packit Bot |
ea69bd |
## and licensing terms. If you want to make contributions
|
|
Packit Bot |
ea69bd |
## under your own copyright or a different license this
|
|
Packit Bot |
ea69bd |
## must be explicitly stated in the contribution and the
|
|
Packit Bot |
ea69bd |
## Logwatch project reserves the right to not accept such
|
|
Packit Bot |
ea69bd |
## contributions. If you have made significant
|
|
Packit Bot |
ea69bd |
## contributions to this script and want to claim
|
|
Packit Bot |
ea69bd |
## copyright please contact logwatch-devel@lists.sourceforge.net.
|
|
Packit Bot |
ea69bd |
########################################################
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
use strict;
|
|
Packit Bot |
ea69bd |
use Logwatch ':dates';
|
|
Packit Bot |
ea69bd |
use Time::Local;
|
|
Packit Bot |
ea69bd |
use POSIX qw(strftime);
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Allow timestamp from two different logfile format: syslog and stderr
|
|
Packit Bot |
ea69bd |
my $date_format1 = '%Y-%m-%d %H:%M:%S';
|
|
Packit Bot |
ea69bd |
my $date_format2 = '%b %e %H:%M:%S';
|
|
Packit Bot |
ea69bd |
my $filter1 = TimeFilter($date_format1);
|
|
Packit Bot |
ea69bd |
my $filter2 = TimeFilter($date_format2);
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Allow summarization of WARNING and HINT too if wanted
|
|
Packit Bot |
ea69bd |
my $detail = exists $ENV{'LOGWATCH_DETAIL_LEVEL'} ? $ENV{'LOGWATCH_DETAIL_LEVEL'} : 0;
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Used to replace the month trigram into the syslog timestamp
|
|
Packit Bot |
ea69bd |
my %month2num = ( Jan => 0, Feb => 1, Mar => 2, Apr => 3,
|
|
Packit Bot |
ea69bd |
May => 4, Jun => 5, Jul => 6, Aug => 7,
|
|
Packit Bot |
ea69bd |
Sep => 8, Oct => 9, Nov => 10, Dec => 11 );
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Array of the relevant lines in the log file.
|
|
Packit Bot |
ea69bd |
# First element: type of event
|
|
Packit Bot |
ea69bd |
# Second element: matching regexp ($1 should contain the message)
|
|
Packit Bot |
ea69bd |
# Third element: anonymous hash ref (stores message counts)
|
|
Packit Bot |
ea69bd |
my @message_categories = (
|
|
Packit Bot |
ea69bd |
['Panics', qr/PANIC: (.*)$/o, {}],
|
|
Packit Bot |
ea69bd |
['Fatals', qr/FATAL: (.*)$/o, {}],
|
|
Packit Bot |
ea69bd |
['Errors', qr/ERROR: (.*)$/o, {}]
|
|
Packit Bot |
ea69bd |
);
|
|
Packit Bot |
ea69bd |
if ($detail) {
|
|
Packit Bot |
ea69bd |
# Add more log information
|
|
Packit Bot |
ea69bd |
push(@message_categories,
|
|
Packit Bot |
ea69bd |
['Warnings', qr/WARNING: (.*)$/o, {}],
|
|
Packit Bot |
ea69bd |
['Hints', qr/HINT: (.*)$/o, {}]
|
|
Packit Bot |
ea69bd |
);
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Set the current year as syslog don't have this information.
|
|
Packit Bot |
ea69bd |
my $cur_year = (localtime(time))[5];
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Parse messages from stdin
|
|
Packit Bot |
ea69bd |
while(<>) {
|
|
Packit Bot |
ea69bd |
my $line = $_;
|
|
Packit Bot |
ea69bd |
# skipping messages that are not within the requested range
|
|
Packit Bot |
ea69bd |
next unless $line =~ /^($filter1|$filter2)/o;
|
|
Packit Bot |
ea69bd |
my $datetime = $1;
|
|
Packit Bot |
ea69bd |
my $time = '';
|
|
Packit Bot |
ea69bd |
# Date/time format differ following the log_destination (stderr or syslog)
|
|
Packit Bot |
ea69bd |
if ($datetime =~ /(\d{4})-(\d{2})-(\d{2})\s+(\d+):(\d+):(\d+)/) {
|
|
Packit Bot |
ea69bd |
{
|
|
Packit Bot |
ea69bd |
# timelocal is quite chatty
|
|
Packit Bot |
ea69bd |
local $SIG{'__WARN__'} = sub {};
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
$time = timelocal($6, $5, $4, $3, $2-1, $1-1900);
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
} elsif ($datetime =~ /(\w)\s+(\d+)\s+(\d+):(\d+):(\d+)/) {
|
|
Packit Bot |
ea69bd |
{
|
|
Packit Bot |
ea69bd |
# timelocal is quite chatty
|
|
Packit Bot |
ea69bd |
local $SIG{'__WARN__'} = sub {};
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
$time = timelocal($5, $4, $3, $2, $month2num{$1}, $cur_year);
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# Remove character position
|
|
Packit Bot |
ea69bd |
$line =~ s/ at character \d+//;
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
foreach my $cur_cat (@message_categories) {
|
|
Packit Bot |
ea69bd |
if($line =~ /$cur_cat->[1]/) {
|
|
Packit Bot |
ea69bd |
my $msgs = $cur_cat->[2];
|
|
Packit Bot |
ea69bd |
$msgs->{$1} = {count => '0',
|
|
Packit Bot |
ea69bd |
first_occurrence => $time,
|
|
Packit Bot |
ea69bd |
sum => 0,
|
|
Packit Bot |
ea69bd |
sqrsum => 0} unless exists $msgs->{$1};
|
|
Packit Bot |
ea69bd |
$msgs->{$1}->{'count'}++;
|
|
Packit Bot |
ea69bd |
# summing up timestamps and squares of timestamps
|
|
Packit Bot |
ea69bd |
# in order to calculate the rms
|
|
Packit Bot |
ea69bd |
# using first occurrence of message as offset in calculation to
|
|
Packit Bot |
ea69bd |
# prevent an integer overflow
|
|
Packit Bot |
ea69bd |
$msgs->{$1}->{'sum'} += $time - $msgs->{$1}->{'first_occurrence'};
|
|
Packit Bot |
ea69bd |
$msgs->{$1}->{'sqrsum'} += ($time - $msgs->{$1}->{'first_occurrence'}) ** 2;
|
|
Packit Bot |
ea69bd |
last;
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# generating summary
|
|
Packit Bot |
ea69bd |
foreach my $cur_cat (@message_categories) {
|
|
Packit Bot |
ea69bd |
# skipping non-requested message types
|
|
Packit Bot |
ea69bd |
next unless keys %{$cur_cat->[2]};
|
|
Packit Bot |
ea69bd |
my ($name, undef, $msgs) = @{$cur_cat};
|
|
Packit Bot |
ea69bd |
print $name, ":\n";
|
|
Packit Bot |
ea69bd |
print '-' x (length($name)+1), "\n";
|
|
Packit Bot |
ea69bd |
my $last_count = 0;
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# sorting messages by count
|
|
Packit Bot |
ea69bd |
my @sorted_msgs = sort { $msgs->{$b}->{'count'} <=> $msgs->{$a}->{'count'} } keys %{$msgs};
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
foreach my $msg (@sorted_msgs) {
|
|
Packit Bot |
ea69bd |
# grouping messages by number of occurrence
|
|
Packit Bot |
ea69bd |
print "\n", $msgs->{$msg}->{'count'}, " times:\n" unless $last_count == $msgs->{$msg}->{'count'};
|
|
Packit Bot |
ea69bd |
my $rms = 0;
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# printing timestamp
|
|
Packit Bot |
ea69bd |
print '[';
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
if($msgs->{$msg}->{'count'} > 1) {
|
|
Packit Bot |
ea69bd |
# calculating rms
|
|
Packit Bot |
ea69bd |
$rms = int(sqrt(
|
|
Packit Bot |
ea69bd |
($msgs->{$msg}->{'count'} *
|
|
Packit Bot |
ea69bd |
$msgs->{$msg}->{'sqrsum'} -
|
|
Packit Bot |
ea69bd |
$msgs->{$msg}->{'sum'}) /
|
|
Packit Bot |
ea69bd |
($msgs->{$msg}->{'count'} *
|
|
Packit Bot |
ea69bd |
($msgs->{$msg}->{'count'} - 1))));
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
print strftime($date_format1, localtime($msgs->{$msg}->{'first_occurrence'}+int($rms/2)));
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
print ' +/-';
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
# printing rms
|
|
Packit Bot |
ea69bd |
if($rms > 86400) {
|
|
Packit Bot |
ea69bd |
print int($rms/86400) , ' day(s)';
|
|
Packit Bot |
ea69bd |
} elsif($rms > 3600) {
|
|
Packit Bot |
ea69bd |
print int($rms/3600) , ' hour(s)';
|
|
Packit Bot |
ea69bd |
} elsif($rms > 60) {
|
|
Packit Bot |
ea69bd |
print int($rms/60) , ' minute(s)';
|
|
Packit Bot |
ea69bd |
} else {
|
|
Packit Bot |
ea69bd |
print $rms, ' seconds';
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
} else {
|
|
Packit Bot |
ea69bd |
# we have got this message a single time
|
|
Packit Bot |
ea69bd |
print strftime($date_format1, localtime($msgs->{$msg}->{'first_occurrence'}));
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
print '] ', $msg, "\n";
|
|
Packit Bot |
ea69bd |
$last_count = $msgs->{$msg}->{'count'};
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|
|
Packit Bot |
ea69bd |
print "\n";
|
|
Packit Bot |
ea69bd |
}
|
|
Packit Bot |
ea69bd |
|