Printing to screen and to file

Discussion in 'Perl Misc' started by Peter Jamieson, Feb 10, 2008.

  1. I can print to a file by using:

    open(STDOUT, ">>tmp.txt");

    and print warnings to a file

    open(STDERR, ">>tmp.txt");

    But what I would like to do is both print STDOUT and STDERR to a file
    but also to still view both on screen.

    I looked in perldoc and elsewhere but could not see how to do this.
    Any help appreciated!
    Peter Jamieson, Feb 10, 2008
    #1
    1. Advertising

  2. Peter Jamieson

    Paul Lalli Guest

    On Feb 9, 7:09 pm, "Peter Jamieson" <>
    wrote:
    > I can print to a file by using:
    >
    > open(STDOUT, ">>tmp.txt");
    >
    > and print warnings to a file
    >
    > open(STDERR, ">>tmp.txt");
    >
    > But what I would like to do is both print STDOUT and STDERR to a file
    > but also to still view both on screen.
    >
    > I looked in perldoc and elsewhere but could not see how to do this.
    > Any help appreciated!


    Use the IO::Tee module from CPAN to create a filehandle that prints to
    both the file and STDOUT, select() that filehandle, and then setup a
    warn handler to print to the default filehandle rather than STDERR:

    $ perl -MIO::Tee -le'
    open my $fh, ">", "log.txt" or die $!;
    my $tee = IO::Tee->new(\*STDOUT, $fh);
    select $tee;
    $SIG{__WARN__} = sub { print @_ };
    print "Info";
    warn "Warning";
    '
    Info
    Warning at -e line 7.

    $ cat log.txt
    Info
    Warning at -e line 7.



    Hope this helps,
    Paul Lalli
    Paul Lalli, Feb 10, 2008
    #2
    1. Advertising

  3. Hi Paul, Thanks for your assistance!
    I have been absent from home for some time and am only now catching up
    on things.
    I will try your advice asap.
    Thanks again, Cheers, Peter

    "Paul Lalli" <> wrote in message
    news:...
    On Feb 9, 7:09 pm, "Peter Jamieson" <>
    wrote:
    > I can print to a file by using:
    >
    > open(STDOUT, ">>tmp.txt");
    >
    > and print warnings to a file
    >
    > open(STDERR, ">>tmp.txt");
    >
    > But what I would like to do is both print STDOUT and STDERR to a file
    > but also to still view both on screen.
    >
    > I looked in perldoc and elsewhere but could not see how to do this.
    > Any help appreciated!


    Use the IO::Tee module from CPAN to create a filehandle that prints to
    both the file and STDOUT, select() that filehandle, and then setup a
    warn handler to print to the default filehandle rather than STDERR:

    $ perl -MIO::Tee -le'
    open my $fh, ">", "log.txt" or die $!;
    my $tee = IO::Tee->new(\*STDOUT, $fh);
    select $tee;
    $SIG{__WARN__} = sub { print @_ };
    print "Info";
    warn "Warning";
    '
    Info
    Warning at -e line 7.

    $ cat log.txt
    Info
    Warning at -e line 7.



    Hope this helps,
    Paul Lalli
    Peter Jamieson, Mar 2, 2008
    #3
  4. Hi David, Thanks for your detailed response!
    I have been absent from home for some time and am only now catching up
    on things.
    I will try out code soon.
    Thank you!, Cheers, Peter


    "David Filmer" <> wrote in message
    news:...
    > Peter Jamieson wrote:
    >
    >> But what I would like to do is both print STDOUT and STDERR to a file
    >> but also to still view both on screen.

    >
    > If you want to get really fancy and versatile you can do this with a
    > logging module.
    >
    > My favorite is Log::Dispatch. Here is some sample code that I use in my
    > "skeleton" boilerplate starter script to do all the work of setting up
    > the logging methods (you need to do a bunch of stuff up-front, but once
    > it's done, the actual logging is VERY simple, as you will see):
    >
    > ######################################################################
    > ### LOGGING. Levels are: #############################################
    > ### debug info notice warning error critical alert emergency ##
    > ######################################################################
    > ##
    > use Mail::Sendmail; ##
    > use Log::Dispatch; ##
    > use Log::Dispatch::Screen; ##
    > use Log::Dispatch::File; ##
    > use Log::Dispatch::Email::MailSendmail; ##
    > ##
    > my $log; ##
    > ##
    > LOG_METHODS: { #lexically isolate variables in a block ##
    > my $logdir = $cfg{'dir'}{'log'} || "/var/tmp"; ##
    > my @admin_email = @{$cfg{'email'}{'admin'}} || ##
    > sprintf('%s@%s', scalar getpwuid($<), hostname); ##
    > ##
    > unshift @{$Mail::Sendmail::mailcfg{'smtp'}}, ##
    > $cfg{'email'}{'smtp'} || 'localhost'; ##
    > ##
    > my $add_lf = sub { my %p = @_; "$p{'message'}\n"}; ##
    > my $add_indent = sub {my %p = @_; " $p{'message'}"}; #for Outlook ##
    > my $add_timestamp = sub { my %p = @_; ##
    > sprintf "%s - %s", scalar(localtime), ##
    > $p{'message'}; }; ##
    > my $add_level = sub { my %p = @_; ##
    > sprintf "%-10s %s", ($p{'level'} =~ /debug/i) ##
    > ? lc $p{'level'} ##
    > : uc $p{'level'},##
    > $p{'message'} }; ##
    > ##
    > $log = Log::Dispatch->new ( callbacks => [$add_level, $add_lf] ); ##
    > ##
    > $log ->add( Log::Dispatch::Screen ->new( ##
    > name => 'screen', ##
    > min_level => 'debug', ##
    > stderr => 0, ) ##
    > ); ##
    > $log ->add( Log::Dispatch::File ->new( ##
    > name => 'file', ##
    > min_level => 'info', ##
    > filename => sprintf ( "%s/%s.log", ##
    > $logdir, ##
    > $FindBin::Script ), ##
    > mode => 'append', ##
    > callbacks => $add_timestamp, ##
    > )); ##
    > $log ->add( Log::Dispatch::Email::MailSendmail ->new( ##
    > name => 'email', ##
    > min_level => 'error', ##
    > to => \@admin_email, ##
    > subject => "ERROR in $PROGRAM_NAME", ##
    > callbacks => $add_indent, ##
    > from => sprintf ("SERVER<%s\@%s>", ##
    > (hostname =~ /^([^\.]*)/)[0], ##
    > 'do-not-reply.com' ) , ##
    > smtp => $cfg{'email'}{'smtp'} || 'localhost', ##
    > )); ##
    > }; #do ##
    >
    > #dispatch our very first message - print all the runtime info ##
    > $log -> debug(sprintf ##
    > "[%s] Begin %s\n\tVersion %s on %s as %s\n" ##
    > ."\tConfigFile: %s\n\tKillfile(s):\n%s", ##
    > __LINE__, __FILE__, ##
    > $main::VERSION, ##
    > hostname(), ##
    > "$REAL_USER_ID ($ENV{'USER'})", ##
    > $cfg{'inifile'}, ##
    > map {"\t\t$_\n"} keys %{$cfg{'killfile'}}, ##
    > ); ##
    > ######################################################################
    >
    > (I'm using a configuration hash (%cfg) which is populated earlier, and
    > I'm allowing for numerous default values within my method definitions)
    >
    > This creates three different types of logging methods (console, file,
    > and e-mail). When we pass a message to the logger, it will fire ANY and
    > ALL methods which are at (or above) the log level specified for the
    > various methods. For example,
    >
    > $log -> debug("This message goes to the screen only");
    > $log -> info("This message goes to BOTH screen and file.");
    > $log -> error("This goes to screen, file, AND e-mail");
    >
    > I could add many other methods as well (database logging, multiple
    > levels of file logging, etc).
    >
    > As you can see, I've added several callback functions to do things like
    > add a timestamp and automatically add linefeeds. I've found that
    > Outlook can do some funny things with wrapping, so I add an indention
    > to e-mail messages to avoid Outlook reformatting.
    >
    > Check it out; it's an amazing module:
    >
    > http://search.cpan.org/~drolsky/Log-Dispatch-2.11/lib/Log/Dispatch.pm
    Peter Jamieson, Mar 2, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Russell
    Replies:
    1
    Views:
    364
    Steve C. Orr [MVP, MCSD]
    Jan 21, 2004
  2. Pat
    Replies:
    5
    Views:
    524
  3. owl
    Replies:
    2
    Views:
    859
  4. Biranchi Narayan Panda
    Replies:
    1
    Views:
    2,708
    Alexey Smirnov
    Feb 17, 2010
  5. Nairb

    screen.height vs. screen.availHeight

    Nairb, Jul 2, 2003, in forum: Javascript
    Replies:
    0
    Views:
    104
    Nairb
    Jul 2, 2003
Loading...

Share This Page