简体   繁体   中英

How to set up logging in akka-typed so that actor paths are properly showing?

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. 

try 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">

try 2

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.

try 3

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM