From 9f817236f6d2930d4aeb1c47f2b6b2bf14348ac3 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Tue, 5 May 2020 14:58:35 +0200 Subject: [PATCH 1/4] Added dedicated logger for deserialization failures --- ...LocalActorRefProviderLogMessagesSpec.scala | 42 +++++++++++++++++++ .../scala/akka/actor/ActorRefProvider.scala | 17 +++++--- 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala new file mode 100644 index 0000000000..fd3f93168f --- /dev/null +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 Lightbend Inc. + */ + +package akka.actor.typed + +import akka.actor.testkit.typed.scaladsl.{ 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 { + + "An LocalActorRefProvider" must { + + "logs on dedicated 'serialization' logger when an ActorRef can't be deserialized" in { + val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider + val invalidPath = provider.rootPath / "user" / "invalid" + + LoggingTestKit + .debug("Resolve (deserialization)") + .withLoggerName("akka.actor.LocalActorRefProvider.Deserialization") + .expect { + provider.resolveActorRef(invalidPath) + } + + } + } +} diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index fcc0c3a850..3eaf85f406 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -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("/")) From 80915db7952592620634dba6ebfe192a88893df8 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Tue, 5 May 2020 16:19:12 +0200 Subject: [PATCH 2/4] add coverage for invalid and foreing path --- ...LocalActorRefProviderLogMessagesSpec.scala | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala index fd3f93168f..641dd7b585 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala @@ -4,7 +4,7 @@ package akka.actor.typed -import akka.actor.testkit.typed.scaladsl.{ LoggingTestKit, ScalaTestWithActorTestKit } +import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, LoggingTestKit, ScalaTestWithActorTestKit } import akka.actor.typed.internal.adapter.ActorSystemAdapter import org.scalatest.wordspec.AnyWordSpecLike @@ -26,17 +26,59 @@ class LocalActorRefProviderLogMessagesSpec "An LocalActorRefProvider" must { - "logs on dedicated 'serialization' logger when an ActorRef can't be deserialized" in { + "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)") + .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) + } + } + + // "logs on dedicated 'serialization' logger for empty paths" in { + + // val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider + // val invalidPath = provider.rootPath + + // LoggingTestKit + // .debug("Resolve (deserialization) of empty path") + // .withLoggerName("akka.actor.LocalActorRefProvider.Deserialization") + // .expect { + // provider.resolveActorRef(invalidPath.toString) + // } + // } + } } From a5fc6fcbda96b1f3d826458a07a42af45acaa837 Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Tue, 5 May 2020 16:37:37 +0200 Subject: [PATCH 3/4] added LogCapturing --- .../actor/typed/LocalActorRefProviderLogMessagesSpec.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala index 641dd7b585..8fa90643dd 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala @@ -4,7 +4,7 @@ package akka.actor.typed -import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, LoggingTestKit, ScalaTestWithActorTestKit } +import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, LogCapturing, LoggingTestKit, ScalaTestWithActorTestKit } import akka.actor.typed.internal.adapter.ActorSystemAdapter import org.scalatest.wordspec.AnyWordSpecLike @@ -22,7 +22,8 @@ object LocalActorRefProviderLogMessagesSpec { class LocalActorRefProviderLogMessagesSpec extends ScalaTestWithActorTestKit(LocalActorRefProviderLogMessagesSpec.config) - with AnyWordSpecLike { + with AnyWordSpecLike + with LogCapturing { "An LocalActorRefProvider" must { From bd923e285a9274dd2beaf4dd0b18aff8ec8134de Mon Sep 17 00:00:00 2001 From: Renato Cavalcanti Date: Thu, 7 May 2020 21:00:41 +0200 Subject: [PATCH 4/4] remove commented out (irrelevant) test case --- .../LocalActorRefProviderLogMessagesSpec.scala | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala index 8fa90643dd..48baf19193 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/LocalActorRefProviderLogMessagesSpec.scala @@ -67,19 +67,5 @@ class LocalActorRefProviderLogMessagesSpec ActorTestKit.shutdown(otherSystem) } } - - // "logs on dedicated 'serialization' logger for empty paths" in { - - // val provider = system.asInstanceOf[ActorSystemAdapter[_]].provider - // val invalidPath = provider.rootPath - - // LoggingTestKit - // .debug("Resolve (deserialization) of empty path") - // .withLoggerName("akka.actor.LocalActorRefProvider.Deserialization") - // .expect { - // provider.resolveActorRef(invalidPath.toString) - // } - // } - } }