在Web应用程序中记录用户活动

Jam*_*mes 13 java logging servlets dwr spring-security

我希望能够在Web应用程序中记录用户活动.我目前正在使用log4j,它适用于日志记录错误等,但我不确定最好的方法是记录用户,执行的servlet方法和方法参数.我正在使用spring security进行身份验证.

典型的servlet可能如下所示:

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

    @RequestMapping("/checkBalance")
    public double checkBalance() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果有两个用户,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
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*icz 32

使用内置于Log4J中的MDC/NDC功能实现非常简单(SLF4J和Logback仅支持MDC).

实现MDC过滤器

首先,实现一个servlet过滤器,它将向MDC/NDC添加用户名.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");
        }
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

将MDC值添加到日志记录模式中

确保web.xml在Spring安全过滤器之后应用此过滤器.MDC功能非常灵活 - 如果需要,它会将MDC线程局部映射中保存的所有值添加到每个日志记录语句中.在您的情况下,只需添加:

%X{user}
Run Code Online (Sandbox Code Playgroud)

你的日志模式.

不显眼的记录方法参数/值

记录方法名称,参数和返回值取决于您(用户名将自动添加),但有一些优雅的方法可以完全删除样板记录代码.试试这个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>
Run Code Online (Sandbox Code Playgroud)

最后的想法