我有以下问题:我想使用java.util.logging.Logger
。不,我找到了不同的资源1,2,3,如何修改记录器的行为。
特别是在2 a的问题中(在我看来),根据类名初始化记录器的结构很好。这还允许在基于包的级别上修改详细程度,以便在需要时进行调试。
经过一番深入研究后发现,全局记录器和“空”记录器(名称为""
)不一样。另请参见下面的示例。
我刚刚创建了一个记录器foo.Bar
,它锚定在空记录器而不是名为foo
的记录器上。
只有在我首次创建记录器bar
时,记录器bar.Baz
才能正确锚定。
这使得this question中的方法主要无用,因为我们不能假设之前要创建父记录器。根据需要,我必须解析类名并创建记录器。
我是否正确,我必须添加一些static {...}
代码,以便在初始化自己的记录器之前以递归方式初始化记录器?
如果多个类为包记录器调用Logger.getLogger(String)
方法(导致总体上多次调用,例如bar.Baz
和bar.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
答案 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;相关代码并不一定遵循框架的语法,仅举例来说。