Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

duplicating STDERR to a logfile...

by cadphile (Beadle)
on May 08, 2002 at 21:52 UTC ( #165195=perlquestion: print w/ replies, xml ) Need Help??
cadphile has asked for the wisdom of the Perl Monks concerning the following question:

A simple question really: I want to capture the STDERR from commands like croak and cluck into a log file that records all output of my program. I've read the previous comments in Perl Monks and I find the following in the Camel book:
use FileHandle; use Carp qw (cluck croak); my $LOG_FH = new FileHandle( "somefile", "w" ); my $fileno = fileno $LOG_FH; open STDERR, ">&$fileno" or croak "Can't dup STDERR."; cluck "Testing the output of Carp commands.";
(I need to use the $fileno because the ">&" dup operation doesn't work on I/O typeglobs.)

This works fine: all STDERR after this goes into $LOG_FH, but it no longer goes to the terminal.

But what I want is like the command "tee". I want STDERR to go to the terminal window, AND to be duplicated into the $LOG_FH filehandle.

Any clues??

Thanks, -Cadphile

Comment on duplicating STDERR to a logfile...
Download Code
Re: duplicating STDERR to a logfile...
by Kanji (Parson) on May 08, 2002 at 21:54 UTC
Re: duplicating STDERR to a logfile...
by jsegal (Friar) on May 08, 2002 at 22:09 UTC
    How about (at least on UNIX)
    open(STDERR,"|tee somefile 1>&2"); print STDERR "this goes to STDERR and somefile\n";
    (The "1>2" ensures that what gets printed still goes to your main process's STDERR instead of STDOUT).

    --JAS
Re: duplicating STDERR to a logfile...
by belg4mit (Prior) on May 09, 2002 at 01:42 UTC
    Another means would be to install a signal handler, this would receive Carp's cooked messages and you could tee from within. I wouldn't recommend opening the file within the handler though (memory allocaiton and (un)safe signal handling).

    Alternatively you could just use Carp::longmess and Carp::shortmess yourself.

    --
    perl -pew "s/\b;([mnst])/'$1/g"

(RhetTbull) Re: duplicating STDERR to a logfile...
by RhetTbull (Curate) on May 09, 2002 at 02:03 UTC
    My favorite way to handle this is with Filter::Handle. For example:
    use warnings; use strict; use Carp; use Filter::Handle qw/subs/; open (LOGFILE, ">logfile") or die "could not open logfile: $!"; #filter STDERR through an anonymous sub Filter \*STDERR, sub {local $_ = "@_"; print LOGFILE "Filtered: $_ "; +$_}; #need a signal handler to capture warnings from carp and warn which ar +e not captured by Filter::Handle (but by capturing ourselves and prin +ting to STDERR, they do get picked up by Filter::Handle) $SIG{__WARN__} = sub {local $_ = "@_"; print STDERR $_}; #prints to both STDERR and to LOGFILE print STDERR "error!\n"; carp "carp!"; warn "warn!"; #STDERR will no longer be filtered through your sub UnFilter \*STDERR; print STDERR "not captured to log\n"; warn "this one got away"; close LOGFILE;
    Update: Added signal handler to capture output of warn and carp
      Thanks RhetTbull -- This is the exact solution I was hunting for. Simple implementation, and it works just right.

      cheers

      Cadphile...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://165195]
Approved by Kanji
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (12)
As of 2015-07-06 11:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (72 votes), past polls