Otel.Ctx (otel v0.4.1)

Copy Markdown View Source

OTel Context (spec context/README.md, Status: Stable).

A propagation mechanism that carries execution-scoped values across API boundaries within a single process. Cross-cutting concerns (Trace, Baggage, …) store their values in the Context.

The Context type t/0 is @opaque — construct via new/0 and read/write only through the public API. The three spec-mandated operations (create_key/1, get_value/2, set_value/3) are pure and take a Context as an explicit argument. The three optional global operations (current/0, attach/1, detach/1) manage the "current" ambient Context via the process dictionary, as required for implicit-style usage (Elixir). Two convenience wrappers (get_value/1, set_value/2) read and write through the current Context for call sites that prefer the implicit form.

Values stored in the current Context are only visible to the current process. Callers that want "return default when key is missing" semantics compose get_value(...) || default at the call site.

Public API

FunctionRole
create_key/1, get_value/2, set_value/3Application (OTel API MUST) — core Context ops (L56-L92)
current/0, attach/1, detach/1Application (OTel API SHOULD) — optional global ops (L95-L136)
new/0Application (Convenience) — build an empty Context

References

  • OTel Context: opentelemetry-specification/specification/context/README.md

Summary

Types

A context key (spec context/README.md §Create a key, L63-L67).

t()

An opaque OTel Context (spec context/README.md §Overview).

A context value. Any Erlang term.

Functions

Application (OTel API SHOULD) — "Attach Context" (context/README.md L105-L117, optional global operation).

Application (OTel API MUST) — "Create a key" (context/README.md L56-L67).

Application (OTel API SHOULD) — "Get current Context" (context/README.md L101-L103, optional global operation).

Application (OTel API SHOULD) — "Detach Context" (context/README.md L119-L136, optional global operation).

Application (OTel API MUST) — "Get value" (context/README.md L69-L79).

Application (Convenience) — build an empty Context.

Application (OTel API MUST) — "Set value" (context/README.md L81-L92).

Types

key()

@type key() :: term()

A context key (spec context/README.md §Create a key, L63-L67).

Per spec "The key name exists for debugging purposes and does not uniquely identify the key". In BEAM the caller-supplied term itself serves as the key — typically an atom or a {module, name} tuple. Callers that need runtime uniqueness are expected to supply it themselves (e.g. {__MODULE__, make_ref()}).

t()

@opaque t()

An opaque OTel Context (spec context/README.md §Overview).

The internal representation (a plain Elixir map) is not part of the public contract — construct with new/0 and access only through the public API. Per spec "A Context MUST be immutable, and its write operations MUST result in the creation of a new Context"; set_value/3 returns a new Context and leaves the input unchanged.

attach/1 returns a value of this type that serves as the Token per spec L113 — pass it to detach/1 to restore the previous Context. Treat attach-returned values as opaque tokens; do not inspect their contents.

value()

@type value() :: term()

A context value. Any Erlang term.

Functions

attach(ctx)

@spec attach(ctx :: t()) :: t()

Application (OTel API SHOULD) — "Attach Context" (context/README.md L105-L117, optional global operation).

Associates ctx with the current process and returns the previous Context, which can be passed to detach/1 as a token per spec L113. On the first attach in a process, the previous Context is normalized from nil to an empty Context so that the returned token is always a valid Context value.

Treat the returned value as an opaque token — do not inspect it.

create_key(name)

@spec create_key(name :: term()) :: key()

Application (OTel API MUST) — "Create a key" (context/README.md L56-L67).

Returns the given name unchanged as a context key.

The spec requires CreateKey to accept a name and return an opaque object representing the key. In BEAM the caller-supplied term (typically an atom or a {module, name} tuple) is already a suitable key, so this returns it verbatim. Callers who need runtime uniqueness are expected to supply it themselves (e.g. {__MODULE__, make_ref()}).

current()

@spec current() :: t()

Application (OTel API SHOULD) — "Get current Context" (context/README.md L101-L103, optional global operation).

Returns the current process's Context, or a fresh empty Context when nothing is attached. Used by SDK components and instrumentation libraries to read the ambient Context. End-user code typically reads domain values through higher-level APIs (Otel.Baggage.current/0, Otel.Trace.current_span/0) rather than calling this directly.

detach(ctx)

@spec detach(ctx :: t()) :: :ok

Application (OTel API SHOULD) — "Detach Context" (context/README.md L119-L136, optional global operation).

Restores the previous Context from a token returned by attach/1. Returns :ok.

Per spec L124-L129 an implementation MAY detect wrong-order detach calls and emit a signal. This implementation does not — the clause is a spec MAY (optional), and .claude/rules/code-conventions.md §No SHOULD-level diagnostics directs us to skip diagnostic emissions that the spec does not mandate. opentelemetry-erlang happens to take the same approach.

get_value(ctx, key)

@spec get_value(ctx :: t(), key :: key()) :: value()

Application (OTel API MUST) — "Get value" (context/README.md L69-L79).

Returns the value in ctx for key, or nil when the key is not present. Callers who want a default value compose || default at the call site.

new()

@spec new() :: t()

Application (Convenience) — build an empty Context.

Returns a fresh empty Context. Preferred over %{} at external call sites because t/0 is opaque.

set_value(ctx, key, value)

@spec set_value(ctx :: t(), key :: key(), value :: value()) :: t()

Application (OTel API MUST) — "Set value" (context/README.md L81-L92).

Returns a new Context with key mapped to value. The spec requires immutability — the input ctx is unchanged.