使用 Log4J 内置的 MDC/NDC 功能实际上非常简单(SLF4J 和 Logback 仅支持 MDC)。
实施 MDC 过滤器
首先,实现一个 servlet 过滤器,将用户名添加到 MDC/NDC。 Logback提供了方便MDC插入Servlet过滤器 http://logback.qos.ch/apidocs/ch/qos/logback/classic/helpers/MDCInsertingServletFilter.html,Spring框架还添加了Log4jNestedDiagnosticContextFilter http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/filter/Log4jNestedDiagnosticContextFilter.html到商店。看看它们,但你需要一个像这样的定制的:
public class UserToMdcFilter implements javax.servlet.Filter
{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
MDC.put("user", SecurityContextHolder.getContext().getAuthentication().getPrincipal());
try {
chain.doFilter(request, response);
} finally {
MDC.remove("user");
}
}
//...
}
将 MDC 价值添加到您的日志记录模式中
确保此过滤器应用于web.xml
在 Spring 安全过滤器之后。 MDC 功能非常灵活 - 如果需要,它会将 MDC 线程本地映射中保存的所有值添加到每个日志记录语句中。对于您的情况,只需添加以下内容:
%X{user}
到你的日志记录pattern http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html.
不显眼的记录方法参数/值
记录方法名称、参数和返回值由您决定(用户名将自动添加),但是有一些优雅的方法可以完全删除样板记录代码。尝试这个 Spring 内置方面:
<bean id="customizableTraceInterceptor" class="org.springframework.aop.interceptor.CustomizableTraceInterceptor">
<property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
<property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
</bean>
<aop:config>
<aop:advisor advice-ref="customizableTraceInterceptor" pointcut="execution(public * BankAccountServlet.*(..))"/>
</aop:config>
最后的想法
- 看看这个线程:http://forum.springsource.org/showthread.php?88890-MDC-Log4j-Filter-with-Spring-Security-3.0.2 http://forum.springsource.org/showthread.php?88890-MDC-Log4j-Filter-with-Spring-Security-3.0.2
- 考虑使用Logback http://logback.qos.ch/作为日志库并坚持使用 SLF4J API。