Van Liedekerke Franky <[EMAIL PROTECTED]> writes:
> Hi,
>
> I'm using tcpserver and cyclog to log qmail and qmail-smtpd. Now I would
> like to know how to combine these two: in the qmail log I see who mailed to
> whom, but I don't know the IP address, this is in the qmail-smtpd log. So
> how can I combine these two logs?
Sort them...
% sort this-log that-log | tailocal
Here is a perl script that does this in a somewhat more comfortable
fashion. It extracts a time-slice from the qmail-related logs and
merges them together.
You may need to change the names of the log directories, near the
beginning of the script. Note: this script is strictly for raw cyclog
files. They must be named @<14-digit-timestamp> with each line
beginning with an accustamp time value. Filenames ending in .gz will
be decompressed automatically.
You also need the Time::ParseDate module, available on CPAN.
================================================================
#!/usr/bin/perl -w
# Display merged pop3d, smtpd and qmail-send logs
# fdc, 1998-07-15
use strict;
use Time::ParseDate;
use Getopt::Std;
use vars qw($opt_g $opt_h $opt_p $opt_q $opt_s $opt_t);
my $pop3log = '/var/log/pop3d';
my $sendlog = '/var/log/qmail-send';
my $smtplog = '/var/log/smtpd';
getopts('g:hpqst') and !$opt_h or die <<EOT;
Usage:
$0 [ flags ] [ <start> ] [ to|bis <end> ]
flags:
-g re only show lines matching re (grep)
-p show POP3 log \\
-q show qmail-send log | show all logs if none of pqs are given
-s show qmail-smtpd log /
-t test (just show the start and end times)
start and end are date/time specifications (see man Time::ParseDate)
default: <start> = now -1 minute; <end> = <start> +1 minute
EOT
my $now = time;
my($start,$end);
my @extra = (PREFER_PAST=>1, UK=>1, WHOLE=>1);
if (@ARGV) {
my($from,$x,$till) =
split / (through|thru|to|until|till|bis) /, "@ARGV";
$start = parsedate($from, @extra);
die "$from?\n" unless $start;
if ($till) {
push @extra, (NOW=>$start) unless $till =~ /now/;
$end = parsedate($till, @extra);
die "$till?\n" unless $end;
}
else { $end = $start+60 }
}
else {
$start = $now-60;
$end = $now;
}
if ($opt_t) {
print isodate($start), " -> ", isodate($end), "\n";
exit 0;
}
my @files = ();
push @files, $pop3log if $opt_p;
push @files, $sendlog if $opt_q;
push @files, $smtplog if $opt_s;
@files = ($pop3log, $sendlog, $smtplog) unless @files;
my $tmp = "/tmp/mail-log.$$";
open(OUT, "|sort|tailocal >$tmp") or
die "Can't create output pipe: $!\n";
$SIG{PIPE} = 'IGNORE';
$SIG{__DIE__} = sub { close OUT; unlink $tmp; die @_ };
foreach my $file (@files) {
scan($file, $start, $end);
}
close(OUT) or die "Pipe error: $!\n";
open(IN, $tmp) or die "Can't read results file ($tmp): $!\n";
print while (<IN>);
close(IN);
unlink $tmp;
exit 0;
sub scan {
my($d,$s,$e) = @_;
opendir(D, $d) or die "Can't open $d: $!\n";
my @logs = sort grep /^@/, readdir(D);
closedir(D);
my $limit = sprintf "\@%014d", $s;
while (@logs > 1) {
last if $logs[1] gt $limit;
shift @logs;
}
foreach my $f (@logs) {
$f = "$d/$f";
$f = "gzip -cdq 2>/dev/null $1|" if $f =~ /(.*\.gz)$/;
open(F, $f) or die "Can't read $f: $!\n";
while (<F>) {
next unless /^(\d+)/;
next unless $1 >= $s;
last unless $1 <= $e;
next if $opt_g and !/$opt_g/o;
print OUT;
}
close(F);
}
}
sub isodate {
my(@t) = localtime $_[0];
sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]);
}
--
Frank Cringle, [EMAIL PROTECTED]
voice: (+49 2304) 467101; fax: 943357