Thursday, May 7, 2009

Simple print-and-log subroutine

I find that I have a use for this almost all the time. It's a silly little set of subs, but in my role as sysadm, I often need to go back and see what all those printed messages were.

So here is my not-so-elegant workhorse for when I need to stuff things into logs, and shuffling modules isn't an option. I hope it's useful for someone else, too.

Dependencies, assumptions and prerequisites:

  • Perl 5-ish
  • Pre-defined global variables:
    • $level - log level (undef = normal, 1 = warn, 2 = die)
    • $logfile - a logfile that we can append to
    • $msgprefix - a program or subroutine specific prefix
    • $verbose - whether to print to STDOUT
  • Preferably disabled output buffering

Usage:

&plog("Log this");
&plogwarn("Warn about and log this");
&plogdie("Log this and die");

The code:

sub plogwarn
{
my $msg = shift;
&plog ($msg,1);
}

sub plogdie
{
my $msg = shift;
&plog ($msg,2);
exit 1;
}

sub plog
{
my $msg = shift;
my $level = shift;
my @lt = localtime;
# Format current datetime sensibly:
my $dt = sprintf("%d-%02d-%02d %02d:%02d:%02d",
$lt[5]+1900,$lt[4]+1,
$lt[3],$lt[2],$lt[1],$lt[0]);
warn "$dt $0: sub plog: No message!\n" unless defined $msg;
unless (open(F,">>$logfile")) {
warn "$dt $0: sub plog: Failed to open logfile ($logfile) for write.\n";
} else {
print F "$dt $msgprefix$msg\n";
close F;
}
if ($verbose) {
unless (defined($level)) {
print "$dt $msgprefix$msg\n";
} elsif ($level == 1) {
warn "$dt $msgprefix$msg\n";
} elsif ($level == 2) {
die "$dt $msgprefix$msg\n";
}
}
}

No comments: