Merge pull request #29028 from akka/actor-ref-provider-logging

LocalActorRefProvider: added dedicated logger for deserialization failures
This commit is contained in:
Renato Cavalcanti 2020-05-29 10:26:58 +02:00 committed by GitHub
commit 0969e9d5a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 5 deletions

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2020 Lightbend Inc. <https://www.lightbend.com>
*/
package akka.actor.typed
import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, LogCapturing, LoggingTestKit, ScalaTestWithActorTestKit }
import akka.actor.typed.internal.adapter.ActorSystemAdapter
import org.scalatest.wordspec.AnyWordSpecLike
object LocalActorRefProviderLogMessagesSpec {
val config = """
akka {
loglevel = DEBUG # test verifies debug
log-dead-letters = on
actor {
debug.unhandled = on
}
}
"""
}
class LocalActorRefProviderLogMessagesSpec
extends ScalaTestWithActorTestKit(LocalActorRefProviderLogMessagesSpec.config)
with AnyWordSpecLike
with LogCapturing {
"An LocalActorRefProvider" must {
"logs on dedicated 'serialization' logger of unknown path" in {
val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider
LoggingTestKit
.debug("of unknown (invalid) path [dummy/path]")
.withLoggerName("akka.actor.LocalActorRefProvider.Deserialization")
.expect {
provider.resolveActorRef("dummy/path")
}
}
"logs on dedicated 'serialization' logger when path doesn't match existing actor" in {
val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider
val invalidPath = provider.rootPath / "user" / "invalid"
LoggingTestKit
.debug("Resolve (deserialization) of path [user/invalid] doesn't match an active actor.")
.withLoggerName("akka.actor.LocalActorRefProvider.Deserialization")
.expect {
provider.resolveActorRef(invalidPath)
}
}
"logs on dedicated 'serialization' logger when of foreign path" in {
val otherSystem = ActorTestKit("otherSystem").system.asInstanceOf[ActorSystemAdapter[_]]
val invalidPath = otherSystem.provider.rootPath / "user" / "foo"
val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider
try {
LoggingTestKit
.debug("Resolve (deserialization) of foreign path [akka://otherSystem/user/foo]")
.withLoggerName("akka.actor.LocalActorRefProvider.Deserialization")
.expect {
provider.resolveActorRef(invalidPath)
}
} finally {
ActorTestKit.shutdown(otherSystem)
}
}
}
}

View file

@ -387,7 +387,14 @@ private[akka] class LocalActorRefProvider private[akka] (
override val rootPath: ActorPath = RootActorPath(Address("akka", _systemName))
private[akka] val log: MarkerLoggingAdapter =
Logging.withMarker(eventStream, getClass.getName + "(" + rootPath.address + ")")
Logging.withMarker(eventStream, getClass)
/*
* This dedicated logger is used whenever a deserialization failure occurs
* and can therefore be disabled/enabled independently
*/
private[akka] val logDeser: MarkerLoggingAdapter =
Logging.withMarker(eventStream, getClass.getName + ".Deserialization")
override val deadLetters: InternalActorRef =
_deadLetters
@ -587,14 +594,14 @@ private[akka] class LocalActorRefProvider private[akka] (
def resolveActorRef(path: String): ActorRef = path match {
case ActorPathExtractor(address, elems) if address == rootPath.address => resolveActorRef(rootGuardian, elems)
case _ =>
log.debug("Resolve (deserialization) of unknown (invalid) path [{}], using deadLetters.", path)
logDeser.debug("Resolve (deserialization) of unknown (invalid) path [{}], using deadLetters.", path)
deadLetters
}
def resolveActorRef(path: ActorPath): ActorRef = {
if (path.root == rootPath) resolveActorRef(rootGuardian, path.elements)
else {
log.debug(
logDeser.debug(
"Resolve (deserialization) of foreign path [{}] doesn't match root path [{}], using deadLetters.",
path,
rootPath)
@ -607,13 +614,13 @@ private[akka] class LocalActorRefProvider private[akka] (
*/
private[akka] def resolveActorRef(ref: InternalActorRef, pathElements: Iterable[String]): InternalActorRef =
if (pathElements.isEmpty) {
log.debug("Resolve (deserialization) of empty path doesn't match an active actor, using deadLetters.")
logDeser.debug("Resolve (deserialization) of empty path doesn't match an active actor, using deadLetters.")
deadLetters
} else
ref.getChild(pathElements.iterator) match {
case Nobody =>
if (log.isDebugEnabled)
log.debug(
logDeser.debug(
"Resolve (deserialization) of path [{}] doesn't match an active actor. " +
"It has probably been stopped, using deadLetters.",
pathElements.mkString("/"))