有一个Spring应用程序,我需要将不同的servlet请求路由到两个不同的日志文件中。我在Spring的过滤器链中创建了一个过滤器,并尝试设置一个有效的log4j2配置。
过滤器:
@Component
public class LogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
if (request.getServletPath().contains("healthcheck")) {
try (CloseableThreadContext.Instance context = CloseableThreadContext.put("health", "true")) {
chain.doFilter(request, response);
}
} else {
try (CloseableThreadContext.Instance context = CloseableThreadContext.put("health", "false")) {
chain.doFilter(request, response);
}
}
}
}
Log4j2配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Appenders>
<Routing name="Routing">
<Routes pattern="$${health}==true">
<Route>
<RollingRandomAccessFile name="FILE"
fileName="logs/reference-service.log"
filePattern="logs/reference-service.log.%d{yyyy-MM-dd-hh-mm}.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1024 KB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Route>
</Routes>
<Routes pattern="$${health}==false">
<Route>
<RollingRandomAccessFile name="FILE_HEALTH"
fileName="logs/reference-service-health.log"
filePattern="logs/reference-service-health.log.%d{yyyy-MM-dd-hh-mm}.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1024 KB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="org.hibernate" level="info" additivity="false">
<AppenderRef ref="FILE"/>
<AppenderRef ref="FILE_HEALTH"/>
</Logger>
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="FILE"/>
<AppenderRef ref="FILE_HEALTH"/>
</Logger>
<Root level="debug">
<AppenderRef ref="FILE"/>
<AppenderRef ref="FILE_HEALTH"/>
</Root>
</Loggers>
</Configuration>
使用上述配置,日志记录根本无法正常工作。 使用Logback可以轻松实现该任务,但是不幸的是,我必须坚持使用Log4j2。
==================================== 更新
这是通过注销实现的方式。
@Component
public class LogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
try {
if (request.getServletPath().contains("healthcheck")) {
MDC.put("health", "true");
}
chain.doFilter(request, response);
} finally {
MDC.remove("health");
}
}
}
public class MdcFilterHealth extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
String marked = event.getMDCPropertyMap().get("health");
if (!"true".equals(marked)) {
return FilterReply.DENY;
} else {
return FilterReply.NEUTRAL;
}
}
}
public class MdcFilterNonHealth extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
String marked = event.getMDCPropertyMap().get("health");
if ("true".equals(marked)) {
return FilterReply.DENY;
} else {
return FilterReply.NEUTRAL;
}
}
}
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="myservice.config.MdcFilterNonHealth"/>
<file>logs/reference-service.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} | [%thread] | %-5level | %-30.30M | %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/archived/reference-service_%d{dd-MM-yyyy}.log</fileNamePattern>
<maxHistory>10</maxHistory>
<totalSizeCap>1024KB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="FILE_HEALTH" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="myservice.config.MdcFilterHealth"/>
<file>logs/reference-service-health.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} | [%thread] | %-5level | %-30.30M | %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/archived/reference-service-health_%d{dd-MM-yyyy}.log</fileNamePattern>
<maxHistory>10</maxHistory>
<totalSizeCap>1024KB</totalSizeCap>
</rollingPolicy>
</appender>
<Logger name="org.hibernate" level="info" additivity="false">
<appender-ref ref="FILE"/>
<appender-ref ref="FILE_HEALTH"/>
</Logger>
<Logger name="org.springframework" level="info" additivity="false">
<appender-ref ref="FILE"/>
<appender-ref ref="FILE_HEALTH"/>
</Logger>
<root level="debug">
<appender-ref ref="FILE"/>
<appender-ref ref="FILE_HEALTH"/>
</root>
</configuration>
答案 0 :(得分:0)
因此,找到的解决方案是:
@Component
public class LogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
if (request.getServletPath().contains("healthcheck")) {
try (CloseableThreadContext.Instance context = CloseableThreadContext.put("health", "true")) {
chain.doFilter(request, response);
}
} else {
chain.doFilter(request, response);
}
}
}
<Configuration status="WARN" monitorInterval="30">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT" follow="true">
<PatternLayout
pattern="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} %highlight{${LOG_LEVEL_PATTERN:-%5p}}{FATAL=red blink, ERROR=red, WARN=yellow, INFO=green, DEBUG=blue, TRACE=white} %style{${sys:PID}}{magenta} [%15.15t] %style{%-40.40C{1.}}{cyan} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
</Console>
<Routing name="ROUTING">
<Routes pattern="$${ctx:health}">
<Route key="true">
<RollingRandomAccessFile name="FILE_HEALTH"
fileName="logs/reference-service-health.log"
filePattern="logs/reference-service-health.log.%d{yyyy-MM-dd-hh-mm}.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1024 KB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Route>
<Route>
<RollingRandomAccessFile name="FILE"
fileName="logs/reference-service.log"
filePattern="logs/reference-service.log.%d{yyyy-MM-dd-hh-mm}.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1024 KB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="org.hibernate" level="info" additivity="false">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="ROUTING"/>
</Logger>
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="ROUTING"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="ROUTING"/>
</Root>
</Loggers>
</Configuration>