3

2 つのアペンダー (1 つの画面と他のファイル) を持つロガーがあります。変更可能な可変ログレベルを備えた画面アペンダーと、何があってもすべてをログに記録するファイルアペンダーが必要です。したがって、たとえば、画面への出力を無効にすることができます (Screen アペンダー) が、ログファイル (ファイル アペンダー) で TRACE のレベルまでの完全なログを取得できます。Screen アペンダーの変更には成功しましたが、同じロガーの File アペンダーを TRACE のレベルに設定できません。さまざまなしきい値設定を使用してみましたが、成功しませんでした。

# Define a category logger
my $log = Log::Log4perl->get_logger("main");

# Define a layout
my $layout = Log::Log4perl::Layout::PatternLayout->new("[%d{yyyy/MM/dd HH:mm:ss,SSS}]%m%n");

# Define a file appender
my $file_appender = Log::Log4perl::Appender->new(
                    "Log::Log4perl::Appender::File",
                    name      => "Logfile",
                    filename  => "$logfile",
                    autoflush => 1,
                    umask => 022,
                    header_text => "INVOCATION:$0 @ARGV", 
                    #Threshold => "TRACE",  DOES NOT WORK
                );

# Define a stderr appender
my $stderr_appender =  Log::Log4perl::Appender->new(
                    "Log::Log4perl::Appender::ScreenColoredLevels",
                    name      => "Screen",
                    stderr    => 1,
                );

# Have both appenders use the same layout (could be different)
$stderr_appender->layout($layout);
$file_appender->layout($layout);

#add both appenders to logger
$log->add_appender($stderr_appender);
$log->add_appender($file_appender);

#add a level to logger
#$log_level coming from command line or configuration
$log->level($log_level);

#$file_appender->threshold( "TRACE" );   THIS DOES NOT WORK
#Log::Log4perl->appender_thresholds_adjust(-1, ['Logfile']);   NOR THIS

#check your appenders
#print Dumper( Log::Log4perl->appenders() );   
4

1 に答える 1

4

log4perl FAQから:

ERROR および WARN メッセージを別のファイルに記録したい! どうやってやるの?

ステートメントの優先度に基づいて、各ログ ステートメントを異なるファイルに書き込む必要があるとします。優先度が WARN のメッセージは /tmp/app.warn に送られ、優先度が ERROR のイベントは /tmp/app.error に送られるはずです。

ここで、AppWarn と AppError の 2 つのアペンダーを定義し、両方をルート ロガーに割り当てると、Log4perl のメッセージ伝播機能により、下のロガーから発生するメッセージが両方のアペンダーによってログに記録されます。アペンダーのしきい値メカニズムを介してそれらの露出を制限し、AppWarn のしきい値を WARN に設定し、AppError を ERROR に設定した場合でも、AppWarn でエラー メッセージが表示されます。これは、AppWarn の WARN 設定が WARN よりも優先度の低いメッセージを除外するためです。エラーは高くなり、通過が許可されます。

これに必要なのは、Log::Log4perl 0.30 で利用可能な Log4perl カスタム フィルターです。

両方のアペンダーは、着信メッセージの優先度が、アペンダーがメッセージをログに記録することになっている優先度と正確に一致することを確認する必要があります。このタスクを達成するために、MatchError と MatchWarn という 2 つのカスタム フィルターを定義しましょう。これらは、アペンダーにアタッチされると、渡されるメッセージを特定の優先度に一致するものに制限します。

   log4perl.logger = WARN, AppWarn, AppError
        # Filter to match level ERROR
    log4perl.filter.MatchError = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.MatchError.LevelToMatch  = ERROR
    log4perl.filter.MatchError.AcceptOnMatch = true
        # Filter to match level WARN
    log4perl.filter.MatchWarn  = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.MatchWarn.LevelToMatch  = WARN
    log4perl.filter.MatchWarn.AcceptOnMatch = true
        # Error appender
    log4perl.appender.AppError = Log::Log4perl::Appender::File
    log4perl.appender.AppError.filename = /tmp/app.err
    log4perl.appender.AppError.layout   = SimpleLayout
    log4perl.appender.AppError.Filter   = MatchError
        # Warning appender
    log4perl.appender.AppWarn = Log::Log4perl::Appender::File
    log4perl.appender.AppWarn.filename = /tmp/app.warn
    log4perl.appender.AppWarn.layout   = SimpleLayout
    log4perl.appender.AppWarn.Filter   = MatchWarn

上記で定義されたアペンダー AppWarn および AppError は、それぞれ /tmp/app.warn および /tmp/app.err にログを記録し、カスタム フィルター MatchWarn および MatchError がアタッチされています。この設定により、システム内のどこかで発行されたすべての WARN メッセージが /tmp/app.warn (および ERROR メッセージが /tmp/app.error) に送信されますが、重複することはありません。

log4perl とそのサブモジュールの CPAN ドキュメントも参照してください。

http://search.cpan.org/~mschilli/Log-Log4perl-1.46/lib/Log/Log4perl/Filter.pm

于 2016-02-14T19:27:36.990 に答える