This module is showcasing how to use some APIs from Brave.
- build.gradle.kts
- TracingFactory.kt
- BraveHelloWorldV1.kt
- BraveExecutorsV1.kt
- BraveExecutorsV2.kt
- BraveCoroutinesV1.kt
- BraveCoroutinesV2.kt
- BraveReactorV1.kt
- this factory is used in all examples in this project to create an instance of
brave.Tracing
- it first creates an instance of
zipkin2.reporter.brave.AsyncZipkinSpanHandler
for reporting spans to Tempo - then, it proceeds with
Tracing.newBuilder()
which is provided with sampling, naming and other options brave.propagation.ThreadLocalCurrentTraceContext
is created for propagating the trace context- this is where
brave.context.slf4j.MDCScopeDecorator
gets registered to take care of putting baggage into MDC - additionally,
brave.baggage.BaggagePropagation
is configured to propagate each provided baggage field locally
tracer.newTrace()
will create a newbrave.Span
(trace) with a given nameSpan.tag()
is used to set tags on a trace (don't confuse this with baggage though)Span.start()
is called to signal that span has startedbrave.baggage.BaggageField.updateValue()
is used to set a baggage valuetracer.withSpanInScope(trace)
helps with setting the trace as current for a block of codeSpan.finish()
is needed to signal that the span has ended and can be reported to Tempo
- here we create a couple of thread pools / executors for doing processing of each user in 2 stages
- we use APIs from previous example, but have to run
tracer.withSpanInScope(trace)
within each task
- this is an improved version of the previous example with executors
- here each executor is wrapped with
tracing.currentTraceContext().executorService()
- this allows to avoid calling
tracer.withSpanInScope()
on the nested tasks, as those inherit the trace context - underneath,
CurrentTraceContextExecutorService
is used to capture context of the current trace at the time of calling.submit()
on the pool
- in this version we call
tracer.withSpanInScope(trace)
outside of coroutine code to make the trace current - then we launch a coroutine with
kotlinx.coroutines.slf4j.MDCContext
added to the context - this does not give us trace propagation, but at least MDC values from baggage are maintained between thread switches
- this example improves the previous one by handling trace propagation within coroutines
TracingContextElement
is first implemented by extendingThreadContextElement
- we are then able to add
TracingContextElement(tracing.currentTraceContext())
to coroutine context - this makes sure that tracing context is restored every time the coroutine switches a thread
- here we again rely on
io.micrometer:context-propagation
library ContextRegistry.getInstance().registerThreadLocalAccessor()
is used to manipulatetracing.currentTraceContext()