在Web应用程序中logging用户活动

我希望能够在Web应用程序中logging用户活动。 我目前正在使用log4j这适用于logging错误等,但我不确定最好的方法是logging用户,执行servlet方法和方法参数。 我正在使用spring security进行身份validation。

一个典型的servlet可能如下所示:

public class BankAccountServlet { @RequestMapping("/deposit") public void deposit(double amount) { ... } @RequestMapping("/checkBalance") public double checkBalance() { ... } } 

如果有两个用户foo和bar,foo检查他的余额,并且存入两个现金10.00和5.00。 我希望日志看起来像:

 01/01/1970 23:59:59 - foo - checkBalance 02/01/1970 23:59:59 - bar - deposit - 10.00 02/01/1970 23:59:59 - bar - deposit - 5.00 

如果有人能提供一些build议,我真的很感激他们的帮助。

实现使用Log4J中内置的MDC / NDCfunction(SLF4J和Logback仅支持MDC)实际上非常简单。

实现MDCfilter

首先,实现一个将用户名添加到MDC / NDC的servletfilter。 Logback提供了方便的MDCInsertingServletFilter ,Spring框架还将Log4jNestedDiagnosticContextFilter添加到商店。 看看他们,但你会需要一个像这样的自定义:

 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值添加到您的日志logging模式

确保在Spring安全筛选器之后的web.xml应用此筛选器。 MDCfunction是非常灵活的 – 它会将所有保存在MDC线程本地映射中的值添加到每个日志logging语句中(如果需要的话)。 在你的情况下,只需添加这个:

 %X{user} 

到你的日志模式 。

不显眼的logging方法参数/值

logging方法名称,参数和返回值取决于您(用户名将自动添加),但有一些优雅的方式来完全删除样板日志代码。 试试这个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
  • 考虑使用Logback作为日志库,并使用SLF4J API。

我以前使用过log4j来logging不止错误。 我在我的代码中添加了INFO标签并更改日志级别。 这样,如果您决定不再需要logging这些活动,则只需更改日志logging级别即可完成。 我希望有帮助。

如果要login服务器日志,请使用使用容器日志logging机制的ServletContext.log()方法并login到容器日志中。