在Java中 - 我可以设置日志级别pr线程吗?

时间:2014-11-07 08:42:37

标签: java logging java.util.logging

我总是想知道是否可以在pr线程级别上以编程方式设置java.util.logging的日志级别。

用例是在Web服务器中。如果我的代码检测到某个用户的错误级别异常,我想为该客户启用跟踪日志记录。

我正在考虑使用servletfilter执行此操作,并将其绑定到其会话ID。但据我所知,我可以在appender上设置的日志级别不是线程仿射。即如果我将根级别设置为FINE,它将影响系统中的所有线程,并且日志将填满其他200个同步用户流量。当然,我之后可以过滤日志,但无论如何都会出现性能损失。

有没有人有这方面的经验?

2 个答案:

答案 0 :(得分:1)

  

我总是想知道是否可以在pr线程级别上以编程方式设置java.util.logging的日志级别。

创建log filter以捕获用户上下文并将过滤对象的级别设置为ALL:

   public class UserFilter implements Filter {

    private final Level lvl;
    private final Object userContext;

    public UserFilter(Level originalLevel, Object userContext) {
        this.lvl = originalLevel;
        this.userContext = userContext;
    }

    @Override
    public boolean isLoggable(LogRecord record) {
        if (!belongsTo(record, userContext)) {
            int levelValue = this.lvl.intValue();
            if (record.getLevel().intValue() < levelValue
                    || levelValue == Level.OFF.intValue()) {
                return false;
            }
        }
        return true;
    }


    private boolean belongsTo(LogRecord record) {
        /**
         * Insert logic here.
         */
        //return ((Integer) this.userContext) == record.getThreadId();
        return true;
    }
}

对于您的用例,您应该能够创建一个servlet过滤器:

  1. 创建一个日志过滤器,用于标识用户并捕获当前日志级别。
  2. 安装日志过滤器,然后将级别更改为FINE。

答案 1 :(得分:0)

好吧,你应该总是能够直接调用log(level, message);并通过使用一些线程本地映射来获得实际级别。

您也可以编写一些包装器来处理这个问题,例如:

public void debugExceptCritical(Logger l, String message) {
  //critical would be your per-thread flag, 
  //just make sure to reset it when it is no longer used, e.g. in a servlet filter
  l.log( critical  ? ERROR : DEBUG, message ); 
}

或者你可以尝试获取调用它的类(我在某个地方做了但不记得细节,所以我必须查找它)并使用此信息来获取方法内的记录器。

查询来电者:

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for( StackTraceElement elem : stackTrace ) {
  //look for the debugExceptCritical method or maybe just the class it contains
  //if found take the class name of the next element to look up the correct logger  
}

另一种方法是,根据您实际使用的日志框架,可能会挂钩一些每线程过滤器/ appender /其中的任何内容。在Log4J中,我要么尝试添加自己的appender,然后检查critical标志并更改日志事件的级别,或者始终记录关键操作,并使用每线程过滤器,当{{1}时拒绝这些日志事件没有设置标志。