Search code examples
perllog4perl

How can I tell if Log4perl emitted any warnings during a run?


I've been using Log4perl extensively in a number of scripts. I'd like to augment those scripts to set an error code if any WARN or ERROR messages have been logged. I couldn't find any obvious way to do this based on existing documentation.

I'd like to avoid a brute-force rewrite of my existing scripts to add a check on every WARN or ERROR log message; I'd prefer to handle it prior to script exit if possible like this pseudocode:

if $log->has_warnings_or_errors then
  exit 1
else
  exit 0

Is there any easy way to call Log4Perl to determine if the current logger has issues messages of certain levels?


Solution

  • Use an appender.

    MyCounter.pm:

    package MyCounter;
    
    use warnings;
    use strict;
    
    use Log::Log4perl::Level;
    
    sub new {
      my($class,%arg) = @_;
      bless {} => $class;
    }
    
    sub log {
      my($self,%arg) = @_;
      ++$self->{ $arg{log4p_level} };
    }
    
    sub howmany {
      my($self,@which) = @_;
      my $total = 0;
      $total += ($self->{$_} || 0) for @which;
      $total;
    }
    
    1;
    

    myprog:

    #! /usr/bin/perl
    
    use warnings;
    use strict;
    
    use Log::Log4perl;
    
    my $conf = q(
      log4perl.category.MyLogger = INFO, Screen
    
      log4perl.appender.Screen = Log::Log4perl::Appender::Screen
      log4perl.appender.Screen.layout = Log::Log4perl::Layout::SimpleLayout
    );
    
    Log::Log4perl->init(\$conf);
    
    my $l = Log::Log4perl->get_logger("MyLogger");
    
    my $counter = Log::Log4perl::Appender->new("MyCounter");
    $l->add_appender($counter);
    
    $l->warn("warning");
    $l->info("info");
    $l->error("incorrect");
    $l->fatal("really bad, man");
    
    print $counter->howmany(qw/ WARN ERROR FATAL /), "\n";
    
    exit ($counter->howmany(qw/ WARN ERROR FATAL /) ? 1 : 0);
    

    Output:

    $ ./myprog 
    WARN - warning
    INFO - info
    ERROR - incorrect
    FATAL - really bad, man
    3
    $ echo $?
    1

    Comment out the ...->warn, ...->error, and ...->fatal lines to get

    $ ./myprog 
    INFO - info
    0
    $ echo $?
    0