gpt4 book ai didi

scala - SLF4J 初始化 - 替代记录器

转载 作者:行者123 更新时间:2023-12-04 04:41:27 25 4
gpt4 key购买 nike

我在 Scala 中做一个项目,我正在使用 slf4j 和 Logback 进行日志记录。现在,日志初始化似乎不是线程安全的。作为一种解决方案,slf4j 正在创建替代记录器,即 NoOp 记录器,它吞下初始化期间生成的日志语句。 The slf4j homepage就此事指出:

Substitute loggers were created during the default configuration phase of the underlying logging system

Highly configurable logging systems such as logback and log4j may create components which invoke loggers during their own initialization. See issue LOGBACK-127 for a typical occurrence. However, since the binding process with SLF4J has not yet completed (because the underlying logging system was not yet completely loaded into memory), it is not possible to honor such logger creation requests.

To avoid this chicken-and-egg problem, SLF4J creates substitute loggers during this phase (initialization). Calls made to the substitute loggers during this phase are simply dropped. After the initialization completes, the substitute logger will delegate logging calls to the appropriate logger implementation and otherwise will function as any other logger returned by LoggerFactory.

If any substitute logger had to be created, SLF4J will emit a a listing of such loggers. This list is intended to let you know that any logging calls made to these loggers during initialization have been dropped.



还有一个 Unresolved issue描述问题。

对我来说,问题发生在我测试应用程序的各个部分如何协同工作时。在自己的线程中运行的生产者的日志语句丢失,因为它们被发送到替代记录器。在创建生产者线程之前添加一条日志语句似乎有助于及时初始化记录器。但是,我想知道对 LoggerFactory.getLogger 作为应用程序中的第一条语句的任意调用是否保证我永远不会登录到替代记录器。

简而言之,我的问题是:
  • LoggerFactory.getLogger(classOf[A]) 是否实例化所有记录器,或者可能是两个之后,对 LoggerFactory.getLogger(classOf[B]) 的并发调用将产生一个替代记录器?
  • 有没有办法获得保证,即检查记录器是否已初始化(我无法检查记录器的类型,因为它被 slf4j 门面隐藏)编辑 : 实际上,我只是想我也许可以检查记录器的类型。以下想法能否带来有用的解决方案?:
    def logger(context: Class[_]) = {
    log = LoggerFactory.getLogger(context)
    if (log.isInstanceOf[SubstituteLogger]) logger(context) else log

    我看到这种方法的问题是它依赖于一个特定于实现的类,即 NOPLogger SubstituteLogger。

  • 附录 :
    我不确定这是否与这个问题相关,但我将 slf4j 记录器包装在为每个日志记录上下文实例化的类中(上下文 = 调用记录器的类)。此外,还有一个创建此包装器实例的对象,该对象作为隐式构造函数参数传递给每个想要进行日志记录的类。我将记录器作为参数传递,而不是记录到静态对象(或混合特征)以在单元测试中传递特殊的记录器。

    最佳答案

    我遇到了同样的问题,因为多个依赖项带来了它们自己的 NoOp Logger 副本。就我而言,解决方案是明确地继承 slf4j-log4j12通过:

    libraryDependencies = Seq(
    ...
    ).map(_.exclude("org.slf4j", "slf4j-log4j12" ))

    关于scala - SLF4J 初始化 - 替代记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25844441/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com