18

Spring の @Scheduled アノテーションを使用して、数秒ごとにメソッドを実行することに成功しています。唯一の問題は、この方法が原因で、Hibernate と Spring からトランザクションなどに関する多くのログ メッセージを取得することです。

アプリケーション内の他のトランザクションについてこの情報を受け取りたいので、ロギング レベルを同じに保ちたいと考えています。

特定のメソッドの実行中に別のライブラリのログを一時的に抑制する方法はありますか?

4

3 に答える 3

5

通常、ログ フレームワークはパッケージレベルのログ構成をサポートします。logback.xmlファイルで以下のようなことができます:

<configuration>
    <logger name="org.hibernate.transaction" level="OFF"/>   // change log level to suppress here
     <logger name="org.springframework.transaction" level="OFF"/>

    <root level="ALL">
        <appender class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{ISO8601} | %-5level | %thread | %logger{1} | %m%n</pattern>
            </encoder>
        </appender>
    </root>
</configuration>

jboss アプリケーション サーバーでは、以前に同じ問題があり、以下のようにパッケージ レベルのログ構成で不要なログをフィルター処理しました。

<logger category="com.lftechnology.sbworkbench">
    <level name="DEBUG"/>
</logger>
<logger category="org.quartz">
    <level name="WARN"/>
</logger>
<logger category="com.liferay.portal">
    <level name="INFO"/>
</logger>
<logger category="org.jboss.as.server.deployment">
    <level name="ERROR"/>
</logger> 

特定の方法でライブラリのログを抑制することに関心があるため、プログラムでそれを行い、終了時に復元する必要があります。しかし、それが特定のコード ブロックに影響するかどうかはわかりません。

さらに、アプリケーションが同時に実行される場合、以下のようにThreadLocalを使用できます

public Class A implements Runnable {
    //you can later dynamically configure this variable also
    private static final ThreadLocal<Logger> CLASS_LOGGER = new ThreadLocal<Logger>(){
       Logger LOGGER = LoggerFactory.getLogger(A.class);
         return LOGGER;
       }

     @Override
 public void run() {
   //before calling your function change log level
   //as we declare local variable here this most likely  to affect log here only
   Logger Logger = LoggerFactory.getLogger("org.hibernate.transaction");
   Level oldLogLevel = Logger.getLevel(); 
   Logger.setLevel(Level.OFF); // 

   callYourFunction();

   //restore log level to previous
   Logger.setLevel(oldLogLevel);

 }

ここに同様の答えがあります

于 2014-05-22T08:24:12.683 に答える
5

はい: ロガーのログ レベルを動的に設定できるため、時間の経過とともに変更できます。

理想的には、関連するクラス階層の最上位にあるロガーを取得し、ログ レベルを任意に設定するだけです。たとえば、休止状態の場合:

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;

// When you want to temporarily change the log level
Logger orgHibernateLogger = LoggerFactory.getLogger("org.hibernate");
Level oldLogLevel = orgHibernateLogger.getLevel();
orgHibernateLogger.setLevel(Level.ERROR); // or whatever level you want

// When you want to return to the old log level
orgHibernateLogger.setLevel(oldLogLevel);

これは、関連する階層内の他のロガーがログ レベルを明示的に構成していない限り、機能するはずです。階層内の他のロガーがログ レベルを明示的に構成している場合は、明示的に設定されたすべてのログ レベルを一時的に調整し、最後にすべてを「通常」に戻す必要があります。

これはコンテキスト ベースのアプローチではなく、時間ベースのアプローチであることに注意してください。一時ログ レベルの使用中に他のコードがライブラリを同時に使用すると、その一時ログ レベルも取得されます。ログレベルは、通常に戻ったときにのみ「通常」に戻ります。一時的なログレベルを使用しているときに他のコードの実行を妨げずにそれを回避する簡単な方法はないと思います。

編集:目的のスレッドでのみ不要なログをオフにできる方法については、Durron597 による回答を参照してください。少し単純ではありませんが、うまくいくようです。

于 2014-05-15T17:53:38.690 に答える