-
Notifications
You must be signed in to change notification settings - Fork 45
MP Context Propagation integration #205
Copy link
Copy link
Open
Description
Currently, parent span is lost when code moves to another thread. This can be easily solved when using MP Context Propagation with a custom ThreadContextProvider.
With such a provider in place, registered for context type "OpenTracing", you just need to do request propagation:
ManagedExecutor executor = ManagedExecutor.builder().
propagated(ThreadContext.APPLICATION, ThreadContext.CDI, "OpenTracing").
build();
executor.runAsync(() -> restClient.target("http://localhost:9080").request().get());OpenTracing spec should define that integration when MP Context Propagation is available.
An example of a rudimentary ThreadContextProvider I've just implemented myself for this case:
import io.opentracing.Span;
import io.opentracing.Tracer;
import java.util.Map;
import javax.enterprise.inject.spi.CDI;
import org.eclipse.microprofile.context.spi.ThreadContextController;
import org.eclipse.microprofile.context.spi.ThreadContextProvider;
import org.eclipse.microprofile.context.spi.ThreadContextSnapshot;
public class OpenTracingSpanContextProvider implements ThreadContextProvider {
public static final String THREAD_CONTEXT_TYPE = "OpenTracing";
@Override
public ThreadContextSnapshot currentContext(Map<String, String> map) {
Tracer tracer;
Span activeSpan;
try {
tracer = CDI.current().select(Tracer.class).get();
activeSpan = tracer.activeSpan();
} catch (RuntimeException e) {
// No active Tracer instance
tracer = null;
activeSpan = null;
}
// Pass the current Tracer and Span (might be null)
return new OTSpanThreadContextSnapshot(tracer, activeSpan);
}
@Override
public ThreadContextSnapshot clearedContext(Map<String, String> map) {
return new OTSpanThreadContextSnapshot(null, null);
}
@Override
public String getThreadContextType() {
return THREAD_CONTEXT_TYPE;
}
public static class OTSpanThreadContextSnapshot implements ThreadContextSnapshot {
private final Tracer tracer;
private final Span propagatedSpan;
public OTSpanThreadContextSnapshot(Tracer tracer, Span propagatedSpan) {
this.tracer = tracer;
this.propagatedSpan = propagatedSpan;
}
@Override
public ThreadContextController begin() {
if (tracer == null || propagatedSpan == null) {
// There was no active span. No context to propagate and nothing to restore afterwards
return new OTSpanThreadContextController(null, null);
}
Span newThreadSpan = tracer.activeSpan();
// Establish the span from the callee thread
tracer.scopeManager().activate(propagatedSpan, true);
return new OTSpanThreadContextController(tracer, newThreadSpan);
}
}
public static class OTSpanThreadContextController implements ThreadContextController {
private final Tracer tracer;
private final Span threadSpan;
public OTSpanThreadContextController(Tracer tracer, Span threadSpan) {
this.tracer = tracer;
this.threadSpan = threadSpan;
}
@Override
public void endContext() throws IllegalStateException {
if (tracer == null || threadSpan == null) {
// No context to restore
return;
}
tracer.scopeManager().activate(threadSpan, true);
}
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels