Class DistributedTracer

java.lang.Object
com.loomcache.server.observability.DistributedTracer

public final class DistributedTracer extends Object
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

  1. Create: createSpan(String) starts a new root span
  2. Child: createChildSpan(Span, String) creates a child span
  3. Attributes: setAttribute(String, String, String) adds key-value data
  4. Events: addEvent(String, String) records timestamped annotations
  5. 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
  • 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 buffer
      exporter - optional span exporter
      meterRegistry - the Micrometer MeterRegistry for metrics
      Throws:
      IllegalArgumentException - if sampleRate is invalid or capacity invalid input: '<'= 0
      NullPointerException - if meterRegistry is null
  • Method Details

    • currentTraceContext

      public static @Nullable DistributedTracer.TraceContext currentTraceContext()
      Get the current trace context from ScopedValue.
      Returns:
      the current TraceContext or null if not in a tracing context
    • createSpan

      public DistributedTracer.TraceContext createSpan(String operationName)
      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 object
      operationName - the child operation name
      Returns:
      a TraceContext for the child span
      Throws:
      NullPointerException - if either parameter is null
    • setAttribute

      public void setAttribute(String spanId, String key, String value)
      Add an attribute (key-value pair) to the current active span.
      Parameters:
      spanId - the span ID
      key - the attribute key
      value - the attribute value
      Throws:
      NullPointerException - if any parameter is null
    • addEvent

      public void addEvent(String spanId, String eventName)
      Add an event to the current active span.
      Parameters:
      spanId - the span ID
      eventName - 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 ID
      status - the final status
      Returns:
      the completed Span object
      Throws:
      NullPointerException - if any parameter is null or if span not found
    • getSpanFromBuffer

      public @Nullable DistributedTracer.Span getSpanFromBuffer(int index)
      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

      public List<DistributedTracer.Span> 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