Otel.API.Trace.Span.Noop (otel v0.2.0)

Copy Markdown View Source

No-op Span operations implementation (OTel trace/api.md §"Behavior of the API in the absence of an installed SDK", L860-L874, Status: Stable).

Spec summary (L862-L874) applied to Span mutations:

"In general, in the absence of an installed SDK, the Trace API is a 'no-op' API. This means that operations on a Tracer, or on Spans, should have no side effects and do nothing."

Start-span behaviour lives on Otel.API.Trace.Tracer.Noop (L865-L874 SpanContext-propagation exception); this module covers the 9 post-creation Span mutations. Each callback silently returns the shape the spec expects (:ok for mutations, false for recording?/1) with no state, no validation, no side effects.

Why this module exists

Unlike Tracer / Meter / Logger whose handles are {module, config} tuples — so Provider.get_x/1 can hand out a {Noop, []} tuple and the facade pattern-matches on the module — Span takes a SpanContext handle that doesn't carry a dispatcher. Otel.API.Trace.Span resolves its SDK module through a module-level :persistent_term slot. Defaulting that slot to Span.Noop keeps the facade branchless (get_module().set_attribute(...) always dispatches to a valid module) and mirrors the project-wide Noop pattern established by Tracer.Noop, Meter.Noop, Logger.Noop, and TextMap.Noop.

opentelemetry-erlang's reference takes a different route — its #span_ctx{span_sdk={Module, _}} embeds the dispatcher in the SpanContext itself (otel_span.erl L156-L157), so Erlang doesn't need a dedicated otel_span_noop module (none exists). Our SpanContext is deliberately a pure W3C data value (trace_id, span_id, trace_flags, tracestate, is_remote) with no SDK field; Span.Noop fills the gap.

All functions are safe for concurrent use.

Public API

FunctionRole
recording?/1SDK (Noop implementation) — always false (L862-L863)
set_attribute/3SDK (Noop implementation) — discard attribute (L862-L863)
set_attributes/2SDK (Noop implementation) — discard attribute map (L862-L863)
add_event/2SDK (Noop implementation) — discard event (L862-L863)
add_link/2SDK (Noop implementation) — discard link (L862-L863)
set_status/2SDK (Noop implementation) — discard status (L862-L863)
update_name/2SDK (Noop implementation) — discard name change (L862-L863)
end_span/2SDK (Noop implementation) — discard end signal (L862-L863)
record_exception/4SDK (Noop implementation) — discard exception event (L862-L863)

References

  • OTel Trace API §Behavior in absence of SDK: opentelemetry-specification/specification/trace/api.md L860-L874
  • OTel Trace API §Span operations: opentelemetry-specification/specification/trace/api.md L449-L705

Summary

Functions

SDK (Noop implementation) — add_event/2 discards the event silently (trace/api.md L862-L863).

SDK (Noop implementation) — add_link/2 discards the link silently (trace/api.md L862-L863).

SDK (Noop implementation) — end_span/2 discards the end signal silently (trace/api.md L862-L863).

SDK (Noop implementation) — record_exception/4 discards the exception event silently (trace/api.md L862-L863).

SDK (Noop implementation) — recording?/1 always returns false (trace/api.md L862-L863).

SDK (Noop implementation) — set_attribute/3 discards the attribute silently (trace/api.md L862-L863).

SDK (Noop implementation) — set_attributes/2 discards the attribute map silently (trace/api.md L862-L863).

SDK (Noop implementation) — set_status/2 discards the status silently (trace/api.md L862-L863).

SDK (Noop implementation) — update_name/2 discards the name change silently (trace/api.md L862-L863).

Types

primitive()

@type primitive() ::
  String.t() | {:bytes, binary()} | boolean() | integer() | float() | nil

primitive_any()

@type primitive_any() ::
  primitive() | [primitive_any()] | %{required(String.t()) => primitive_any()}

Functions

add_event(span_ctx, event)

@spec add_event(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  event :: Otel.API.Trace.Event.t()
) :: :ok

SDK (Noop implementation) — add_event/2 discards the event silently (trace/api.md L862-L863).

add_link(span_ctx, link)

@spec add_link(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  link :: Otel.API.Trace.Link.t()
) :: :ok

SDK (Noop implementation) — add_link/2 discards the link silently (trace/api.md L862-L863).

end_span(span_ctx, timestamp)

@spec end_span(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  timestamp :: non_neg_integer()
) :: :ok

SDK (Noop implementation) — end_span/2 discards the end signal silently (trace/api.md L862-L863).

record_exception(span_ctx, exception, stacktrace, attributes)

@spec record_exception(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  exception :: Exception.t(),
  stacktrace :: list(),
  attributes :: %{required(String.t()) => primitive_any()}
) :: :ok

SDK (Noop implementation) — record_exception/4 discards the exception event silently (trace/api.md L862-L863).

recording?(span_ctx)

@spec recording?(span_ctx :: Otel.API.Trace.SpanContext.t()) :: boolean()

SDK (Noop implementation) — recording?/1 always returns false (trace/api.md L862-L863).

set_attribute(span_ctx, key, value)

@spec set_attribute(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  key :: String.t(),
  value :: primitive_any()
) :: :ok

SDK (Noop implementation) — set_attribute/3 discards the attribute silently (trace/api.md L862-L863).

set_attributes(span_ctx, attributes)

@spec set_attributes(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  attributes :: %{required(String.t()) => primitive_any()}
) :: :ok

SDK (Noop implementation) — set_attributes/2 discards the attribute map silently (trace/api.md L862-L863).

set_status(span_ctx, status)

@spec set_status(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  status :: Otel.API.Trace.Status.t()
) :: :ok

SDK (Noop implementation) — set_status/2 discards the status silently (trace/api.md L862-L863).

update_name(span_ctx, name)

@spec update_name(
  span_ctx :: Otel.API.Trace.SpanContext.t(),
  name :: String.t()
) :: :ok

SDK (Noop implementation) — update_name/2 discards the name change silently (trace/api.md L862-L863).