在 Scala 中动态选择记录器的实现

Dynamically choose implementation of logger in Scala

我有一个库,我在其中使用 log4j 来记录内容。对于我的库的某些特定 类(所有 类 扩展 Component),我希望日志语句在开头包含后缀 [component_name]

我不想改变日志语句通常的样子。因此,在这些名为 'foo' 的特殊组件之一中,语句 log.info("message") 应该在日志系统中输出 [foo] message

这是我到目前为止所做的以及我被卡住的地方:

object Logging {
   val logger = Logger.getLogger("my_logger_name")
}

这是基本的记录器,我在整个代码中使用 Logging.logger.info("message")

调用它

我认为最好的办法是使用特征构建丰富的记录器

trait WithEnrichedLogger {
   this: Component =>
   val logger = new EnrichedLogger(this.name)
}

class EnrichedLogger(name: String) {
   def info(msg: String): Unit = Logging.logger.info(s"[${name}] $msg")
}

我的组件看起来像

abstract class Component with WithEnrichedLogger {
     def name: String
     ....

     def some_method: Unit = { 
        logger.info("log statement") \ it should print the '[name]' at the beginning 
     }
 } 

此设置中的问题是,在创建 Component 时,WithEnrichedLogger 特征被初始化,而 name 的值仍然为空。为此,声明为"null log statement"

这个解决方案在我看来是最优雅的,但如果更好,请向我推荐不同的解决方案

你只需要让 loggerlazy:

trait WithEnrichedLogger {
  this: Component =>
  lazy val logger = new EnrichedLogger(this.name)
}

现在 logger 在首次使用之前不会创建,届时 name 值将有效。