DaWolf has asked for the wisdom of the Perl Monks concerning the following question:

Greetings.

I have an application the outuputs STDERR to a file, in this form:
# The aaplication begins with: my $err_file = "error.log"; open(ERRLOG, "+>>logs/system/$err_file"); flock(ERRLOG,2); *STDERR = *ERRLOG; # and ends with: flock(ERRLOG,8); close(ERRLOG);
I'd like to prepend every error msg with date and time. Is it possible? I know how to do it in an ordinary string, but can I tell Perl that every STDERR should be formatted in this way?

Thanks in advance,

my ($author_nickname, $author_email) = ("DaWolf","erabbott\@terra.com.br") if ($author_name eq "Er Galvão Abbott");

Replies are listed 'Best First'.
Re: Formatting STDERR
by Corion (Patriarch) on Feb 12, 2004 at 10:00 UTC

    merlyn has a nifty routine for that, which I shamelessly stole for Simple HTTP in under 100 lines :

    $SIG{__WARN__} = sub { warn __stamp(shift) }; $SIG{__DIE__} = sub { die __stamp(shift) }; # This sub Copyright (c) 1996,97,98,99,2000,01 by Randal L. Schwartz sub __stamp { my ($message) = @_; my $stamp = sprintf "[$$] [%02d@%02d:%02d:%02d] ", localtime[3,2,1,0 +]; $message =~ s/^/$stamp/gm; $message; }

    After that, all your output to STDERR (warnings, dies) will be prefixed with the (time)stamp.

      Not really. All your dies and warnings will be formatted (until someone localises $SIG{__WARN__} or $SIG {__DIE__}). It doesn't format anything generated with print STDERR.

      I suggest using IPC::Open3, with "-|" as the fourth argument. This will fork the process, allowing the parent to read STDERR from the child, and hence you are able to format STDERR they way you want.

      Abigail

Re: Formatting STDERR
by leriksen (Curate) on Feb 12, 2004 at 10:11 UTC
    Have a look at Filter::Handle and tie's in general

    +++++++++++++++++
    #!/usr/bin/perl
    use warnings;use strict;use brain;

Re: Formatting STDERR
by nite_man (Deacon) on Feb 12, 2004 at 10:47 UTC

    Try to look at Log::Log4perl - module for control and costomize the loggin behaviour in your applications. It's a port Log4j on Perl. There are many features - loggin levels, logger categories, log messages layouts, dispath log messages to file, on screen, by email etc.

    Hope it will be helpful!

    ~ Schiller

Re: Formatting STDERR
by Roy Johnson (Monsignor) on Feb 12, 2004 at 16:11 UTC
    While Filter::Handle looks like the right module for the job, I'd probably just do it by hand as below. If your error output isn't going to be line-based, you should use select to poll for input within the child. Season to taste.
    my $err_file = "error.log"; open(ERRLOG, "+>>logs/system/$err_file") or die "Could not open logfil +e:$!\n"; flock(ERRLOG,2); # Was *STDERR = *ERRLOG; my $child = open(STDERR, '|-'); if ($child < 0) { die "Could not fork: $!\n" } if ($child == 0) { while (<>) { printf ERRLOG '%s %s', scalar(localtime), $_; } exit 0; } print "One\n"; print STDERR "Foo\n"; print "Two\n"; print STDERR "Bar\n"; # and ends with: flock(ERRLOG,8); close(ERRLOG);

    The PerlMonk tr/// Advocate