我有一个使用log4j2的Singleton Logger,它将从各种类中调用。 输出格式为 - 日期INFO com.so.pg1 abc
说我有4个类(第1页,第2页,第3页,第4页)。我目前正在使用pg4类,它在内部声明了pg1,pg2,pg3。 所有这些都有一个私人记录器字段。
private static SingletonLog logger = SingletonLog.getInstance(pg4.class.getName());
他们所有的方法都包含 log.info(),我将日志记录级别设置为 INFO 。 我需要一种方法来确保每次pg1调用log.info(" abc"), 输出应该看起来像日期INFO com.so.pg1 abc 。 并且pg2调用log.info(" xyz")输出应该看起来像 date INFO com.so.pg2 xyz 。 但是现在所有的日志都有相同的类名com.so.pg3,如下所示。
各种记录器引用应该由SingletonLog类实现处理,并且对于调用类应该是无缝的。
请帮我纠正这个问题。
示例代码:
public class pg4 {
private static SingletonLog logger = SingletonLog.getInstance(pg4.class.getName());
pg1 two = new pg1();
pg2 two = new pg2();
pg3 two = new pg3();
public void methodA() {
logger.setLevel(INFO);
logger.info("efg");
pg1.methodB(); //This too has SingletonLog field with p1.class.getName() as input.
pg2.methodC(); // same as above
pg3.methodD(); // same as above
}
}
public class SingletonLog {
private static Logger internalLog = null;
private static SingletonLog uniqueInstance = null;
public getInstance(String className) {
if (uniqueInstance == null)
uniqueInstance = new unique();
internalLog = LogManager.getLogger(className);
return uniqueInstance;
}
}
Expected Output for this code:
<date> INFO com.so.pg4 efg
<date> INFO com.so.pg1 abc
<date> INFO com.so.pg2 xyz
<date> INFO com.so.pg3 mno
Actual Output:
<date> INFO com.so.pg3 efg
<date> INFO com.so.pg3 abc
<date> INFO com.so.pg3 xyz
<date> INFO com.so.pg3 mno
答案 0 :(得分:0)
Singleton会阻止您获得所需的输出。
第一次调用Singleton.getInstance(“a.b.c”)时,会使用FQCN(完全限定类名)“a.b.c”创建记录器。此记录器被缓存,下次调用Singleton.getInstance(“x.y.z”)时,它将返回缓存的相同(a.b.c)实例。一旦创建并缓存了记录器,getInstance()方法将忽略指定的FQCN。
解决方案是不使用单身人士。
Log4j已在内部缓存Loggers。如果您从某个地方拨打LogManager.getLogger("a.b.c")
,然后再从另一个地方拨打LogManager.getLogger("a.b.c")
,您将获得相同的 Logger实例。但是,如果您从另一个地方拨打LogManager.getLogger("x.y.z")
,则会获得不同的 Logger实例。这是正常用法,我相信这可以满足您的需求。它将导致您在“预期输出”下显示的输出。