log 4 j 2の再ロード、および異なるレベルのログが異なるログファイルに出力されることについて

5527 ワード

log4j2[2.1]
log 4 j 2のプロファイル形式はJSON、またはXMLとすることができる.
一般にclasspathパスでlog 4 j 2を検索する.json、またはlog 4 j 2.xml,
あるいは、システムパラメータを使用してプロファイルを設定することもできます.たとえば、コマンドラインで起動するアプリケーションです.
-Dlog4j.configurationFile=path/to/log4j2.xml

アプリケーション起動時にlog 4 j 2をclasspathやシステムパラメータでプロファイルを検索して初期化するほか、コードにlog 4 j 2のプロファイルをいつでも再ロードして再構成することもできます.
例えば、WEBアプリケーションではlog 4 j 2を使用することを望んでいない一般的なシーンを考えてみましょう.xmlを自分のjarファイルにパッケージ(log 4 j 2の構成を変更するのは面倒)、log 4 j 2も望んでいません.xmlはWEB-INF/classesの下に置いて(ユーザーが勝手にWEB-INFの下のファイルを操作することを望んでいない)、それではlog 4 j 2をxmlや他のプロジェクトで使用されるプロファイルは、TOMCAT/bin/configなどの集中的な場所に配置されます.この場合、log 4 j 2を初期化するとしますか?InitServiceletを提供します.たとえば、次のようにします.

...
public void init() throws ServletException {
    String configRoot = this.getInitParameter("configRoot");
    String log4j2Config = configRoot + File.separator + this.getInitParameter("log4j2Config");
    File file = new File(log4j2Config);
    try {
        LoggerContext context =(LoggerContext)LogManager.getContext(false);
        context.setConfigLocation(file.toURI());
        
        //     Log4j2      
        context.reconfigure();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    
    //todo:      logger,              
    logger = LogManager.getLogger(DefaultInitServlet.class);
}

それに対応して、webでさえあれば.xmlはこのInitServiceletを構成し、configRootとlog 4 j 2 configの2つのパスを提供すればよい(configRootを構成するのではなく、System.getProperty(「user.dir」)を通じてアプリケーションの実行ディレクトリを取得することもできる.tomcatにとって、このディレクトリはtomcat/binであり、コマンドラインのようなアプリケーションがbat/shのディレクトリである)
web.xml
参照

    InitServlet
    test.InitServlet
    0
   
       
        configRoot
        d://config
   

   
       
        log4j2Config
        log4j2/log4j2.xml
   


では、log 4 j 2を再初期化する方法について説明し、異なるレベルのログを異なるログファイルに出力する方法について説明します.これはネット上で、公式サイトを含めて、はっきり言っている人は一人もいません.
例えば、trace/debugレベルのログをdebugに出力.log、infoレベルのログがinfoに出力.log、warn/error/fatalレベルなどの他のログはerrorに出力される.log、このように出力を分けるのはメリットがあります.私たちは以下のlog 42 jに従います.xmlの構成で、このような出力を実現できます.

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="off" monitorInterval="1800">
    <Properties>
        <Property name="log-path">d://logs</Property>
    </Properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36}.%M()/%L  - %msg%xEx%n"/>
        </Console>

        <File name="app_debug" fileName="${log-path}/app/debug.log" append="false">
            <Filters>
                <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
        </File>
        <File name="app_info" fileName="${log-path}/app/info.log" append="false">
            <Filters>
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>

            <PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
        </File>
        <File name="app_error" fileName="${log-path}/app/error.log" append="false">
            <Filters>
                <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="com.test.app" level="trace" additivity="false">
            <appender-ref ref="Console"/>
            <appender-ref ref="app_debug"/>
            <appender-ref ref="app_info"/>
            <appender-ref ref="app_error"/>
        </Logger>
    </Loggers>
</configuration>

主にThresholdFilterのonMatch/onMismatchの3つのオプション値:ACCEPT/DNY/NEUTRALを理解するのですが、実は、字面の意味によってもよく理解できます.
重要なのは、複数のThresholdFilterがある場合、Filtersは必須であると同時に、Filtersではまず該当しないログレベルをフィルタリングし、不要なものをまずDENYから外し、次にACCEPTに必要なログレベルをACCEPTし、この順序を逆転させることはできない.