#!/usr/bin/perl
##########################################################################
# $Id$
##########################################################################
#######################################################
## Copyright (c) 2008 Kirk Bauer
## Covered under the included MIT/X-Consortium License:
## http://www.opensource.org/licenses/mit-license.php
## All modifications and contributions by other persons to
## this script are assumed to have been donated to the
## Logwatch project and thus assume the above copyright
## and licensing terms. If you want to make contributions
## under your own copyright or a different license this
## must be explicitly stated in the contribution an the
## Logwatch project reserves the right to not accept such
## contributions. If you have made significant
## contributions to this script and want to claim
## copyright please contact logwatch-devel@lists.sourceforge.net.
#########################################################
$^W=1;
use strict;
my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0;
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
my $DebugCounter = 0;
my $Top = $ENV{'stunnel_print_top'} || 20;
if ( $Debug >= 5 ) {
print STDERR "\n\nDEBUG: Inside stunnel Filter \n\n";
$DebugCounter = 1;
}
my @OtherList = ();
my %OtherList = ();
my %connections = ();
my %versioninfo = ();
my %errors = ();
my %notices = ();
my $sockdata = 0;
my $ssldata = 0;
sub other {
my $msg = shift;
unless (exists $OtherList{$msg}) {
$OtherList{$msg} = 1;
push(@OtherList, $msg);
} else {
$OtherList{$msg}++;
}
}
my $ThisLine;
while (defined($ThisLine = <STDIN>)) {
$ThisLine =~ s/LOG\d\[\d{1,5}:\d{15}\]: (.*)/$1/;
if ( $Debug >= 5 ) {
print STDERR "DEBUG($DebugCounter): $ThisLine";
$DebugCounter++;
}
chomp($ThisLine);
my $origline = $ThisLine;
if ($ThisLine =~ m/^(.+) connected from (\d+\.\d+\.\d+\.\d+)/) {
my $service = $1;
my $ip = $2;
if (! exists($connections{$service}{$ip})) {
$connections{$service}{$ip} = 0;
}
++$connections{$service}{$ip};
} elsif ($ThisLine =~ m/^Connection (reset|closed): (\d+) bytes sent to SSL, (\d+) bytes sent to socket/) {
$ssldata += $2;
$sockdata += $3;
} elsif ($ThisLine =~ m/^Connection (reset|closed)/) {
# ignore
} elsif ($ThisLine =~ m/^connect_blocking: connected/) {
# ignore
} elsif ($ThisLine =~ m/^connect_blocking: getsockopt ([0-9a-fA-F.:]+: Connection refused) \(\d+\)$/) {
$errors{"connect_blocking: $1"}++;
} elsif ($ThisLine =~ m/^(?:remote socket|local socket|accept): (Too many open files) \(\d+\)$/) {
$errors{"$1: increase the maximum number of open file descriptors"}++;
} elsif ($ThisLine =~ m/^Log file reopened$/) {
# ignore
} elsif ($ThisLine =~ m/^SSL socket closed on SSL_read with \d+ byte\(s\) in buffer$/) {
# ignore
} elsif ($ThisLine =~ m/^stunnel [\d\.]+ on [\w\-]+ [\w\+]+ with OpenSSL [\w\.]+ \d+ \w+ \d+/) {
$versioninfo{$ThisLine} = 1;
} elsif ($ThisLine =~ m/^Service (\S+) accepted connection from ([0-9a-fA-F.:]+):\d{1,5}/) {
$connections{$1}{$2}++;
} elsif ($ThisLine =~ m/^Service (\S+) connected remote server from ([0-9a-fA-F.:]+):\d{1,5}/) {
$connections{"remote: $1"}{$2}++;
} elsif ($ThisLine =~ m/^Error detected on (SSL|socket) \((read|write)\) file descriptor: (.*) \(\d+\)/) {
$errors{"$1 $2 file descriptor: $3"}++;
} elsif ($ThisLine =~ m/^(SSL_write: (?:Broken pipe|Connection reset by peer)) \(\d+\)$/) {
$errors{"$1"}++;
} elsif ($ThisLine =~ m/^transfer: s_poll_wait: TIMEOUTclose exceeded: closing$/) {
$notices{"TIMEOUTclose exceeded: closing connection"}++;
} elsif ($ThisLine =~ m/^(SSL_(?:accept|read|shutdown): .*|getpeerbyname: .*)(?: \(\d+\))?$/) {
$notices{$1}++;
} else {
# Report any unmatched entries...
other($ThisLine);
}
}
if (keys %errors) {
print "\nErrors:\n";
foreach my $e (sort keys %errors) {
printf " %-50s %6d time(s)\n", $e, $errors{$e};
}
}
if (keys %notices) {
print "\nNotices:\n";
foreach my $n (sort keys %notices) {
printf " %-50s %6d time(s)\n", $n, $notices{$n};
}
}
if (keys %connections) {
print "\nconnections:\n";
foreach my $service (sort keys %connections) {
print " $service\n";
my $ips = $connections{$service};
my $i = 0;
foreach my $ip (sort {$connections{$service}{$b} <=> $connections{$service}{$a}} keys %{$connections{$service}}) {
if ($i >= $Top) {
printf " %-48s\n", "... only top $Top printed ...";
last;
} else {
printf " %-48s %6d time(s)\n", $ip, $connections{$service}{$ip};
$i++;
}
}
}
}
if ($sockdata > 0) {
if ($sockdata > 1024*1024) {
printf "\n%-48s %10.2f MB\n", "amount of socket data transferred:", $sockdata / 1024 / 1024;
} else {
printf "\n%-48s %10.2f KB\n", "amount of socket data transferred:", $sockdata / 1024;
}
}
if ($ssldata > 0) {
if ($ssldata > 1024*1024) {
printf "\n%-48s %10.2f MB\n", "amount of SSL data transferred:", $ssldata / 1024 / 1024;
} else {
printf "\n%-48s %10.2f KB\n", "amount of SSL data transferred:", $ssldata / 1024;
}
}
if (keys %versioninfo) {
print "\nversion information:\n";
foreach my $v (sort keys %versioninfo) {
print " $v\n";
}
}
if (@OtherList) {
print "\n**Unmatched Entries**\n";
for (@OtherList) {
my $count = $OtherList{$_};
print "($count) $_\n";
}
}
exit(0);
# vi: shiftwidth=3 tabstop=3 syntax=perl et
# Local Variables:
# mode: perl
# perl-indent-level: 3
# indent-tabs-mode: nil
# End: