You want to look at Nested Diagnostic Contexts or Mapped Diagnostic Contexts in log4j or slf4j. An NDC/MDC allows you to insert data into your session that can be filtered by log4j.
So you would define the user name to be in the NDC and then you can change the log4j.properties to change the logging level for specific users.
An MDC uses a Map, whereas an NDC is based upon a stack principle. If you're using slf4j, you can even create separate log files depending upon the information in your MDC.
For instance, we did this when users logged into a website. We wanted to trace what a particular user was doing (retrospectively), so we added the user name and session id to the NDC, and then we could post filter on those.
The code was similar to the following:
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
MDC.put("username", session.getParameter("username")); // or where ever t is stored
chain.doFilter(request, response);
}
}
In your log4j.xml, this filters based upon the user:
<appender name="UserDebug" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="userdebug.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="5000KB"/>
<param name="maxBackupIndex" value="5"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] user:%X{username} %-5p - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="user:fred" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
%X{key} outputs the value of MDC.get(key) in an MDC. If you wanted a more complex filter, you can extend it yourself, and look at the values in the MDC yourself.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…