Created
April 20, 2018 12:40
-
-
Save mdvorak/80c52b56d2587f66b6201f3cf36c4d1c to your computer and use it in GitHub Desktop.
opentracing-contrib/java-spring-cloud#92 Standard logging integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.opentracing.Scope; | |
import io.opentracing.ScopeManager; | |
import io.opentracing.Span; | |
import org.slf4j.MDC; | |
import org.springframework.lang.Nullable; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Objects; | |
public class DiagnosticContextScopeManager implements ScopeManager { | |
private final ScopeManager scopeManager; | |
private final SpanDiagnosticContext spanDiagnosticContext; | |
public DiagnosticContextScopeManager(ScopeManager scopeManager, SpanDiagnosticContext spanDiagnosticContext) { | |
this.scopeManager = Objects.requireNonNull(scopeManager); | |
this.spanDiagnosticContext = Objects.requireNonNull(spanDiagnosticContext); | |
} | |
@Override | |
public Scope activate(Span span, boolean finishSpanOnClose) { | |
// Activate scope | |
Scope scope = scopeManager.activate(span, finishSpanOnClose); | |
Map<String, String> context = spanDiagnosticContext.create(scope.span()); | |
// Return wrapper | |
return new DiagnosticContextScope(scope, context); | |
} | |
@Nullable | |
@Override | |
public Scope active() { | |
return scopeManager.active(); | |
} | |
/** | |
* Wrapper class for {@link Scope}, which also closes attached {@link SpanDiagnosticContext}. | |
* <p> | |
* Created by {@link DiagnosticContextScopeManager}. | |
*/ | |
public static class DiagnosticContextScope implements Scope { | |
private final Scope scope; | |
private final Map<String, String> previous = new HashMap<>(); | |
public DiagnosticContextScope(Scope scope, Map<String, String> context) { | |
this.scope = scope; | |
// Initialize MDC | |
for (Map.Entry<String, String> entry : context.entrySet()) { | |
this.previous.put(entry.getKey(), MDC.get(entry.getKey())); | |
mdcReplace(entry.getKey(), entry.getValue()); | |
} | |
} | |
@Override | |
public void close() { | |
// Close | |
scope.close(); | |
// Restore previous context | |
for (Map.Entry<String, String> entry : previous.entrySet()) { | |
mdcReplace(entry.getKey(), entry.getValue()); | |
} | |
} | |
@Nullable | |
@Override | |
public Span span() { | |
return scope.span(); | |
} | |
private static void mdcReplace(String key, @Nullable String value) { | |
if (value != null) { | |
MDC.put(key, value); | |
} else { | |
MDC.remove(key); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.uber.jaeger.SpanContext; | |
import io.opentracing.Span; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class JaegerDiagnosticContext implements SpanDiagnosticContext { | |
@Override | |
public Map<String, String> create(Span span) { | |
// Get Jaeger context | |
SpanContext spanContext = (SpanContext) span.context(); | |
// Prepare context map | |
Map<String, String> contextMap = new HashMap<>(3); | |
contextMap.put("traceId", Long.toHexString(spanContext.getTraceId())); | |
contextMap.put("spanId", Long.toHexString(spanContext.getSpanId())); | |
contextMap.put("flags", Integer.toHexString(spanContext.getFlags())); | |
return contextMap; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.uber.jaeger.Tracer; | |
import io.opentracing.ScopeManager; | |
import io.opentracing.contrib.spring.cloud.starter.jaeger.TracerBuilderCustomizer; | |
import io.opentracing.util.ThreadLocalScopeManager; | |
import org.springframework.lang.NonNull; | |
public class JaegerDiagnosticContextTracerBuilderCustomizer implements TracerBuilderCustomizer { | |
private final ScopeManager scopeManager; | |
private final SpanDiagnosticContext spanDiagnosticContext; | |
public JaegerDiagnosticContextTracerBuilderCustomizer(@NonNull SpanDiagnosticContext spanDiagnosticContext) { | |
scopeManager = new ThreadLocalScopeManager(); | |
this.spanDiagnosticContext = spanDiagnosticContext; | |
} | |
public JaegerDiagnosticContextTracerBuilderCustomizer(@NonNull ScopeManager scopeManager, @NonNull SpanDiagnosticContext spanDiagnosticContext) { | |
this.scopeManager = scopeManager; | |
this.spanDiagnosticContext = spanDiagnosticContext; | |
} | |
@Override | |
public void customize(Tracer.Builder builder) { | |
builder.withScopeManager(new DiagnosticContextScopeManager(scopeManager, spanDiagnosticContext)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.opentracing.Span; | |
import java.util.Map; | |
@FunctionalInterface | |
public interface SpanDiagnosticContext { | |
Map<String, String> create(Span span); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.opentracing.contrib.spring.cloud.starter.jaeger.TracerBuilderCustomizer; | |
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | |
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
@Configuration | |
public class TracerDiagnosticContextAutoConfiguration { | |
@Configuration | |
@ConditionalOnClass(TracerBuilderCustomizer.class) | |
public static class JaegerDiagnosticContextConfiguration { | |
@Bean | |
@ConditionalOnMissingBean(SpanDiagnosticContext.class) | |
public JaegerDiagnosticContext jaegerDiagnosticContext() { | |
return new JaegerDiagnosticContext(); | |
} | |
@Bean | |
public TracerBuilderCustomizer diagnosticContextTracerBuilderCustomizer(SpanDiagnosticContext spanDiagnosticContext) { | |
return new JaegerDiagnosticContextTracerBuilderCustomizer(spanDiagnosticContext); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment