如何正确初始化记录器?

时间:2016-02-01 12:23:15

标签: java logging java.util.logging

我有以下问题:我想使用java.util.logging.Logger。不,我找到了不同的资源123,如何修改记录器的行为。

特别是在2 a的问题中(在我看来),根据类名初始化记录器的结构很好。这还允许在基于包的级别上修改详细程度,以便在需要时进行调试。

经过一番深入研究后发现,全局记录器和“空”记录器(名称为"")不一样。另请参见下面的示例。 我刚刚创建了一个记录器foo.Bar,它锚定在空记录器而不是名为foo的记录器上。 只有在我首次创建记录器bar时,记录器bar.Baz才能正确锚定。

这使得this question中的方法主要无用,因为我们不能假设之前要创建父记录器。根据需要,我必须解析类名并创建记录器。

我是否正确,我必须添加一些static {...}代码,以便在初始化自己的记录器之前以递归方式初始化记录器? 如果多个类为包记录器调用Logger.getLogger(String)方法(导致总体上多次调用,例如bar.Bazbar.FooBaz获取记录器bar),这是否会产生任何负面影响?

import java.util.Enumeration;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class TestLogger
{
    public static void main(String[] args)
    {
        // Create the logger directly
        Logger.getLogger("foo.Bar");
        // Create the logger objects step-by-step
        Logger.getLogger("bar");
        Logger.getLogger("bar.Baz");
        // Put the available loggers to output
        Enumeration<String> e = LogManager.getLogManager().getLoggerNames();
        while(e.hasMoreElements())
        {
            String s = e.nextElement();
            Logger l = Logger.getLogger(s);
            String p = (l.getParent() == null ? "none" : "'" + l.getParent().getName() + "'");
            System.out.println("'" + s + "': " + p);
        }
    }
}

程序的输出是

'bar': ''
'global': ''
'foo.bar': ''
'bar.baz': 'bar'
'': none

1 个答案:

答案 0 :(得分:1)

在每个班级中使用Logger.getLogger(String)的一个负面影响是,您无法模拟它(或通过特殊记录器)进行测试。

示例:假设您需要测试以下C类:

package a.b;
class C {
  private Logger logger;
  private int capacity;
  private int size;
  C(int capacity) {
    this.logger = Logger.getLogger("a.b.C");
    this.capacity = capacity;
    size = 0;
  }
  void add(int item) {
    if (size >= capacity) {
      logger.log("You already reached the capacity: " + capacity);
    }
    //...
  }
}

如果达到容量,则需要添加日志。现在你需要测试它。做一个测试的测试非常困难和黑客:

public void testCapacityReachedLogs() {
    C c = new C(2);
    c.add(1);
    c.add(2);
    // verify that c logged the exact string: "You already reached the capacity: 2"
}

但是如果你有:

package a.b;
class D {
  private Logger logger;
  private int capacity;
  private int size;
  D(Logger logger, int capacity) {
    this.logger = logger;
    this.capacity = capacity;
    size = 0;
  }
  void add(int item) {
    if (size >= capacity) {
      logger.log("You already reached the capacity: " + capacity);
    }
    //...
  }
}

现在你可以模拟Logger:

public void testCapacityReachedLogs() {
    Logger logger = getMock(Logger.class);
    D d = new D(logger, 2);
    d.add(1);
    d.add(2);
    verify(logger).log("You already reached the capacity: 2");
}

注意&#34; mock&#34;相关代码并不一定遵循框架的语法,仅举例来说。