basic Perl log function

I believe any good Perl utility should have a log to which pertinent information should be written. I’m not even going to go over the merits of having a log file, but all good scripts should have one.

Setup – Define the Function and Log Filename

Here’s the log function which I use in my Perl scripts. This could easily be exported to a log module. Yes, I realize there are probably a lot of good logging modules out there already, I’m just offering this for the lazy sods who don’t currently log anything in their Perl scripts, but realize that it’s a good idea to start.

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon  += 1; $wday += 1; $year += 1900;
my @months = qw { Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec };
unshift @months , '';


my $date = sprintf "%04d%03s%02d" , $year , $months[$mon] , $mday ;
my $logfile = "/tmp/$progname.$date.log";

open( LOGFILE , ">> $logfile" )
    or die "Can't open file '$logfile'. $!\n";
select((select(LOGFILE), $| = 1)[0]); # autoflush LOGFILE

sub logh() {
    my $msg = shift(@_);
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $mon  += 1; $wday += 1; $year += 1900;

    my @months = qw { Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec };
    my $dts;
    $dts = sprintf("%04d%3s%02d %02d:%02d:%02d",
                   $year,$months[$mon],$mday,$hour,$min,$sec);
    my $pid = $$;
    printf LOGFILE ("$dts:$pid: $msg\n" , @_);
}

I’ve actually included a bit more than just the log function – a few more lines to show how I set up the log filename. I like to create a daily log and assume the script I’m writing will eventually be run from a cron job or something.

Logging Strings – Calls to the logh() subroutine

This is the reason for all the setup — the actual log strings. Because of the way the arguments to the logh() function are utilized,
printf-style strings & arguments can be sent to the function. Here are some example calls to the logh function (pulled directly from a live production script):

I generally start out with the first line in the examples below (I always have a script global called “$progname”).

&logh("$progname started");
&logh("site '$store_nbr' not found in DB. adding site.");
&logh("all data matches for site '$store_nbr': nothing to do.");
&logh("adding site $store_nbr to db");
&logh("updating '$k' to '$v' for store $store_nbr in db");

Close It Out

Though it’s not really necessary these days, it’s good practice to actually close the file at the end of your script. I like to include the block below to close out the log file.

&logh("$progname ended");
my $line = '='x72;
&logh("$line");
close( LOGFILE );