Log4j2 在生产环境中禁用控制台
Log4j2 disable console on production
我正在开发 Web 应用程序并且我正在使用 log4j2。在开发模式下,我使用 RollingFile 和 Console appender 进行记录。
一切正常,但我想在我的项目发布时禁用控制台附加程序,并且它将处于生产模式。
这是我的 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>
谢谢!
使用 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) {
}
}
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-产品。因为Console的appender name还是console-local.
我的log4j版本是2.14.1
我正在开发 Web 应用程序并且我正在使用 log4j2。在开发模式下,我使用 RollingFile 和 Console appender 进行记录。
一切正常,但我想在我的项目发布时禁用控制台附加程序,并且它将处于生产模式。 这是我的 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>
谢谢!
使用 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) {
}
}
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-产品。因为Console的appender name还是console-local.
我的log4j版本是2.14.1