Subject: | dispatch disregards individual output level settings |
My understanding is that each output specifies which levels it accepts
and should only be given valid messages. In Log::Dispatch 2.21 the log
method only checks if ANY of the outputs will accept the new message.
This results in messages appearing in outputs in which they should not
be expected.
Log::Dispatch::log checks logging levels across all outputs.
If the check succeeds, it then calls _log_to() which sends the message
to all outputs regardless of their individual min_level and/or max_level
settings.
This can be fixed by adding a _should_log() check in
Log::Dispatch::_log_to() before sending the message to each output (see
patch)
I've also included a simple test script which demonstrates this problem.
Steve
Subject: | Log.t |
#!/usr/bin/perl
use strict;
use warnings;
use YAML;
use Test::More;
use FindBin qw( $RealBin );
use lib "$RealBin/../../lib";
use SDE::Log
plan( 'tests' => 21 );
my $dispatcher = SDE::Log->dispatcher();
$dispatcher->add( LogTester->new(
'name' => 'debug',
'min_level' => 'debug',
'max_level' => 'info',
)
);
$dispatcher->add( LogTester->new(
'name' => 'runtime',
'min_level' => 'warning',
'max_level' => 'critical',
)
);
isa_ok( $dispatcher, 'Log::Dispatch', 'Expect a Log::Dispatch object' );
ok( $dispatcher->would_log( 'debug' ), 'debug should not be logged' );
ok( $dispatcher->would_log( 'info' ), 'info should not be logged' );
ok( ! $dispatcher->would_log( 'notice' ), 'notice should not be logged' );
ok( $dispatcher->would_log( 'warning' ), 'warning should be logged' );
ok( $dispatcher->would_log( 'error' ), 'error should be logged' );
ok( $dispatcher->would_log( 'critical' ), 'critical should be logged' );
ok( ! $dispatcher->would_log( 'alert' ), 'alert should not be logged' );
ok( ! $dispatcher->would_log( 'emergency' ), 'emergency should not be logged' );
$dispatcher->log( 'level' => 'debug', 'message' => 'debug message' );
$dispatcher->log( 'level' => 'info', 'message' => 'info message' );
$dispatcher->log( 'level' => 'notice', 'message' => 'notice message' );
$dispatcher->log( 'level' => 'warning', 'message' => 'warning message' );
$dispatcher->log( 'level' => 'error', 'message' => 'error message' );
$dispatcher->log( 'level' => 'critical', 'message' => 'critical message' );
$dispatcher->log( 'level' => 'alert', 'message' => 'alert message' );
$dispatcher->log( 'level' => 'emergency', 'message' => 'emergency message' );
my @debug_messages = $dispatcher->output( 'debug' )->messages();
is( $#debug_messages, 1, 'two debugging messages' );
is( $debug_messages[0]{'level'}, 'debug', 'first debug message should have the level: debug' );
is( $debug_messages[0]{'message'}, 'debug message', 'first debug message should have been a debug message' );
is( $debug_messages[1]{'level'}, 'info', 'second debug message should have the level: info' );
is( $debug_messages[1]{'message'}, 'info message', 'second debug message should have been an info message' );
my @runtime_messages = $dispatcher->output( 'runtime' )->messages();
is( $#runtime_messages, 2, 'three runtime messages' );
is( $runtime_messages[0]{'level'}, 'warning', 'first runtime message should have the level: debug' );
is( $runtime_messages[0]{'message'}, 'warning message', 'first runtime message should have been a debug message' );
is( $runtime_messages[1]{'level'}, 'error', 'second runtime message should have the level: error' );
is( $runtime_messages[1]{'message'}, 'error message', 'second runtime message should have been an error message' );
is( $runtime_messages[2]{'level'}, 'critical', 'third runtime message should have the level: critical' );
is( $runtime_messages[2]{'message'}, 'critical message', 'third runtime message should have been a critical message' );
exit( 0 );
package LogTester;
use YAML;
use Log::Dispatch::Output;
use base qw( Log::Dispatch::Output );
sub new
{
my $class = shift;
my $self = bless {}, $class;
$self->_basic_init( @_ );
$self->{'messages'} = [];
return $self;
}
sub log
{
my $self = shift;
my $message = { @_ };
push( @{$self->{'messages'}}, $message );
}
sub messages
{
my $self = shift;
return @{$self->{'messages'}};
}
Subject: | level_check.patch |
diff --git a/lib/Log/Dispatch.pm b/lib/Log/Dispatch.pm
index 0ad463c..a98f041 100755
--- a/lib/Log/Dispatch.pm
+++ b/lib/Log/Dispatch.pm
@@ -146,7 +146,7 @@ sub _log_to
if (exists $self->{outputs}{$name})
{
- $self->{outputs}{$name}->log(@_);
+ $self->{outputs}{$name}->log(@_) if $self->{outputs}{$name}->_should_log($p{level});
}
elsif ($^W)
{