使用特征名称作为记录器名称

Using a trait name as a logger name

我有以下代码:

import org.slf4j.LoggerFactory
trait Logger {
    lazy val log = LoggerFactory.getLogger(getClass.getName)
}

trait DoSomething1 extends Logger { ... }
trait DoSomething2 extends Logger { ... }
trait DoSomething3 extends Logger { ... }
...
trait DoAll extends DoSomething1 with DoSomething2 with ...

val act = new DoAll {}

在我的日志中我看到:

INFO  Main$$anon: blablabla ...
INFO  Main$$anon: blablabla ...
INFO  Main$$anon: blablabla ...
ERROR Main$$anon: blablabla ...
DEBUG Main$$anon: blablabla ...

我无法理解是哪个特征打印每条消息。 我想看到类似的内容:

INFO  Main$$DoSomething1: blablabla ...
INFO  Main$$DoSomething3: blablabla ...
DEBUG Main$$DoSomething2: blablabla ...

或者 Scala 源名称:

INFO  Main$$DoSomething1.scala: blablabla ...
INFO  Main$$DoSomething3.scala: blablabla ...
DEBUG Main$$DoSomething2.scala: blablabla ...

我可以使用特征名称作为记录器名称吗?

Main$$anon 是您匿名编译的 scala class new DoAll {} 的 "java compatible" 名称。 所有特征都一样,因为 getClass.getName return 相同的值。

如果你想有不同的值,你应该在每个特征中覆盖 logger, 而不是 class name 在构造它时使用一些预定义值。

例如你可以使用下面的代码:

trait Logger {
    val logger = LoggerFactory.getLogger(loggerName)
    def loggerName = getClass.getName
}

trait A {
    def loggerName = "A"
    // ...
}

trait B {
    def loggerName = "B"
    // ...
}

等...

您可以使用的一个简单模式是将 Logger 混合到伴生对象中并将其导入:

object DoSomething1 extends Logger
trait DoSomething1 {
   import DoSomething1._
   ...
}
object DoSomething2 extends Logger
trait DoSomething2 {
   import DoSomething2._
   ...
}
object DoSomething3 extends Logger
trait DoSomething3 {
   import DoSomething3._
   ...
}
trait DoAll extends DoSomething1 with DoSomething2 with ...

val act = new DoAll {}

然后你应该有一些类似的东西:

INFO  DoSomething1$: blablabla ...
INFO  DoSomething3$: blablabla ...
DEBUG  DoSomething2$: blablabla ...