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

时间:2019-05-27 21:02:11

标签: scala design-patterns traits typetraits

我有一个使用log4j记录内容的库。对于我的库中的某些特定类(所有扩展Component的类),我希望log语句在开头包含后缀[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的值仍为空。因此,该语句为“空日志语句”

此解决方案在我看来是最优雅的解决方案,但请更好地提出不同的建议

1 个答案:

答案 0 :(得分:3)

您只需要将logger的值设为lazy

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

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

相关问题