Проблема при определении черты Logging в scala - PullRequest
2 голосов
/ 26 ноября 2010

Кажется, что общий шаблон ведения логов в scala - это использование черты Logging, смешанной с конкретным классом (см. Проекты с открытым исходным кодом, такие как Liftweb, akka, ...).

Что-то вроде этого:

trait Logging {
  val loggerName = this.getClass.getName
  @transient lazy val log = new Logger(loggerName)
}

Это именно то, что я правильно использую, но я застрял с проблемой из-за этого паттерна.Действительно, если признак Logging смешан производным классом, Logger будет использоваться с именем самого производного класса.

Вот пример, чтобы прояснить себя:

class Logger(logName : String){
  def debug( msg : String ) { println("["+logName+"] : "+msg) }
}

trait Logging {
  val loggerName = this.getClass.getName
  @transient lazy val log = new Logger(loggerName)
}

package a {
  class A extends Logging {
    log.debug("log from A")
  }
}

package b {
  import a._
  class B extends A with Logging {
    log.debug("log from B")
  }
}

object LogTest {
  import b._
  def main(args : Array[String]) = {
    val instance = new B
  }
}

Когда я запускаю эту программу, я получаю:

[b.B] : log from A
[b.B] : log from B

Вместо:

[a.A] : log from A
[b.B] : log from B

Кто-нибудь нашел решение этой проблемы?

Ответы [ 3 ]

2 голосов
/ 27 ноября 2010

По моему опыту, это определенно не то поведение, которое вам нужно .

Если у вас есть некоторая иерархия классов, которая содержит переопределение методов, ваши журналы могут быть полны строк, которые выглядят следующим образом:

13:44:42.654 - AbstractFooService [INFO] : I have a: foo
13:44:42.656 - AbstractFooService [INFO] : I have bar-d my: foo

И вы будете спрашивать себя, с какой конкретной реализацией службы вы имели дело? Если вы не знаете, как вы можете быть уверены, какой путь к коду был выбран, чтобы получить то, где вы находитесь? Может быть, между ними должно было быть третье утверждение:

13:44:42.655 - SpecialFooService [INFO] : I want to baz this foo to bar

Гораздо проще отлаживать, если в журналах содержится

13:44:42.654 - DefaultFooService [INFO] : I have a: foo
13:44:42.656 - DefaultFooService [INFO] : I have bar-d my: foo

Потому что тогда вы можете сразу же сказать , что вы используете неправильный сервис foo

2 голосов
/ 26 ноября 2010

Я мог бы добиться этого эффекта, используя регистраторы в объектах-компаньонах:

object A extends Logging; 
class A { import A._
  log.debug("log from A")
}

object B extends Logging; 
class B extends A  { import B._
  log.debug("log from B")
}
0 голосов
/ 26 ноября 2010

Это может быть очевидно, но если вы не хотите, чтобы черта Logging была унаследована, вы могли бы просто использовать приватную переменную вместо того, чтобы смешивать в ней черту.

class A {
  private val log = Logger(this)
}

class B extends A with Logging {
}

или

class A extends Logging {
}

class B extends A {
  override lazy val log = // ...
}
...