Ich habe eine Java Akka Anwendung und ich möchte für jede Nachricht einen separaten MDC Kontext setzen auf Informationen in der Nachricht basierend Handhabung, zum Beispiel habe ich die folgende Basis-Interface für alle Nachrichten:Schauspieler MDC Kontext in aroundReceive Methode
public interface IdMessage {
String getId();
}
auch habe ich die folgende Basis Schauspieler für alle Akteure:
public class BaseActor extends AbstractActor {
private final DiagnosticLoggingAdapter log = Logging.apply(this);
@Override
public void aroundReceive(PartialFunction<Object, BoxedUnit> receive, Object msg) {
if (msg instanceof IdMessage) {
final Map<String, Object> originalMDC = log.getMDC();
log.setMDC(ImmutableMap.of("id", ((IdMessage) msg).getId()));
try {
super.aroundReceive(receive, msg);
} finally {
if (originalMDC != null) {
log.setMDC(originalMDC);
} else {
log.clearMDC();
}
}
} else {
super.aroundReceive(receive, msg);
}
}
}
Und die eigentliche Schauspieler Umsetzung:
public class SomeActor extends BaseActor {
SomeActor() {
receive(ReceiveBuilder
.match(SomeMessage.class, message -> {
...
}
}
}
Ich möchte sicherstellen, dass alle Log-Einträge innerhalb SomeActor#receive()
MDC-Kontext in der BaseActor
gesetzt haben. Um dies zu tun SomeActor#receice()
müssen im selben Thread wie BaseActor#aroundReceive()
Methode ausgeführt werden.
Ich habe keine Informationen über das Verhalten von aroundReceive
gefunden - wird das immer im selben Thread wie die tatsächliche receive
Methode ausgeführt werden? Basierend auf meinen Tests wird es immer im selben Thread ausgeführt.
Die Gründe, warum 'DiagnosticLoggingAdapter' nicht den Trick macht, werden in [diese Antwort] erklärt (http://stackoverflow.com/a/31237679/843660). Wie beim Überschreiben von "aroundReceive" wird dies als interne API markiert und funktioniert nur, wenn Sie Ihre Klasse in das Paket "akka.actor" stellen, was ein Hack ist. Siehe [diese Antwort] (http://stackoverflow.com/a/26723452/843660). Ich bin mir nicht sicher, was man in Java machen kann. – dskrvk