using Logger.getGlobal() with tomcat9 and org.apache.logging.log4j.jul.LogManager – log4j config is ignored

huangapple go评论53阅读模式
英文:

using Logger.getGlobal() with tomcat9 and org.apache.logging.log4j.jul.LogManager - log4j config is ignored

问题

我们有一个使用 jul 进行日志记录的传统应用程序的 tomcat9 正在运行。为了能够更轻松地控制日志格式并具有 MDC 和其他一些功能,我们使用 org.apache.logging.log4j.jul.LogManager 和一个类似以下方式的 log4j 配置文件:

-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
-Dlog4j.configurationFile="\path\to\file\log4j2.xml"

这对于通过 Logger log = Logger.getLogger(LoggingTest.class.getName()); 获取的所有记录器都非常有效。

但是在传统代码中,还使用了 GlobalLogger 和匿名记录器,例如以下方式(简化但重现了问题):

Logger.getGlobal().log(Level.INFO, "使用全局记录器的条目");
Logger.getAnonymousLogger().log(Level.INFO, "使用匿名记录器的条目");

这些记录器不是通过 log4j 记录的,而是直接使用 Java Util 记录,完全忽略了 LogManager。在这些情况下返回的记录器不是 org.apache.logging.log4j.jul.CoreLogger 的实例,而是 java.util.logging.Logger,尽管它的管理器仍然是 org.apache.logging.log4j.jul.LogManager。

这是否是已知的限制和/或是否有解决方法呢?

英文:

We have a tomcat9 with a legacy application using jul for logging running. To be able to steer the log format easier and have MDC and some other features we use org.apache.logging.log4j.jul.LogManager and a log4j config file like so:

-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
-Dlog4j.configurationFile="\path\to\file\log4j2.xml

this works very well for all loggers which are fetched via
Logger log = Logger.getLogger(LoggingTest.class.getName());

but in the legacy code there is also the GlobalLogger as well as Anonymous Loggers used e.g. like this (simplified but reproduces the problem):

Logger.getGlobal().log(Level.INFO, "bar with global");
Logger.getAnonymousLogger().log(Level.INFO, "bar with anonymous");

these are not logging via log4j but directly with Java Util ignoring the LogManager completely. The logger returned in these cases is not an instance of org.apache.logging.log4j.jul.CoreLogger but java.util.logging.Logger, although it's manager is still org.apache.logging.log4j.jul.LogManager.

Is this a known limitation and/or is there a workaround for that?

答案1

得分: 1

查看源代码,看起来 Logger.getAnonymousLogger() 直接调用 new Logger(),而不是通过 LogManager。这使得 Log4j 的替代 LogManager 无法正确支持此操作,因为 Log4j 期望其 LogManager 替代类来创建 Loggers。

GlobalLogger 在初始化过程中似乎也是通过调用 new Logger() 进行设置。然而,在您上面的代码中,显示您正在针对全局记录器调用 getLogger(),这有点有趣,因为 getLogger() 是一个静态方法,应该与 Logger.getLogger() 的行为相同,后者最终调用 LogManager 来获取一个 Logger。所以在这种情况下,我不确定为什么您不会得到一个 Log4j CoreLogger。

英文:

Looking at the source code it looks like Logger.getAnonymoustLogger() does a new Logger() directly instead of going through the LogManager. This makes it impossible for Log4j's replacement LogManager to properly support this as Log4j is expecting its LogManager replacement to be creating Loggers.

The GlobalLogger appears to also be setup with a new Logger() call during initialization. However, in your code above you show that you are calling getLogger() against the Global Logger which is a bit interesting since getLogger() is a static method and should behave just like Logger.getLogger() which ends up calling the LogManager to get a Logger, so in this case I am not sure why you would not also be getting a Log4j CoreLogger.

huangapple
  • 本文由 发表于 2020年9月8日 23:36:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63797200.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定