【问题标题】:Dynamically choose implementation of logger in Scala在Scala中动态选择记录器的实现
【发布时间】:2019-05-27 21:02:10
【问题描述】:

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

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

这是我到目前为止所做的,也是我卡住的地方:

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

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

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

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 trait 被初始化并且name 的值仍然是空的。因此,该语句为“空日志语句”

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

【问题讨论】:

    标签: scala design-patterns traits typetraits


    【解决方案1】:

    您只需要将logger 的值设为lazy

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

    现在logger 在第一次使用之前不会被创建,届时name 的值将是有效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-08
      • 2018-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      • 2011-11-18
      • 1970-01-01
      相关资源
      最近更新 更多