Akka: Tracable logs

Viewed 277

I'm using Akka with Java. I want to know is there any best practice/pattern to trace scenarios with logging in Akka environment?

Here is a very simple scenario:

  1. A source Device actor sends a status message to the Propagator actor;
  2. The Propagator actor forwards the status message to its listeners (other Device actors);
  3. Each listener (Device) sends an ack message to the Propagator actor.

Base Requirements:

  1. Each running scenario should be distinguishable in logs.
  2. The scenario-initiator identifier (here is a device-id) should be presented in all logs.

Any advice for adding to requirements? Maybe the initiating message's class name!?

My approach is putting traceable info in logger's MDC: 1) introducing an interface for marking messages and 2) an Abstract class as a base class of all actors:

1- Traceable which is implemented by all (related) message classes:

public interface Traceable {

    String traceId(); // An unique id (UUID) in each scenario (Req#1)

    int deviceId(); // Device which initiated the scenario (Req#2)

}

2- AbstractActorWithLogging as base class of all actors, which puts traceable information in logger's MDC:

public abstract class AbstractActorWithLogging extends AbstractActor {

    protected final DiagnosticLoggingAdapter logger = Logging.getLogger(this);

    @Override
    public void aroundReceive(PartialFunction<Object, BoxedUnit> receive, Object msg) {
        try {
            if (msg instanceof Traceable) logger.setMDC(extractMdc(((Traceable) msg)));
            if (logger.isDebugEnabled()) logger.debug("Received: {}.", msg);
            super.aroundReceive(receive, msg);
            if (logger.isDebugEnabled()) logger.debug("Processed: {}.", msg);
        } finally {
            logger.clearMDC();
        }
    }

    protected Map<String, Object> extractMdc(Traceable traceable) {
        Map<String, Object> mdc = new HashMap<>();
        mdc.put("traceId", traceable.traceId());
        mdc.put("deviceId", traceable.deviceId());
        return mdc;
    }
}
0 Answers
Related