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

Posted

技术标签:

【中文标题】在 Web 应用程序中记录用户活动【英文标题】:Logging user activity in web app 【发布时间】:2011-09-01 05:34:44 【问题描述】:

我希望能够在网络应用中记录用户活动。我目前正在使用 log4j,它可以很好地记录错误等,但我不确定记录用户、执行的 servlet 方法和方法参数的最佳方法是什么。我正在使用 Spring Security 进行身份验证。

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

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

    @RequestMapping("/checkBalance")
    public double checkBalance() 
        ...
    

如果有两个用户,foo 和 bar,foo 检查他的余额,bar 存入两笔现金 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 是为了记录更多的错误。我在整个代码中添加了 INFO 标签并更改了日志记录级别。这样,如果您决定不再需要记录这些活动,您只需更改记录级别即可。我希望这会有所帮助。

【讨论】:

【参考方案2】:

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

实现 MDC 过滤器

首先,实现一个 servlet 过滤器,它将用户名添加到 MDC/NDC。 Logback 提供了方便的MDCInsertingServletFilter,Spring 框架也添加了Log4jNestedDiagnosticContextFilter 到 store。看看它们,但你需要一个像这样的自定义:

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 安全过滤器之后在 web.xml 中应用此过滤器。 MDC 功能真的很灵巧 - 如果需要,它会将保存在 MDC 线程本地映射中的所有值添加到每个日志记录语句。在您的情况下,只需添加以下内容:

%Xuser

到您的日志pattern。

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

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

【讨论】:

Log4J2有这样的例子吗?【参考方案3】:

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

【讨论】:

以上是关于在 Web 应用程序中记录用户活动的主要内容,如果未能解决你的问题,请参考以下文章

在 ios 应用程序中使用活动目录用户验证 Web 服务?

为每个登录用户查找活动应用程序

在 Shiny 应用程序中跟踪用户活动

如何处理jmeter中的记录问题? (即)Smack 插件活动未在 JMeter 中记录

Mysql活动提要设计

Web会话跟踪:Cookie与Session