Interface SpanFactory

All Superinterfaces:
DescribableComponent
All Known Implementing Classes:
LoggingSpanFactory, MicrometerSpanFactory

public interface SpanFactory extends DescribableComponent
The sole public abstraction for creating tracing spans in Axon Framework.

A single SpanFactory is registered against the framework's ComponentRegistry; the per-concern tracing modules then wrap components with delegating tracing decorators that obtain their spans from this factory. There is intentionally no per-bus or per-component SpanFactory interface -- the per-component span shapes (names, kinds, attributes, cross-process metadata propagation) are implementation details of those internal decorators.

Parent resolution. Parents are resolved from (1) the propagated context carried in a Message's metadata (cross-thread / cross-process) and (2) the active span recorded on the supplied ProcessingContext (in-process nesting; see Span.start()). Those two carriers are authoritative for framework-internal parenting. When neither yields a parent, an implementation MAY fall back to its tracing provider's ambient trace context before starting a new trace (a root): that fallback lets framework spans join a trace opened by an externally-instrumented caller (an HTTP controller, a scheduled job) and covers the framework edges where no ProcessingContext exists at span-creation time. To force a new trace regardless of any active span, use createRootSpan(String, ProcessingContext).

Span names are evaluated eagerly. Every factory method takes the operation name as a plain String -- matching OpenTelemetry's own eager API (Tracer.spanBuilder(String)) -- rather than a lazy Supplier<String>. Callers building expensive names (e.g. reflective method signatures) must therefore decide that a span will actually be created before computing the name, and build it only on the span-creating branch. Decorator authors (including extension authors instrumenting their own components) should not install a tracing decorator when no factory is configured, so the un-traced path carries no name-building cost whatsoever.

Fan-out to multiple tracing destinations is a concern of the SpanFactory implementation's export layer, below this abstraction. Tracing is disabled by not registering a SpanFactory component at all -- component decorators are then not installed.

Since:
4.6.0
Author:
Mateusz Nowak, Mitchell Herrijgers
  • Method Details

    • createDispatchSpan

      Span createDispatchSpan(String operationName, Message message, @Nullable ProcessingContext context)
      Creates a Span for an outbound (dispatch / producer) operation on the given Message. The parent is the active span on context (when present), so a message dispatched from within another traced operation nests under it; otherwise resolution continues per the class-level parent-resolution notes (the context propagated in message's metadata, then the implementation's optional ambient fallback, then a new root). The context, when non-null, is also forwarded to every SpanAttributesProvider the implementation was constructed with.
      Parameters:
      operationName - the span name
      message - the message the operation acts on
      context - the active processing context, or null when none is available
      Returns:
      the created span (not yet started)
    • createHandlerSpan

      Span createHandlerSpan(String operationName, Message message, @Nullable ProcessingContext context)
      Creates a Span for an inbound (handler / consumer) operation on the given Message. The parent is the tracing context propagated in message's metadata (cross-thread / cross-process); when none is present, the active span on context; when neither is present, the implementation's optional ambient fallback applies before a new root (see the class-level parent-resolution notes).
      Parameters:
      operationName - the span name
      message - the message being handled
      context - the active processing context, or null when none is available
      Returns:
      the created span (not yet started)
    • createContextParentHandlerSpan

      Span createContextParentHandlerSpan(String operationName, Message message, @Nullable ProcessingContext context)
      Creates a Span for an inbound (handler / consumer) operation that runs inside an independently traced processing context. The parent is the active span on context; the tracing context propagated in message's metadata is attached as a span link instead of replacing that parent. This keeps an enclosing operation, such as a streaming-event-processor batch, as the structural parent while preserving navigation to the producer that created the handled message.

      Implementations MUST prefer the active span on context over the propagated message context. When no active context span is available, the implementation's optional ambient fallback applies before a new root. Implementations MUST independently extract the propagated context from message and attach it as a link; when no link can be extracted, the span is still created and this method never throws.

      Parameters:
      operationName - the span name
      message - the message being handled -- its metadata supplies the link target
      context - the processing context supplying the structural parent, or null when unavailable
      Returns:
      the created span (not yet started)
    • createLinkedHandlerSpan

      Span createLinkedHandlerSpan(String operationName, Message message, Message linkedMessage, @Nullable ProcessingContext context)
      Creates a Span for an inbound (handler / consumer) operation on the given Message, with an additional link to linkedMessage's span context. The link expresses a relationship between traces without changing the span's parent; tracing backends typically render it as navigation between the linked traces. Implementations MUST extract the propagated context from linkedMessage's metadata and attach it as a span link; when no link can be extracted the span is still created without the link, and this method never throws. Parent resolution is as in createHandlerSpan(String, Message, ProcessingContext).
      Parameters:
      operationName - the span name
      message - the message being handled
      linkedMessage - the message whose span context is linked to
      context - the active processing context, or null when none is available
      Returns:
      the created span (not yet started)
    • createInternalSpan

      Span createInternalSpan(String operationName, @Nullable ProcessingContext context)
      Creates a Span for an internal operation that is not directly tied to a Message. The parent is the active span on context (when present), so the internal span nests under the operation that opened it (for example a handler span); otherwise the implementation's optional ambient fallback applies before a new root (see the class-level parent-resolution notes). Non-message attributes are attached by the calling decorator via Span.addAttribute(String, String).
      Parameters:
      operationName - the span name
      context - the active processing context, or null when none is available
      Returns:
      the created span (not yet started)
    • createDisconnectedHandlerSpan

      Span createDisconnectedHandlerSpan(String operationName, Message message, @Nullable ProcessingContext context)
      Creates a Span for an inbound (handler / consumer) operation that should start a new trace (root) yet remain navigable to the producing trace through a span link. The link target is the tracing context propagated in message's metadata.

      This is the "distributed-in-different-trace" handling mode. Use it when joining the publisher's trace would either flood it (long-running consumers, batch processors) or cross trust / lifecycle boundaries, while keeping the consumer's new trace navigable back to the producer through the link.

      Implementations MUST start a new trace (no parent-of relationship to the producer), extract the producer's context from message's metadata and attach it as a span link. When no link can be extracted (e.g. no tracing context on the message), the span is still created without a link and this method never throws.

      Parameters:
      operationName - the span name
      message - the message being handled -- its metadata supplies the link target
      context - the active processing context, or null when none is available
      Returns:
      the created span (not yet started)
    • createRootSpan

      Span createRootSpan(String operationName, @Nullable ProcessingContext context)
      Creates a Span that always starts a new trace (a root), ignoring any active span when resolving its own parent. Use this for operations that legitimately begin their own trace and must not attach to a stale or unrelated active span -- for example an event-processing batch boundary or an out-of-band snapshot operation running on a pooled thread. When context is non-null, starting the span still records it as that context's active span, so spans created next with that context nest under this root.

      When context carries an active span, implementations MUST attach that span as a span link (not as a parent), preserving the relationship to the operation that triggered it without creating a parent-of relationship to that operation.

      Parameters:
      operationName - the span name
      context - the processing context the root should become the active span of (and link back to), or null
      Returns:
      the created root span (not yet started)