In the past I've often written small special-purpose scripts to search for specific data in qpsmtpd logs. It was time to factor out the common code and create a more generalized tool for these tasks. So here it is.
hp
--
_ | Peter J. Holzer | Schlagfertigkeit ist das, was einem
|_|_) | Sysadmin WSR | auf dem Nachhauseweg einfällt.
| | | [EMAIL PROTECTED] | -- Lars 'Cebewee' Noschinski in dasr.
__/ | http://www.hjp.at/ |
#!/usr/bin/perl
=head1 NAME
qgrep - grep through qpsmtpd logs
=head1 SYNOPSIS
qgrep -g code -m code ... files ...
=head1 DESCRIPTION
qpsmtpd writes very detailed log files. Each connection creates many
lines of log output. This script simplifies searching through qpsmtpd
logs by treating all the lines for a single connection (identified by
the second field of each line) as a single string which is then filtered
through perl grep (option -g) and map (option -m) operations.
=head2 EXAMPLES
qgrep logfile
Dump all log entries to stdout ordered by connection.
All lines for a connection will be dumped before the next connection
starts. Connections will be in the same order as their first lines in
the logfile. This is already quite a bit more readable if you have many
parallel connections.
qgrep -g '/Queued/' logfile
Dump only lines from connections where at least one mail was queued.
qgrep -g '/Queued/' \
-m '"."' logfile | wc -c
As above, but replace all lines of of a connection with a single dot and
count the dots: This gives you the number of connections which deliverd
mail.
qgrep -g '/Queued/' -g '/RCPT TO: /i' \
-m 'join "\n", grep / (dispatching|\d{3}) /, split /\n/, $_' \
-m '"$_\n\n"' \
logfile
Select all connections which match both /Queued/ and /RCPT TO: /i, then
select only the SMTP dialogue from them (actually, all lines which
contain either the word "dispatching" or a three-digit number) and add
an empty line to each connection.
=head1 TODO
Identify complex but generally useful patterns (like the one to extract
the SMTP dialogue in the example above) and turn them into options.
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2006 Peter J. Holzer <[EMAIL PROTECTED]>.
This plugin is licensed under the same terms as the qpsmtpd package
itself.
Please see the LICENSE file included with qpsmtpd for details.
=cut
use warnings;
use strict;
use Getopt::Long;
my @ops;
sub make_op {
my $sub = eval "sub { $_[1] }";
die "cannot eval sub { $_[1] }: [EMAIL PROTECTED]" unless $sub;
push @ops, [ $_[0], $sub ]
}
GetOptions("g=s" => \&make_op,
"m=s" => \&make_op,
);
for my $f (@ARGV) {
open (my $fh, "<", $f) or die "cannot open $f: $!";
my @conns;
my %conns;
while (<$fh>) {
if (/^\S+ ([0-9a-f.]+) /) {
my $cid = $1;
if ($conns{$cid}) {
${ $conns{$cid} } .= $_;
} else {
push @conns, $_;
$conns{$cid} = \$conns[-1];
}
}
}
close($fh);
%conns = ();
for my $op (@ops) {
if ($op->[0] eq 'g') {
@conns = grep { $op->[1]($_) } @conns;
} elsif ($op->[0] eq 'm') {
@conns = map { $op->[1]($_) } @conns;
} else {
die "op $op->[0] not implemented\n";
}
}
print @conns;
}
signature.asc
Description: Digital signature
