include actor system’s address in akkaSource log property, see #1621

This commit is contained in:
Roland 2012-01-12 11:35:48 +01:00
parent d0498eb32e
commit 255a8c74e9
7 changed files with 91 additions and 68 deletions

View file

@ -218,18 +218,19 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im
}
})
val name = fsm.path.toString
val fsmClass = fsm.underlyingActor.getClass
system.eventStream.subscribe(testActor, classOf[Logging.Debug])
fsm ! "go"
expectMsgPF(1 second, hint = "processing Event(go,null)") {
case Logging.Debug(`name`, _, s: String) if s.startsWith("processing Event(go,null) from Actor[") true
case Logging.Debug(`name`, `fsmClass`, s: String) if s.startsWith("processing Event(go,null) from Actor[") true
}
expectMsg(1 second, Logging.Debug(name, fsm.underlyingActor.getClass, "setting timer 't'/1500 milliseconds: Shutdown"))
expectMsg(1 second, Logging.Debug(name, fsm.underlyingActor.getClass, "transition 1 -> 2"))
expectMsg(1 second, Logging.Debug(name, fsmClass, "setting timer 't'/1500 milliseconds: Shutdown"))
expectMsg(1 second, Logging.Debug(name, fsmClass, "transition 1 -> 2"))
fsm ! "stop"
expectMsgPF(1 second, hint = "processing Event(stop,null)") {
case Logging.Debug(`name`, _, s: String) if s.startsWith("processing Event(stop,null) from Actor[") true
case Logging.Debug(`name`, `fsmClass`, s: String) if s.startsWith("processing Event(stop,null) from Actor[") true
}
expectMsgAllOf(1 second, Logging.Debug(name, fsm.underlyingActor.getClass, "canceling timer 't'"), Normal)
expectMsgAllOf(1 second, Logging.Debug(name, fsmClass, "canceling timer 't'"), Normal)
expectNoMsg(1 second)
system.eventStream.unsubscribe(testActor)
}

View file

@ -112,7 +112,7 @@ object Status {
}
trait ActorLogging { this: Actor
val log = akka.event.Logging(context.system.eventStream, context.self)
val log = akka.event.Logging(context.system, context.self)
}
object Actor {

View file

@ -296,7 +296,7 @@ class LocalActorRefProvider(
val nodename: String = "local"
val clustername: String = "local"
val log = Logging(eventStream, "LocalActorRefProvider")
val log = Logging(eventStream, "LocalActorRefProvider(" + rootPath.address + ")")
/*
* generate name for temporary actor refs

View file

@ -330,7 +330,11 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
// this provides basic logging (to stdout) until .start() is called below
val eventStream = new EventStream(DebugEventStream)
eventStream.startStdoutLogger(settings)
val log = new BusLogging(eventStream, "ActorSystem", this.getClass)
// unfortunately we need logging before we know the rootpath address, which wants to be inserted here
@volatile
private var _log = new BusLogging(eventStream, "ActorSystem(" + name + ")", this.getClass)
def log = _log
val scheduler = createScheduler()
@ -383,6 +387,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
private lazy val _start: this.type = {
// the provider is expected to start default loggers, LocalActorRefProvider does this
provider.init(this)
_log = new BusLogging(eventStream, "ActorSystem(" + lookupRoot.path.address + ")", this.getClass)
deadLetters.init(dispatcher, lookupRoot.path / "deadLetters")
// this starts the reaper actor and the user-configured logging subscribers, which are also actors
registerOnTermination(stopScheduler())
@ -498,4 +503,6 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor
}
}
override def toString = lookupRoot.path.root.address.toString
}

View file

@ -190,7 +190,7 @@ trait FSM[S, D] extends Listeners {
type Timeout = Option[Duration]
type TransitionHandler = PartialFunction[(S, S), Unit]
val log = Logging(context.system, context.self)
val log = Logging(context.system, this)
/**
* ****************************************

View file

@ -86,8 +86,9 @@ trait LoggingBus extends ActorEventBus {
* Internal Akka use only
*/
private[akka] def startDefaultLoggers(system: ActorSystemImpl) {
val logName = simpleName(this) + "(" + system + ")"
val level = levelFor(system.settings.LogLevel) getOrElse {
StandardOutLogger.print(Error(new EventHandlerException, simpleName(this), this.getClass, "unknown akka.stdout-loglevel " + system.settings.LogLevel))
StandardOutLogger.print(Error(new EventHandlerException, logName, this.getClass, "unknown akka.stdout-loglevel " + system.settings.LogLevel))
ErrorLevel
}
try {
@ -101,7 +102,7 @@ trait LoggingBus extends ActorEventBus {
} yield {
try {
ReflectiveAccess.getClassFor[Actor](loggerName) match {
case Right(actorClass) addLogger(system, actorClass, level)
case Right(actorClass) addLogger(system, actorClass, level, logName)
case Left(exception) throw exception
}
} catch {
@ -115,7 +116,7 @@ trait LoggingBus extends ActorEventBus {
loggers = myloggers
_logLevel = level
}
publish(Debug(simpleName(this), this.getClass, "Default Loggers started"))
publish(Debug(logName, this.getClass, "Default Loggers started"))
if (!(defaultLoggers contains StandardOutLoggerName)) {
unsubscribe(StandardOutLogger)
}
@ -150,18 +151,18 @@ trait LoggingBus extends ActorEventBus {
publish(Debug(simpleName(this), this.getClass, "all default loggers stopped"))
}
private def addLogger(system: ActorSystemImpl, clazz: Class[_ <: Actor], level: LogLevel): ActorRef = {
private def addLogger(system: ActorSystemImpl, clazz: Class[_ <: Actor], level: LogLevel, logName: String): ActorRef = {
val name = "log" + Extension(system).id() + "-" + simpleName(clazz)
val actor = system.systemActorOf(Props(clazz), name)
implicit val timeout = Timeout(3 seconds)
val response = try Await.result(actor ? InitializeLogger(this), timeout.duration) catch {
case _: TimeoutException
publish(Warning(simpleName(this), this.getClass, "Logger " + name + " did not respond within " + timeout + " to InitializeLogger(bus)"))
publish(Warning(logName, this.getClass, "Logger " + name + " did not respond within " + timeout + " to InitializeLogger(bus)"))
}
if (response != LoggerInitialized)
throw new LoggerInitializationException("Logger " + name + " did not respond with LoggerInitialized, sent instead " + response)
AllLogLevels filter (level >= _) foreach (l subscribe(actor, classFor(l)))
publish(Debug(simpleName(this), this.getClass, "logger " + name + " started"))
publish(Debug(logName, this.getClass, "logger " + name + " started"))
actor
}
@ -169,11 +170,13 @@ trait LoggingBus extends ActorEventBus {
trait LogSource[-T] {
def genString(t: T): String
def genString(t: T, system: ActorSystem): String = genString(t)
}
object LogSource {
implicit val fromString: LogSource[String] = new LogSource[String] {
def genString(s: String) = s
override def genString(s: String, system: ActorSystem) = s + "(" + system + ")"
}
implicit val fromActor: LogSource[Actor] = new LogSource[Actor] {
@ -187,10 +190,13 @@ object LogSource {
// this one unfortunately does not work as implicit, because existential types have some weird behavior
val fromClass: LogSource[Class[_]] = new LogSource[Class[_]] {
def genString(c: Class[_]) = simpleName(c)
override def genString(c: Class[_], system: ActorSystem) = simpleName(c) + "(" + system + ")"
}
implicit def fromAnyClass[T]: LogSource[Class[T]] = fromClass.asInstanceOf[LogSource[Class[T]]]
def apply[T: LogSource](o: T) = implicitly[LogSource[T]].genString(o)
def apply[T: LogSource](o: T): String = implicitly[LogSource[T]].genString(o)
def apply[T: LogSource](o: T, system: ActorSystem): String = implicitly[LogSource[T]].genString(o, system)
def fromAnyRef(o: AnyRef): String =
o match {
@ -200,6 +206,15 @@ object LogSource {
case s: String s
case x simpleName(x)
}
def fromAnyRef(o: AnyRef, system: ActorSystem): String =
o match {
case c: Class[_] fromClass.genString(c, system)
case a: Actor fromActor.genString(a, system)
case a: ActorRef fromActorRef.genString(a, system)
case s: String fromString.genString(s, system)
case x simpleName(x) + "(" + system + ")"
}
}
/**
@ -305,6 +320,41 @@ object Logging {
val infoFormat = "[INFO] [%s] [%s] [%s] %s".intern
val debugFormat = "[DEBUG] [%s] [%s] [%s] %s".intern
/**
* Obtain LoggingAdapter for the given actor system and source object. This
* will use the systems event stream.
*
* The source is used to identify the source of this logging channel and must have
* a corresponding implicit LogSource[T] instance in scope; by default these are
* provided for Class[_], Actor, ActorRef and String types. By these, the source
* object is translated to a String according to the following rules:
* <ul>
* <li>if it is an Actor or ActorRef, its path is used</li>
* <li>in case of a String it is used as is</li>
* <li>in case of a class an approximation of its simpleName
* <li>and in all other cases the simpleName of its class</li>
* </ul>
*
* You can add your own rules quite easily:
*
* {{{
* trait MyType { // as an example
* def name: String
* }
*
* implicit val myLogSourceType: LogSource[MyType] = new LogSource {
* def genString(a: MyType) = a.name
* }
*
* class MyClass extends MyType {
* val log = Logging(eventStream, this) // will use "hallo" as logSource
* def name = "hallo"
* }
* }}}
*/
def apply[T: LogSource](system: ActorSystem, logSource: T): LoggingAdapter =
new BusLogging(system.eventStream, LogSource(logSource, system), logSource.getClass)
/**
* Obtain LoggingAdapter for the given logging bus and source object.
*
@ -371,42 +421,7 @@ object Logging {
* }
* }}}
*/
def apply[T: LogSource](system: ActorSystem, logSource: T): LoggingAdapter =
new BusLogging(system.eventStream, implicitly[LogSource[T]].genString(logSource), logSource.getClass)
/**
* Obtain LoggingAdapter for the given actor system and source object. This
* will use the systems event stream.
*
* The source is used to identify the source of this logging channel and must have
* a corresponding implicit LogSource[T] instance in scope; by default these are
* provided for Class[_], Actor, ActorRef and String types. By these, the source
* object is translated to a String according to the following rules:
* <ul>
* <li>if it is an Actor or ActorRef, its path is used</li>
* <li>in case of a String it is used as is</li>
* <li>in case of a class an approximation of its simpleName
* <li>and in all other cases the simpleName of its class</li>
* </ul>
*
* You can add your own rules quite easily:
*
* {{{
* trait MyType { // as an example
* def name: String
* }
*
* implicit val myLogSourceType: LogSource[MyType] = new LogSource {
* def genString(a: MyType) = a.name
* }
*
* class MyClass extends MyType {
* val log = Logging(eventStream, this) // will use "hallo" as logSource
* def name = "hallo"
* }
* }}}
*/
def getLogger(system: ActorSystem, logSource: AnyRef): LoggingAdapter = apply(system, LogSource.fromAnyRef(logSource))
def getLogger(system: ActorSystem, logSource: AnyRef): LoggingAdapter = apply(system, LogSource.fromAnyRef(logSource, system))
/**
* Obtain LoggingAdapter for the given logging bus and source object. This
@ -440,7 +455,7 @@ object Logging {
* }
* }}}
*/
def getLogger(bus: LoggingBus, logSource: AnyRef): LoggingAdapter = apply(bus, LogSource.fromAnyRef(logSource))
//def getLogger(bus: LoggingBus, logSource: AnyRef): LoggingAdapter = apply(bus, LogSource.fromAnyRef(logSource))
/**
* Artificial exception injected into Error events if no Throwable is

View file

@ -27,8 +27,6 @@ class RemoteActorRefProvider(
val scheduler: Scheduler,
_deadLetters: InternalActorRef) extends ActorRefProvider {
val log = Logging(eventStream, "RemoteActorRefProvider")
val remoteSettings = new RemoteSettings(settings.config, systemName)
def rootGuardian = local.rootGuardian
@ -44,6 +42,8 @@ class RemoteActorRefProvider(
val remote = new Remote(settings, remoteSettings)
implicit val transports = remote.transports
val log = Logging(eventStream, "RemoteActorRefProvider(" + remote.remoteAddress + ")")
val rootPath: ActorPath = RootActorPath(remote.remoteAddress)
private val local = new LocalActorRefProvider(systemName, settings, eventStream, scheduler, _deadLetters, rootPath, deployer)