#!/usr/bin/perl -w # # convert-multilog # John Simpson 2003-05-07 # # finds and coverts multilog-format log files to /var/log/___ # # 2005-04-11 jms1 - (no code changed.) changed the copyright notice to # specify that the license is the GPL VERSION 2 ONLY. i'm not comfortable # with the "or future versions" clause until i know what these "future # versions" will look like. # # 2006-11-28 jms1 - (no code changed.) added comments to the $opt_* # variables which tell what each command line switch does. # # 2007-08-14 jms1 - received a bug report- if the first line of an input # file is all whitespace, an empty date is generated and no output # file is opened (because the empty date matches the empty string with # which $fdate is initialized.) changing $fdate to initialize with a # string which, as far as i know, could never be printed by multilog. # thanks to John Coryat for letting me know. # # 2007-09-04 jms1 - adding @exclude to allow certain services to not be # touched at all. # # 2009-06-26 jms1 - fixed a bug where the "guaranteed invalid" string used # to not write empty date files is now detected. no more "Closing (0 lines # added" messages at the beginning of each run. also removed dependency # on Logit.pm. # # 2009-10-20 jms1 - some of tai64nlocal's output lines don't always start # with YYYY-MM-DD. my guess is that the original log lines which cause # this have embedded CR or LF characters. either way, i'm going to assume # that any such lines are continuations of whatever line preceded them, and # i'm going to write them to whatever file is currently open. if the first # line of a file is like this, it will be dropped. thanks to jon lewis for # pointing out the problem, even if i didn't use his solution. # # 2012-08-24 jms1 - found a typo which prevented the program from actually # working. I'm really surprised that nobody reported this... either that, # or I guess nobody really uses this script. # ############################################################################### # # Copyright (C) 2003,2005,2006,2007,2009,2012 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 2, 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### require 5.003 ; use strict ; use Sys::Syslog ; Sys::Syslog::setlogsock ( "unix" ) ; openlog ( "convert-multilog" , "pid" , "user" ) ; END { closelog() ; } ############################################################################### # # configuration and globals my $sdir = "/service" ; my $logdir = "/var/log" ; my @exclude = () ; my $opt_a = 0 ; # send ALRM to each multilog first, to "cut off" log files my $opt_v = 0 ; # debug() messages go to stdout along with syslog my $opt_r = 0 ; # rename log files to "__.done" instead of removing them my %ex = () ; my $notyet = "\x00\xFF\x00" ; # internal marker to recognize when a file # hasn't started processing yet $ENV{"PATH"} = "/usr/local/bin:/usr/bin:/bin" ; ############################################################################### # # debugging stuff my $show_debug = 0 ; sub debug($) { syslog ( "info" , "%s" , $_[0] ) ; if ( $opt_v ) { print $_[0] ; } } ############################################################################### ############################################################################### ############################################################################### # # let's do it map { $ex{$_} = 1 } @exclude ; while ( my $z = shift ) { die "Illegal option string [$z]\n" unless ( $z =~ s/^\-// ) ; if ( $z =~ s/a// ) { $opt_a ++ ; } if ( $z =~ s/r// ) { $opt_r ++ ; } if ( $z =~ s/v// ) { $opt_v ++ ; } die "Illegal option [$z]\n" if ( $z ) ; } debug "Starting\n" ; for my $d ( glob "$sdir/*" ) { unless ( -d "$d/log/main" ) { debug "No log/main directory under $d\n" ; next ; } my $tname = $d ; $tname =~ s|^$sdir/|| ; if ( exists $ex{$tname} ) { debug "Skipping $d\n" ; next ; } my $ifdate = $notyet ; my $fdate = $ifdate ; my $icount = 0 ; my $ocount = 0 ; my $of = "" ; if ( $opt_a && ( -s "$d/log/main/current" ) > 0 ) { debug "svc -a $d/log\n" ; system "svc -a $d/log" ; sleep 2 ; } for my $f ( glob "$d/log/main/\@*.[su]" ) { debug "Reading $f\n" ; open ( I , "tai64nlocal < $f |" ) or die "Can\'t run tai64nlocal < $f: $!\n" ; while ( my $line = ) { $icount ++ ; my $date = $fdate ; if ( $line =~ /^(\d\d\d\d\-\d\d\-\d\d)\s/ ) { $date = $1 ; } elsif ( $fdate eq $notyet ) { debug "Ignoring line $line" ; next ; } if ( $date ne $fdate ) { if ( $fdate && ( $fdate ne $ifdate ) ) { debug "Closing $of ($ocount lines added)\n" ; close O ; $fdate = "" ; $ocount = 0 ; } $of = "$logdir/$tname.$date" ; debug "Adding to $of\n" ; open ( O , ">>$of" ) or die "Can\'t open $of: $!\n" ; $fdate = $date ; } print O $line ; $ocount ++ ; } debug "Done reading $f ($icount lines read) " ; close I ; $icount = 0 ; if ( $opt_r ) { rename ( $f , "$f.done" ) ; debug "(renamed)\n" ; } else { unlink ( $f ) ; debug "(removed)\n" ; } } if ( $fdate ) { debug "Closing $of ($ocount lines added)\n" ; close O ; $fdate = "" ; $ocount = 0 ; } } debug "Done\n" ;