在 Web 应用中记录用户活动

2022-09-03 17:24:51

我希望能够在 Web 应用中记录用户活动。我目前正在使用log4j,它适用于记录错误等,但我不确定记录用户,执行的servlet方法和方法参数的最佳方法是什么。我正在使用弹簧安全性进行身份验证。

典型的 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

如果有人能提供一些建议,我将不胜感激他们的帮助。


答案 1

实际上,使用 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");
        }
    }

    //...
}

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

确保在 Spring 安全筛选器之后应用此筛选器。MDC 功能非常流畅 - 如果需要,它会将保存在 MDC 线程本地映射中的所有值添加到每个日志记录语句中。在您的情况下,只需添加以下内容:web.xml

%X{user}

到日志记录模式

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

日志记录方法名称,参数和返回值由您决定(用户名将自动添加),但是有一些优雅的方法可以完全删除样板日志记录代码。试试这个春天内置的方面:

<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>

最后的思考


答案 2

我过去使用log4j来记录的不仅仅是错误。我在整个代码中添加了 INFO 标记并更改了日志记录级别。这样,如果您决定不再需要记录这些活动,只需更改日志记录级别即可完成。我希望这有帮助。