Reputation: 1294
I can't get set up a proper Logger in a typed actor.
This is the log line I want to achieve:
INFO 16:27:50 com.example.Registry /user/client-0(akka://NumberRegistry) - received input 1.
I'm using slf4j, This the current, best setup code I have managed to write but it's not enough.
private val logger = Logging(context.system.toUntyped, context.self.path.toStringWithoutAddress)
outputting:
INFO 16:27:50 /user/client-0(akka://NumberRegistry) - received input 1.
I can't filter additivity levels on this with slf4j, so I can't differentiate between system logs and my logs. You can't name a subpath in logback.xml
like
<logger name="com.example" level="DEBUG" additivity="false">
If you pass this.getClass
as logSource:
private val logger = Logging(context.system.toUntyped, this.getClass)
you'll just get a bunch of akka.actor.typed.internal.adapter.ActorSystemAdapter
as logger name in the logs.
I tried to create a custom LogSource
, by overriding genString
and getClazz
:
object MyType {
implicit val logSource: LogSource[AnyRef] = new LogSource[AnyRef] {
def genString(o: AnyRef): String = o match {
case o: ActorRef[_] => o.path.path.toStringWithoutAddress
case _ => o.getClass.getName
}
override def getClazz(o: AnyRef): Class[_] = o match {
case _: ActorRef[_] => classOf[akka.event.DummyClassForStringSources]
case _ => o.getClass
}
}
but it doesn't work and it's not nice either.
I read the whole logging documentation but it doesn't detail akka-typed.
How do I set up a logger that has the classname and the actor path set correctly in a typed actor?
Upvotes: 1
Views: 825
Reputation: 14394
If you use the context logger context.log
you will get all the information you want in the MDC:
{
timestamp=1557948214734,
level=INFO,
thread=dependency-system-akka.actor.default-dispatcher-4,
mdc={
sourceThread=dependency-system-akka.actor.default-dispatcher-3,
akkaSource=akka://dependency-system/user/pinger,
sourceActorSystem=dependency-system,
akkaTimestamp=19:23:34.731UTC
},
logger=akka.actor.typed.Behavior$,
message=ping,
context=default
}
To get a pattern like you are looking for use something like this:
<encoder>
<pattern>%-5level %d %logger{35} %mdc{akkaSource} - %msg%n</pattern>
</encoder>
which renders the above like this:
INFO 2019-05-15 12:28:59,012 akka.actor.typed.Behavior$ akka://dependency-system/user/pinger - ping
The only problem that remains that the logger defaults to akka.actor.typed.Behavior$
. But you can initialize that in your context:
object Pinger {
sealed trait Command
case object Ping extends Command
Behaviors.setup { context =>
context.setLoggerClass(this.getClass)
Behaviors.receiveMessage[Command] {
case Ping =>
context.log.info("ping")
Behaviors.same
}
}
}
resulting in
INFO 2019-05-15 12:52:52,911 x.x.actors.Pinger$ akka://dependency-system/user/pinger - ping
Upvotes: 1