matt.tovey has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to come up with a neat way to log messages from my script. I'm logging messages to any of several destinations - stdout, a file, or a text widget, and currently I do this by calling multiple functions (one of which is included below), which isn't very clean. I'm also prioritising ($LOG_LEVEL) each message, and the other functions also support a $PrintFormal boolean, to switch on/off the timestamp output in some cases.
use constant DEBUG => 0; # Log levels use constant INFO => 1; use constant NORMAL => 2; use constant WARN => 3; use constant ERROR => 4; my @LOG_LEVEL_NAME = ('DEBUG', 'INFO', 'NORMAL', 'WARN', 'ERROR'); my $LOG_LEVEL = DEBUG; sub LogMsg { my $level = shift; unless ($level >= $LOG_LEVEL) {return} my ($sec, $min, $hour, $day, $mon, $year) = localtime; $LogCounter++; if (open LOG, ">> $LOGFILE") { printf LOG "%04d.%02d.%02d %02d:%02d:%02d.%d: ", $year+1900, $mon+1, $day, $hour, $min, $sec, $LogCounter; print LOG "$$: $Display: $LOG_LEVEL_NAME[$level]: @_\n"; close LOG; } } LogMsg INFO, "Starting chooser mode...";

What I'd like to do is combine my three functions into one, and seeing as how the function gets used quite a lot, I want it's usage to be as straight-forward as possible. I'm figuring this would probably work with a bit of binary arithmetic:

use constant FILE => 0b0001; use constant STDOUT => 0b0010; use constant GUI => 0b0100; LogMsg FILE|STDOUT, "Message";

But before I go ahead and implement this, I wanted to ask if anyone has any tips, or can point me to some existing code? Is there already a standard way of doing this? Ideally, I'd also like to be able to select a priority and formatting for each of the destinations!

Replies are listed 'Best First'.
Re: Logging messages - is there a better way?
by Tomte (Priest) on Nov 18, 2005 at 13:04 UTC

    I recommend Log::Log4Perl, a highly customizable solution; implementing what you describe - logging to a file, to syslog, sending a mail, ... - just a question of the right configuration...


    An intellectual is someone whose mind watches itself.
    -- Albert Camus

      My vote goes to this module, as well. It makes it very easy to be flexible – you simply instrument your code with logging instructions, and then how much is logged and where is purely a matter of configuration. Very nice.

      Makeshifts last the longest.

        Well, that was my first post on Perl Monks, and I was expecting to look back here tomorrow, and see if I had any replies. I certainly wasn't expecting 4 replies within half an hour! Thanks, people!

        I've seen log4j before, and would have gone for that, but it's not installed on the machines here. My script needs to be able to run on any of them, so editting syslog.conf is something I also want to avoid.

        However, Log::Dispatch is installed, and even though the Tklog option isn't, I think I should be able to code that in simply enough myself. :)

        Thanks for your help,


Re: Logging messages - is there a better way?
by Perl Mouse (Chaplain) on Nov 18, 2005 at 12:59 UTC
    I almost always use the syslog service to do my logging. Be it in Perl (using Sys::Syslog, C, (using syslog(3)), or in the shell (using logger(1)). If not, I write to stderr.

    I never buildin log mangling/redirection in my program. It's up to the user or admin to determine what to do. About the only option I add is the choice of facility (of which there are, unfortunally, way too few). I dislike all those pesky little programs, each having their own ideas on how to log, creating a twisty little maze of logfiles, all different. Large applications doing tons of logging may create their own log files - think Oracle. For the rest, I'd like to control what is logged (and where) in a central place: /etc/syslog.conf.

    Perl --((8:>*
Re: Logging messages - is there a better way?
by jesuashok (Curate) on Nov 18, 2005 at 13:01 UTC

    Generally I use "Log::Dispatch::Perl" module for logging the information.

    From Cpan you can get many modules for this purpose.

    "Keep pouring your ideas"