在 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"
这个解决方案在我看来是最优雅的,但如果更好,请向我推荐不同的解决方案
你只需要让 logger
值 lazy
:
trait WithEnrichedLogger {
this: Component =>
lazy val logger = new EnrichedLogger(this.name)
}
现在 logger
在首次使用之前不会创建,届时 name
值将有效。
我有一个库,我在其中使用 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"
这个解决方案在我看来是最优雅的,但如果更好,请向我推荐不同的解决方案
你只需要让 logger
值 lazy
:
trait WithEnrichedLogger {
this: Component =>
lazy val logger = new EnrichedLogger(this.name)
}
现在 logger
在首次使用之前不会创建,届时 name
值将有效。