Thread: Logging STDERR

    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2011
    Posts
    42
    Rep Power
    3

    Logging STDERR


    Dear Gentlemen,

    Im curious to know if there is a way of logging STDERR on to a logfile in perl. Following is my implementation to figure this out.

    Code:
    my $command = system("lsm -ltr"); #purposely corrupted the statement so that it would return an error
    
       if ($? == 0) {
       print "good..!\n";
       logWriter("EINFO","Main","ok.....!");
       }
       else {
       print "Errors...!\n";
       logWriter("ERROR","Main","$command");
    
    sub logWriter {
    my $log_type = shift; #INFO,TEXT,ERROR,WARN
    my $call_func = shift;
    my $log_string = shift;
    my $log_line = '';
    my $LOG;
    my $timestamp = strftime("%Y%m%d%H%M%S", localtime);
    
       open ($LOG,">LOG_FILE") or die $!;
        $log_line = "$timestamp|".sprintf("%-5s", $log_type)  ."|".sprintf("%-10s", $call_func) ."| $log_string\n";
    print ($LOG $log_line);
            close ($LOG);
           }
    Please help me out good people.

    Many thanks in advance
    /Bindo
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    Why don't you simply redirect STDERR from the shell that is calling your perl program (redirect 2 to a file).
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    There are modules on cpan for this purpose, but based on your other question, using one of them is probably not an option.

    You could simply redirect STDERR as Laurent suggests, but a more robust solution, short of using a module, would be to write a die and warn signal handler (subroutine). The handlers would handle formatting a timestamp and would use the caller() function to include info about the context from the caller's perspective.
    Code:
    local $SIG{__DIE__}  = \&my_custom_die_handler;
    local $SIG{__WARN__} = \&my_custom_warn_handler;
    perldoc perlipc
    perldoc -f caller
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2011
    Posts
    42
    Rep Power
    3
    Mr Fish thank you very much. Could you kindly explain as to how I should go about logging to the same log file I have open with the peice of lines you've mentioned? Can you please use a simple example like the one in my script (ls -ltr being lsm -ltr) or somthing like that.

    Please sir Im not trying to get my work done or anything by copying your code. I really want to grasp the idea is all.

    Many thanks in advance
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2011
    Posts
    42
    Rep Power
    3
    Originally Posted by Laurent_R
    Why don't you simply redirect STDERR from the shell that is calling your perl program (redirect 2 to a file).
    Thanks Mr Laurent. I could just do that. But I'd like the errors also to be on the same logfile.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,873
    Rep Power
    1225
    This is not fully ready for a production level script, but is a short working example.

    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use POSIX qw(strftime);
    use Carp;
    
    open my $error_log, '>>', "$0_error.log" or carp "failed to open '$0_error.log' $!";
    
    local $SIG{__WARN__} = \&error_log;
    local $SIG{__DIE__} = \&error_log;
    
    my $command = system("lsm -ltr");
    
    warn "this warning goes to the logfile";
    print STDERR "this line goes to terminal instead of the logfile";
    
    sub error_log {
        my ($package, $filename, $line) = caller;
        my $timestamp = strftime("%Y-%m-%d %H:%M:%S", localtime);
        print {$error_log} join '~', $timestamp, $package, $filename, $line, @_;
    }
    
    __END__
    close $error_log if $error_log;
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2011
    Posts
    42
    Rep Power
    3
    First of all I appologize for not being able to reply on time since I was on the move.

    Woooow Mr Fish. Thats some real good stuff there. You really are a genius. Thank you very much Sir.

    Mr Laurent, thank you very much for your advices. You have always been so helpful and I've learnt a lot. Let me just resume my work on these scripts and get back to you. Thank you again Sir.

IMN logo majestic logo threadwatch logo seochat tools logo