Class DistributedTracer
java.lang.Object
com.loomcache.server.observability.DistributedTracer
Distributed tracing system for LoomCache with W3C Trace Context compatibility.
Overview
Implements distributed tracing across multiple services with full span hierarchy support, sampling, and exportable trace context. Compliant with W3C Trace Context standard.Trace IDs and Span IDs
- Trace ID: 128-bit (32 hex characters) globally unique identifier for an entire request
- Span ID: 64-bit (16 hex characters) unique identifier for a single operation
- Parent Span ID: Reference to the parent span in the hierarchy
Span Lifecycle
- Create:
createSpan(String)starts a new root span - Child:
createChildSpan(Span, String)creates a child span - Attributes:
setAttribute(String, String, String)adds key-value data - Events:
addEvent(String, String)records timestamped annotations - End:
endSpan(String, SpanStatus)completes the span
Sampling
Spans are probabilistically sampled based on the configurable sample rate (0.0 to 1.0). Metrics track both sampled and unsampled spans.Context Propagation
Uses ScopedValue to maintain trace context across virtual threads:
Span span = tracer.createSpan("operation");
try (var ignore = TRACE_CONTEXT.where(span.traceContext()).scope()) {
// Child operations inherit context automatically
}
Thread Safety
This class is fully thread-safe. All operations on spans and the ring buffer are protected by internal locks. Multiple virtual threads may trace concurrently.Memory Management
Completed spans are stored in a bounded ring buffer (default 1000 entries). When the buffer is full, oldest entries are overwritten. Spans are also exported via the configured exporter.- Since:
- 1.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordImmutable span data structure.static interfaceFunctional interface for exporting completed spans.static interfaceSealed interface for span status.static final recordTimestamped annotation event within a span.static final recordTrace context for propagation across thread boundaries. -
Constructor Summary
ConstructorsConstructorDescriptionDistributedTracer(double sampleRate, int ringBufferCapacity, @Nullable DistributedTracer.SpanExporter exporter, io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a new DistributedTracer with custom configuration.DistributedTracer(io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a new DistributedTracer with default configuration. -
Method Summary
Modifier and TypeMethodDescriptionvoidAdd an event to the current active span.createChildSpan(DistributedTracer.Span parentSpan, String operationName) Create a child span within the current trace context.createSpan(String operationName) Create a new root span with a new trace ID.static @Nullable DistributedTracer.TraceContextGet the current trace context from ScopedValue.endSpan(String spanId, DistributedTracer.SpanStatus status) End a span with the given status.intGet the number of active spans.Get all spans currently in the ring buffer.@Nullable DistributedTracer.SpangetSpanFromBuffer(int index) Get a span from the ring buffer by index.voidsetAttribute(String spanId, String key, String value) Add an attribute (key-value pair) to the current active span.
-
Constructor Details
-
DistributedTracer
public DistributedTracer(io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a new DistributedTracer with default configuration.- Parameters:
meterRegistry- the Micrometer MeterRegistry for metrics
-
DistributedTracer
public DistributedTracer(double sampleRate, int ringBufferCapacity, @Nullable DistributedTracer.SpanExporter exporter, io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a new DistributedTracer with custom configuration.- Parameters:
sampleRate- sampling rate (0.0 to 1.0)ringBufferCapacity- capacity of the in-memory span bufferexporter- optional span exportermeterRegistry- the Micrometer MeterRegistry for metrics- Throws:
IllegalArgumentException- if sampleRate is invalid or capacity invalid input: '<'= 0NullPointerException- if meterRegistry is null
-
-
Method Details
-
currentTraceContext
Get the current trace context from ScopedValue.- Returns:
- the current TraceContext or null if not in a tracing context
-
createSpan
Create a new root span with a new trace ID.- Parameters:
operationName- the operation name- Returns:
- a TraceContext for this span
- Throws:
NullPointerException- if operationName is null
-
createChildSpan
public DistributedTracer.TraceContext createChildSpan(DistributedTracer.Span parentSpan, String operationName) Create a child span within the current trace context.- Parameters:
parentSpan- the parent Span objectoperationName- the child operation name- Returns:
- a TraceContext for the child span
- Throws:
NullPointerException- if either parameter is null
-
setAttribute
Add an attribute (key-value pair) to the current active span.- Parameters:
spanId- the span IDkey- the attribute keyvalue- the attribute value- Throws:
NullPointerException- if any parameter is null
-
addEvent
Add an event to the current active span.- Parameters:
spanId- the span IDeventName- the event name- Throws:
NullPointerException- if any parameter is null
-
endSpan
End a span with the given status. Completes the span and triggers export if configured.- Parameters:
spanId- the span IDstatus- the final status- Returns:
- the completed Span object
- Throws:
NullPointerException- if any parameter is null or if span not found
-
getSpanFromBuffer
Get a span from the ring buffer by index.- Parameters:
index- the ring buffer index (0 to capacity-1)- Returns:
- the Span at that index or null if not yet written
- Throws:
IndexOutOfBoundsException- if index is invalid
-
getAllSpansInBuffer
Get all spans currently in the ring buffer.- Returns:
- a list of non-null spans in the buffer
-
getActiveSpanCount
public int getActiveSpanCount()Get the number of active spans.- Returns:
- the count of currently active spans
-