Log4j2分析与实践-日志分离

    很多时候,多个应用共享一个运行环境,而每个应用需要有自己独立的日志环境。本文的目的就是讨论如何实现日志分离。

使用场景

单独的应用

    单独的应用通常相对比较简单,它们仅需要一个单独的配置即可。

Web应用

    一个典型的Web应用会被打包为WAR文件,会在WEB-INF/lib目录下包含所有的依赖,而在classpath下也会有自己的配置文件(或者在web.xml配置了路径)。

可共享的Web应用和REST服务容器

    这种场景下,会在一个容器里部署多个WAR文件。每个应用都会共享相同的日志配置和实现。当向文件或者流中写入数据时,所有的应用应该共享这个操作过程,以此来避免多个组件通过不同的对象或者通道向相同文件写入数据。

解决方法

简单方法

    最简单的方法就是为每个应用准备一份自己的Log4j拷贝,并且使用BasicContextSelector。在单独应用中这种方法是适用的,也许在Web应用中也会适用。

使用上下文选择器

(1)将Log4j2的jar包放到容器的classpath下面,然后将系统属性Log4jContextSelector设置为org.apache.logging.log4j.core.selector.BasicContextSelector。这样就会使用一个单一的配置创建一个单例的LoggerContext,所有应用生效。
(2)将Log4j2的jar包放到容器的classpath下面,然后使用默认的ClassLoaderContextSelector。容器中的每个应用可以使用同一份配置,或者单独配置。
(3)将系统属性或者Servlet上下文参数Log4jContextSelector 设置为org.apache.logging.log4j.core.selector.JndiContextSelector。这样就会使得容器使用JNDI来定位Web应用的LoggerContext。确保将isLog4jContextSelectorNamed设置为true,同时设置log4jContextName和log4jConfiguration上下文参数。
    设置系统参数的具体方法取决于容器,对于Tomcat而言,直接编辑$CATALINA_HOME/conf/catalina.properties就好了。