66

アプリケーション(Spring Integration)にdebug.logとmain.logの2つのログファイルが必要です。main.logをINFOレベルで実行し、debug.logをDEBUGレベルで実行したいと思います。これは、アペンダーのフィルターで実行できます。ソースに基づいて、さまざまなレベルをアペンダーに記録したいと思います。言い換えると

<logger name="org.springframework" level="ERROR">
    <appender-ref ref="main" />
</logger>
<logger name="org.springframework" level="DEBUG">
    <appender-ref ref="debug" />
</logger>
<logger name="com.myapp" level="INFO">
    <appender-ref ref="main" />
</logger>
<logger name="com.myapp" level="DEBUG">
    <appender-ref ref="debug" />
</logger>

要約すると、次のようになります。

  1. 春のロガー
    • メイン->エラー
    • デバッグ->デバッグ
  2. com.myappロガー
    • メイン->情報
    • デバッグ->デバッグ

このため、DEBUGでロガーを実行する必要があり、アペンダーのしきい値フィルターは十分に細かく設定されていません。

更新質問に明確さを追加

4

6 に答える 6

56

次のようなアペンダーに配置できるThresholdLoggerFilterクラスを作成します。

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <filter class="com.myapp.ThresholdLoggerFilter">
        <logger>org.springframework</logger>
        <level>ERROR</level>
    </filter>
    </appender>

次のコードは機能します

package com.myapp;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

public class ThresholdLoggerFilter extends Filter<ILoggingEvent> {
    private Level level;
    private String logger;

    @Override
    public FilterReply decide(ILoggingEvent event) {
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }

        if (!event.getLoggerName().startsWith(logger))
            return FilterReply.NEUTRAL;

        if (event.getLevel().isGreaterOrEqual(level)) {
            return FilterReply.NEUTRAL;
        } else {
            return FilterReply.DENY;
        }
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    public void setLogger(String logger) {
        this.logger = logger;
    }

    public void start() {
        if (this.level != null && this.logger != null) {
            super.start();
        }
    }
}
于 2012-05-24T09:00:38.293 に答える
21

ルートロガーから継承する場合は、これをもう少し簡単に行うこともできます。たとえば、ここでは、エラー用に追加のロガーを追加して、stderrにログを記録します。特定のロガーに対してのみ有効になります。

<configuration>
    <appender name="CONSOLE-stdout" class="ch.qos.logback.core.ConsoleAppender">
        <target>System.out</target> <!-- the default -->
        <encoder>
            <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="CONSOLE-stderr" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>

        <target>System.err</target>
        <encoder>
            <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="CONSOLE-stdout" />
    </root>

        <!-- We want error logging from this logger to go to an extra appender 
             It still inherits CONSOLE-stdout from the root logger -->
    <logger name="org.springframework" level="INFO">
        <appender-ref ref="CONSOLE-stderr" />
    </logger>
</configuration>
于 2012-05-24T10:14:20.797 に答える
18

すでにここにあるものよりも簡単な追加のソリューションを追加する

SparkやSpringのようなフレームワークを使用していないため、これらのソリューションはどれもうまくいきませんでした。だから私はうまく機能しているように見えるもう少し簡単なことをしました。このソリューションはOPには機能しない可能性がありますが、それほどかさばらないものが必要な場合に役立つ可能性があります。

<property name="pattern" value="%d{yyyy.MMM.dd HH:mm:ss.SSS} [ProgramName] %level - %msg%n" />

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/path/to/your/program.log</file>
    <append>true</append>
    <encoder>
        <pattern>${pattern}</pattern>
    </encoder>
</appender>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <target>System.out</target>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <encoder>
        <pattern>${pattern}</pattern>
    </encoder>
</appender>

<root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
</root>

この構成では、DEBUGステートメントをログファイルに出力しながら、コンソールをかなりクリーンに保つことができます。

于 2017-04-19T20:01:02.727 に答える
7

ログバック要素のみを使用して非常にうまく機能する実用的な解決策を見つけました。基本的に、2つのアペンダーが必要です。1つはデフォルトの構成で、もう1つはフィルターがあります(私の例ではコンソールを使用しています)。

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="WARN_FILTER_STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>WARN</level>
        </filter>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="org.apache.spark" level="INFO" additivity="false">
        <appender-ref ref="SPARK" /><!-- this line is not necessary, just here to ilustrate the need for the filter -->
        <appender-ref ref="WARN_FILTER_STDOUT" />
    </logger>

    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
于 2016-11-12T04:09:10.987 に答える
1

異なるメッセージに複数のロガーを使用すると、次のようになります。

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;

public class ConfigureLogBack 
{
    public static void programmaticConfiguration()
    {
        Logger camel = getLogger("MyRoute", C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\camel-Log.txt");
        Logger services = getLogger("webservices", "C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\services-log.txt");
    }

    private static Logger getLogger(String string, String file) {
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    PatternLayoutEncoder ple = new PatternLayoutEncoder();

    ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
    ple.setContext(lc);
    ple.start();
    FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
    fileAppender.setFile(file);
    fileAppender.setEncoder(ple);
    fileAppender.setContext(lc);
    fileAppender.start();

    Logger logger = (Logger) LoggerFactory.getLogger(string);
    logger.addAppender(fileAppender);
    logger.setLevel(Level.INFO);
    logger.setAdditive(false); /* set to true if root should log too */

    return logger;
}
于 2014-01-22T10:30:34.057 に答える
1

アペンダーのしきい値フィルターが十分に細かく設定されていません

EvaluatorFilterを使用できます。JaninoEventEvaluatorにはjanino(.jar)への参照が必要であり、logback.xmlの例は次のようになります。

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
        <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
            <expression>
                level &lt;= ERROR &amp;&amp; logger.equals(&quot;com.myapp.ThresholdLoggerFilter&quot;)
            </expression>
        </evaluator>
        <OnMismatch>DENY</OnMismatch>
        <OnMatch>NEUTRAL</OnMatch>
    </filter>
 </appender>

このアプローチでは、式タグ内のJava式(xmlエスケープする必要があります)を使用してロギングイベントを評価し、カスタムJavaクラスを作成する必要はありません。

于 2018-12-13T17:49:41.393 に答える