英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论