Frage

Es scheint, dass gemeinsame Protokollierung Muster in scala ist ein Logging Merkmal zu verwenden, die mit konkreter Klasse (vgl Open-Source-Projekten wie Liftweb, akka, ...) gemischt wird.

So etwas:

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

Das ist genau das, was ich richtige Know bin, aber ich bin mit einem Problem nicht, weil dieses Musters. In der Tat, wenn die Protokollierung Merkmal von einer Klasse gemischt wird, das abgeleitet wird, wird der Logger mit dem Namen der meisten abgeleiteten Klasse verwendet werden.

Hier ist ein Beispiel, mich zu klären:

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
  }
}

Wenn ich laufe dieses Programm, das ich habe:

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

Statt:

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

Hat jemand eine Lösung für dieses Problem gefunden?

War es hilfreich?

Lösung

Ich konnte diesen Effekt erzielen Loggern in Begleiter Objekten mit:

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")
}

Andere Tipps

Es ist meine Erfahrung, dass dies definitiv nicht das Verhalten, dass Sie wollen.

Wenn Sie eine Klassenhierarchie haben, die Methode überschrieben enthält, Ihre Protokolle könnten voller Linien sein, die wie folgt aussehen:

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

Und Sie werden sich fragen, was Beton Service-Implementierung wurden Sie den Umgang mit? Wenn Sie nicht wissen, wie können Sie sicher sein, welche Codepfad gemacht zu bekommen, wo Sie sind? Vielleicht sollte es eine dritte Aussage eingebettet zwischen die beiden haben:

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

Viel einfacher zu debuggen, wenn die Protokolle enthalten

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

Da kann man dann sagen, sofort , dass Sie den falschen foo-Dienst verwenden

Dies mag offensichtlich sein, aber wenn Sie nicht möchten, dass der Logging vererbt werden, können Sie einfach eine private Variable verwenden, anstatt in einem Zuge zu mischen.

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

class B extends A with Logging {
}

oder

class A extends Logging {
}

class B extends A {
  override lazy val log = // ...
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top