【问题标题】:Log4j2 disable console on productionLog4j2 在生产中禁用控制台
【发布时间】:2019-04-22 20:12:35
【问题描述】:

我正在开发一个 Web 应用程序,我正在使用 log4j2。在开发模式下,我使用 RollingFile 和 Console appenders 进行日志记录。

一切正常,但我想在我的项目发布时禁用控制台附加程序,它将处于生产模式。 这是我的 log4j2.xml 代码的一部分:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="PropertiesConfig" packages="com.project.application">

    <!-- PROPERTIES -->
    <Properties>
        <Property name="webName">Project</Property> 
        <Property name="logBaseDir">${sys:catalina.base}/logs/</Property>
        <Property name="consolePattern">%highlight{[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n}</Property>
        <Property name="rollingFilePattern">[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n</Property>
    </Properties>

    <!-- APPENDERS -->
    <Appenders>
        <!-- Console -->
        <Console name="Console" 
                 target="SYSTEM_OUT"
                 immediateFlush="true">
            <PatternLayout>
                <pattern>${consolePattern}</pattern>
            </PatternLayout>
        </Console>

        <!-- RollingFile -->
        <RollingFile name="RollingFile" 
                     fileName="${sys:logBaseDir}${webName}/${webName}.log"
                     filePattern="${sys:logBaseDir}${webName}.%d{yyyy-MM-dd}.log"
                     immediateFlush="true">
            <PatternLayout>
                <pattern>${rollingFilePattern}</pattern>
            </PatternLayout>
            <Policies>
                <OnStartupTriggeringPolicy />
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

    <!-- LOGGERS -->
    <Loggers>
        <Logger name="com.project.application" additivity="true" level="warn">
            <AppenderRef ref="RollingFile" />
        </Logger>

        <Root level="info"> <!-- @TODO disable in production -->
            <AppenderRef ref="Console" />                
        </Root>
    </Loggers>

</Configuration> 

谢谢!

【问题讨论】:

    标签: log4j2 appender


    【解决方案1】:

    使用filter,例如ThreadContextMapFilter:

    <Console name="Console" target="SYSTEM_OUT" immediateFlush="true">
      <ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL">
        <KeyValuePair key="is-production" value="1"/><!-- skip on production -->
      </ThreadContextMapFilter>
      <PatternLayout>
        <pattern>${consolePattern}</pattern>
      </PatternLayout>
    </Console>
    

    ThreadContext 条目的初始化可以在ServletContextListener 中执行,例如:

    @WebListener
    public class Log4jThreadContextInitializer implements ServletContextListener {
    
      @Override
      public void contextInitialized(ServletContextEvent sce) {
        String isProduction = isProduction() ? "1" : "0";
        sce.getServletContext().log("Setting 'is-production' flag for Log4j to " + isProduction);
        org.apache.logging.log4j.ThreadContext.put("is-production", isProduction);
      }
    
      private boolean isProduction() {
        // TODO: production detection
      }
    
      @Override
      public void contextDestroyed(ServletContextEvent sce) {
      }
    }
    

    【讨论】:

    • 非常感谢!一些问题:我可以直接将xml中的值设置为“1”或“0”而不是别的吗?为什么要在 ServletContextListener 中初始化?
    • @Ommadawn 但是如果您要在 XML 中设置值(我什至不知道这是否可能),您将如何检测它是否 生产或不?也许,那时您需要一个不同的log4j2.xml 进行生产。请注意,我发布的log4j2.xml 中的代码没有 设置任何内容 - 它仅测试 值是否设置为"1"
    • 我只想要一个值,如果它设置为 1,它会禁用控制台输出打印
    • @Ommadawn 恐怕我不明白。在答案中,我已经展示了如何做到这一点。如果有不清楚的地方,请更具体地说明您的期望。
    • @Ommadawn 是的,如果在ThreadContext 中将is-production 设置为1,Log4j2 将跳过控制台附加程序(因为ThreadContextMapFilter 配置为onMatch="DENY",这意味着它会跳过如果条件匹配,则追加)。
    【解决方案2】:

    Spring-lookup 让我的生活更轻松。我的 appender 是这样的:

    <Appenders>
        <Console name="console-local" target="SYSTEM_OUT">
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{2}:%L - %msg%n" />
        </Console>
    </Appenders>
    

    我添加了这样的属性:

    <Properties>
        <Property name="console-appender">console-${spring:profiles.active}</Property>
    </Properties>
    

    而记录器是这样的:

    <Loggers>
        <root level="info">
            <appender-ref ref="${console-appender}"/>
        </root>
    </Loggers>
    

    如果我的活动配置文件是 local,那么 console-appender 将被设置为 console-local,并且日志将显示在console,因为 ref 会找到 console-local

    再次假设,我的活动配置文件是 prod,那么 console-appender 将设置为 console-prod,并且日志将不会显示在 console 中,因为 ref 不会找到 console-prod。因为 Console 的 appender 名称仍然是 console-local

    我的 log4j 版本是 2.14.1

    【讨论】:

      猜你喜欢
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 2013-02-15
      相关资源
      最近更新 更多