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

Fellow monks,

I need to write some code that will log whatever it's writing to STDOUT and/or STDERR to log file(s). Seems like this might be doable with a PerlIO::via::something module. I didn't find anything to fit the bill on CPAN so I'm considering writing one myself. I've never written a perlio layer before and I find myself a little confused by this whole area of Perl. I'm wondering if there's something akin to a whitepaper on PerlIO layers and how they are supposed to work. I've read a bunch of the commonly available documentation, the PerlIO and PerlIO::via man pages among them, but I'm still having a difficutl time 'putting it all together'. So, I'm looking for something that would describe the whole structure of perlio layers. I don't necessarily need deep gorey details at this point, but I need some more detail than end user documentation.

Of course, maybe there's another simpler way to do this output mirroring/logging/whatever you want to call it. If anyone knows or can think of such a way I'd be happy to hear that too.

--DrWhy

"If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

  • Comment on writing a PerlIO::via module to log stderr?

Replies are listed 'Best First'.
Re: writing a PerlIO::via module to log stderr?
by Tanktalus (Canon) on Mar 15, 2005 at 21:12 UTC

    I wonder if what you really want to do is to use Tie::FileHandle::MultiPlex. What I would do here is open a new filehandle that duplicates STDOUT or STDERR, then close STDOUT or STDERR, open the logfile(s), and then tie STDOUT or STDERR to the multiplex of the duped filehandle and the logfile.

    But more info about PerlIO::via is always a good thing :-)

      Thanks Tanktalus; that will do the trick. Here's a toy script that demonstrates it's use:

      Update: The first version of this only looked like it worked. This version really does.

      #!/usr/bin/perl use Tie::FileHandle::MultiPlex; open (REALERR, ">&STDERR"); tie *STDERR, Tie::FileHandle::MultiPlex, *A, *REALERR, *B; open(A,'>>','testA') or die "testA: $!\n"; open(B,'>>','testB') or die "testB: $!\n"; warn "test message $$";

      This will print out 'test message 2314' or some such to the screen (stderr) as well as appending the same line to files named testA and testB.

      I'd still like to learn more about perlio layers, though the need is not as urgent right now; I'd still be interested in a whitepaper-ish thing on perlio layers if anyone knows of one.

      --DrWhy

      "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

Re: writing a PerlIO::via module to log stderr?
by ambrus (Abbot) on Mar 15, 2005 at 22:15 UTC

    I'm not sure why you want a perlio layer for this. If you really want that, I can't help. If you just want to log your output to a file, you could try IO::Tee from cpan:

    use warnings; my $logfilename = "./log"; { use IO::Tee; open my $log, +">", $logfilename or die "error opening log: $!"; *STDOUT = (IO::Tee- +>new(*STDOUT{IO}, $log) or die "error making tee: $!") } print "This +is both written to stdout and a logfile\n";
      Hmm... Looks like TMTOWTDI...

      --DrWhy

      "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."