[ABE.pm] maillog threading
Ricardo SIGNES
rjbs-perl-abe at lists.manxome.org
Mon Aug 13 12:02:08 PDT 2007
* "Faber J. Fedor" <faber at linuxnj.com> [2007-08-13T13:09:34]
> On 13/08/07 12:18 -0400, John Cappiello wrote:
> > I was under the impression he was looking for a tool like the one I
> > wrote for Jenn that could grep the log for $foo, and return a list of
> > ids that you could pick from and review the path in the logs, but I'm
> > just speculating.
>
> That sounds like what I want. The program would generate a tree of $foo
> message-ids, find the corresponding queuids and the actio(s) taken on
> the email message.
>
> Is Jenn's program available for hacking?
Attached. ICG::CLI is basically Getopt::Long::Descriptive. say/whisper/yell
are basically "print"
--
rjbs
-------------- next part --------------
#!/icg/bin/perl
use ICG::CLI;
use IPC::Open2;
use Time::TAI64 qw(:tai64n);
use Text::Table;
use strict;
my ($opts, $usage) = describe_options(
"%c -o pobox\@pobox.com -m message_id",
[ "to|t=s" => "message was to" ],
[ "from|f=s" => "message was from" ],
[ "to-or-from|o=s" => "message was to / from" ],
[ "message-id|m=s" => "message-id" ],
[ "date|d=s@" => "date of message YYYYMMDD; default: today", {default => ['current']} ],
[ "hour|h=s@" => "hour of message; default: any", {default => ['*']} ],
[ "dump" => "dump all QID data" ],
[ "dump-all" => "dump everything including non QID data" ]
);
unless ( $opts->{to}
or $opts->{from}
or $opts->{to_or_from}
or $opts->{message_id}
) {
&$usage();
}
if ($opts->{hour} < 10 and $opts->{hour} !~ /^0/) { $opts->{hour} = "0$opts->{hour}" }
foreach (["to", "from", "to_or_from"]) {
$opts->{$_} =~ s/(^<|>$)//g;
}
my $pattern = '\(';
my $modified = 0;
if ($opts->{to_or_from}) {
$pattern .= "to=<\Q$opts->{to_or_from}\E>\\|from=<\Q$opts->{to_or_from}\E>";
$modified = 1;
} else {
if ($opts->{to}) {
$pattern .= '\|' if $modified;
$pattern .= "to=<\Q$opts->{to}\E>";
$modified = 1;
}
if ($opts->{from}) {
$pattern .= '\|' if $modified;
$pattern .= "from=<\Q$opts->{from}\E>";
$modified = 1;
}
}
if ($opts->{message_id}) {
$pattern .= '\|' if $modified;
$pattern .= "message-id=<\Q$opts->{message_id}\E>";
$modified = 1;
}
$pattern .= '\)';
if ( not $modified ) { die "No valid pattern: $pattern\n" }
my $qids = [];
my @misc_results;
my $date_search;
if (scalar @{$opts->{date}} > 1) {
$date_search = join ',', @{$opts->{date}};
$date_search = "{$date_search}";
} else {
$date_search = $opts->{date}[0];
}
my $hour_search;
if (scalar @{$opts->{hour}} > 1) {
$hour_search = join ',', @{$opts->{hour}};
$hour_search = "{$hour_search}";
} else {
$hour_search = $opts->{hour}[0];
}
say("Searching /nfs/logs/syslog/maillogs/$date_search/$hour_search");
whisper("lgrep -i '$pattern' /nfs/logs/syslog/maillogs/$date_search/$hour_search");
my @results = `lgrep -i '$pattern' /nfs/logs/syslog/maillogs/$date_search/$hour_search`;
#whisper($_) foreach @results;
my %seen;
foreach (@results) {
my ($qid) = /\b([A-F\d]{6,16})\b/;
if ($qid and not $seen{$qid}) {
push @$qids, { qid => $qid};
$seen{$qid}++;
}
if (not $qid) { push @misc_results, $_ }
}
my $num_qids = scalar(@$qids);
say("Found $num_qids QID.");
foreach my $qid (@$qids) {
whisper("lfgrep -i '$qid->{qid}' /nfs/logs/syslog/maillogs/$date_search/$hour_search");
my @results = `lfgrep -i '$qid->{qid}' /nfs/logs/syslog/maillogs/$date_search/$hour_search`;
foreach my $result (@results) {
my $timestamp = $result;
$timestamp =~ /^(.+?)\s/ and $timestamp = $1;
if ( not $qid->{timestamp} ) {
if ($timestamp =~ /:/) { $timestamp =~ s/^.+?:// }
$qid->{timestamp} = tai64nlocal($timestamp)
and $qid->{timestamp} =~ s/\.\d+$//g;
}
$result =~ s/^[^\s]*\s//g;
if ($result !~ / filter: /) {
$qid->{raw} .= $result;
}
$result =~ /^(.+?):/
and $qid->{host} ||= $1;
$result =~ /\bto=<(.+?)>/
and $qid->{to} ||= $1;
$result =~ /from=<(.+?)>/
and $qid->{from} ||= $1;
$result =~ /message-id=<(.+?)>/
and $qid->{message_id} ||= $1;
$result =~ /\bstatus=(.+?)\b/
and $qid->{status} ||= $1;
}
}
my $number = 0;
my $tb = Text::Table->new( "", "Host", "To", "From", "Timestamp", "Status");
foreach my $qid (@$qids) {
$tb->load( [$number,
$qid->{host},
$qid->{to},
$qid->{from},
$qid->{timestamp},
$qid->{status}]
);
$number++;
}
if ($opts->{dump} or $opts->{dump_all}) {
foreach (@$qids) {
print $_->{raw};
print "\n";
}
if ($opts->{dump_all}) { print "$_" foreach @misc_results }
} else {
my $ur = '';
while ($ur !~ /^q(uit)?$/) {
print "\n", $tb;
my $choices = "#,m#,all,quit";
if (scalar(@misc_results)) {
print scalar(@misc_results), " results without a QID.\n";
$choices = "#,m#,all,nonqid,quit";
}
if ($opts->{message_id}) { $choices =~ s/m#,//g }
print "\n";
$ur = prompt_str("View", { choices => $choices });
$ur = lc($ur);
print "\n";
print "\n";
if ($ur =~ /^\d+$/) {
print $qids->[$ur]{raw};
print "\n";
} elsif ($ur =~ /^m(\d+)$/) {
my $id = $1;
my $args = '';
foreach (@{$opts->{date}}) {
$args .= " -d $_ ";
}
foreach (@{$opts->{hour}}) {
$args .= " -h $_ ";
}
if ($opts->{verbose}) {
$args .= " -v ";
}
whisper(qq|$0 -m '$qids->[$id]{message_id}' $args|);
system(qq|$0 -m '$qids->[$id]{message_id}' $args|);
} elsif ($ur eq 'all') {
foreach (@$qids) {
print $_->{raw};
print "\n";
}
} elsif ($ur eq 'nonqid') {
print "$_" foreach @misc_results;
} else {
print "Invalid Option.";
}
}
}
More information about the ABE-pm
mailing list