#!/usr/bin/perl -w # # recordio-split # John Simpson 2008-09-17 # # reads qmail-smtpd logs. finds recordio lines, stores individual session # transcripts to separate files. # ############################################################################### # # Copyright (C) 2008 John Simpson. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 3, as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ############################################################################### require 5.003 ; use strict ; my %lines = () ; ############################################################################### # # choose an output filename for a given PID sub filename($) { my $pid = shift ; return "$pid.txt" ; } ############################################################################### ############################################################################### ############################################################################### while ( my $line = <> ) { my $oline = $line ; ######################################## # first remove the timestamp # recognizes raw TAI64N format (i.e. "@40000000....") # recognizes output from tai64nlocal (i.e. "yyyy-mm-dd hh:mm:ss.nnnn") # # users of syslog, with its broken timestamp format, will need to # write their own regex here to strip the timestamp off of the # beginning of the line. $line =~ s/^[ \@]40000000[0-9a-f]{16} // ; $line =~ s/^\d{4}\-\d\d\-\d\d \d\d\:\d\d\:\d\d\.\d+ // ; ######################################## # ignore messages which are not from recordio # otherwise, get the PID next unless ( $line =~ /^(\d+) [<>] / ) ; my $pid = $1 ; ######################################## # save (in memory) the line under that PID $lines{$pid} .= $oline ; ######################################## # if this is an EOF line, write the lines out to a file. # # note that if the output file already exists (which will happen on # a busy server, if you process a lot of log lines) then the current # set of log lines will be added to the end of the existing file, # after a separator line of "=" characters. if ( $line =~ / \[EOF\]/ ) { my $f = filename ( $pid ) ; my $sep = ( -f $f ) ? ( ( "=" x 79 ) . "\n" ) : "" ; open ( O , ">>$f" ) or die "Can't create \"$f\": $!\n" ; print O $sep , $lines{$pid} ; close O ; print "Stored $f\n" ; delete $lines{$pid} ; } } ######################################## # write any remaining PIDs out to files as well for my $pid ( keys %lines ) { open ( O , ">>$pid.txt" ) or die "Can't create \"$pid.txt\": $!\n" ; print O $lines{$pid} ; close O ; print "Stored $pid.txt\n" ; delete $lines{$pid} ; }