使用log4j进行条件记录 [英] Conditional logging with log4j

查看:126
本文介绍了使用log4j进行条件记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶尔使用的Web应用程序会为某些用户开发数据完整性问题。我想开启跟踪级别日志记录,但由于我们每秒处理100个请求跟踪日志记录,因此每个请求都是不可能的。

The web application on which I am working occasionally develops data integrity issues for some of the users. I'd like to turn on trace level logging, but since we are dealing with 100s of requests per second trace logging every single request is out of the question.

是否存在log4j能够有条件地记录的方法吗?换句话说,我希望只有在特定用户发出请求时才能获取跟踪日志。由于我事先不知道哪些用户会受到影响,我不能简单地暂时硬编码用户名。

Is there a way with log4j to be able to log conditionally? In other words, I would like to be able to get trace logs only when specific users make a request. Since I don't know beforehand which users will be affected, I cannot simply temporarily hard-code usernames.

编辑:

我想我需要更清楚一些。我可以轻松地为日志语句添加条件。例如

I think I need to be a little clearer. I can easily add conditions to my log statements. For example

Logger logger = Logger.getLogger("foo");
String usernameFilter = "piglet";
String username = request.getParameter("username");
logger.setLevel(usernameFilter.equals(username) ? Level.TRACE : Level.INFO);
if (logger.isTraceEnabled()) {
   logger.trace("blah blah blah");
}

难度在于动态改变设置日志级别的条件。换句话说,在上面的示例中,我如何设置usernameFilter的值,而不是硬编码。

The difficulty is dynamically altering the condition that sets the log level. In other words, in the example above, how can I set the value of usernameFilter, other than hard-coding it.

推荐答案

您想查看嵌套诊断上下文或log4j中的映射的诊断上下文或者是slf4j。 NDC / MDC允许您将数据插入到可以通过log4j过滤的会话中。

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.

因此,您要将用户名定义为NDC,然后您可以更改log4j.properties以更改特定用户的日志记录级别。

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.

MDC使用Map,而NDC基于堆栈原则。如果您使用的是 slf4j ,您甚至可以创建单独的日志文件,具体取决于您的MDC。

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.

例如,我们在用户登录网站时执行此操作。我们想跟踪特定用户正在做什么(追溯),所以我们将用户名和会话ID添加到NDC,然后我们可以对这些用户进行过滤。

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.

代码类似于以下内容:

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);
    }
}

在你的log4j.xml中,这个过滤器基于user:

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}在MDC中输出MDC.get(key)的值。如果你想要一个更复杂的过滤器,你可以自己扩展它,并自己查看MDC中的值。

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

这篇关于使用log4j进行条件记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆