7

我在应用程序中使用 log4j 和 spring-security,记录器应该在每条消息中使用用户名写入日志。我对这一切都很陌生,有人可以提供建议或链接吗?也许有一些标准的方法可以解决这个问题?谢谢你。

编辑使用 spring 框架 3.1 我的 spring-security.xml 是:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http pattern="/favicon.ico" security="none" />
    <http auto-config="true">
            <intercept-url pattern="/**" access="ROLE_ADMIN"/>
    </http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="detect_me" password="1111" authorities="ROLE_ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

和 log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>    
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p [%c] - %m%n" />
        </layout>
    </appender>
    <appender name="R" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="/logs/urlbuilderweb.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p %t %c - %m%n" />            
        </layout>
    </appender>
    <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="10000"/>
        <appender-ref ref="R"/>
    </appender>
    <logger name="org.springframework">
        <level value="WARN"/>
    </logger>
    <logger name="org.directwebremoting">
        <level value="WARN"/>
    </logger>
    <logger name="org.apache.http">
        <level value="WARN"/>
    </logger>
    <logger name="org.hibernate">
        <level value="WARN"/>
    </logger>
    <root>
        <level value="INFO" />
        <appender-ref ref="ASYNC"/>
    </root>
</log4j:configuration>
4

1 回答 1

5

您可以使用NDC 功能。设置一些过滤器/拦截器(取决于您使用的演示技术)。添加嵌套诊断上下文(过滤器示例):

public class LogDiagnosticContextFilter implements javax.servlet.Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // do nothing
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {
        SecurityContext context = SecurityContextHolder.getContext();
        if (context != null) {
            Authentication authentication = context.getAuthentication();
            if (authentication != null) {
                NDC.push("Username=" + authentication.getName());
            }
        }
        chain.doFilter(request, response);
        NDC.pop();
    }
    @Override
    public void destroy() {
        // do nothing
    }
}

确保在 Spring Security 过滤器链 (web.xml) 之后执行过滤器:

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>logDiagnosticContextFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>   

x添加到每个感兴趣的 log4j 模式:

%x %d %p %t %c - %m%n

稍后当你打电话时

LOGGER.info("some text");

您将在代码中的任何位置看到

Username=corresponding_login some text

在你的日志中

于 2012-12-18T09:16:59.563 回答