Logger behaviour and dispatch facade (OTel
logs/api.md §Logger L99-L155; Status: Stable —
inherits the file-level Stable from logs/api.md L9, no
per-section carve-out remaining at v1.55.0).
A Logger emits LogRecords. It is represented as a
{module, config} tuple where module implements this
behaviour — the same pattern used by Otel.API.Trace.Tracer.
Per spec L188-L189 (trace) and by analogy for logs,
configuration (resource, log limits, processors) belongs to
the LoggerProvider, not the Logger itself; obtain a
Logger via Otel.API.Logs.LoggerProvider.get_logger/1
rather than constructing the tuple directly.
All functions are safe for concurrent use (spec L173-L174).
Public API
| Function | Role |
|---|---|
emit/2 | Application (OTel API MUST) — Emit via implicit context (L121-L123) |
emit/3 | Application (OTel API MUST) — Emit via explicit context (L119-L121) |
enabled?/2 | Application (OTel API SHOULD) — Enabled dispatch |
@callback emit/3 | SDK (OTel API MUST) — Emit a LogRecord (L111-L131) |
@callback enabled?/2 | SDK (OTel API SHOULD) — Enabled (L133-L154) |
References
- OTel Logs API §Logger:
opentelemetry-specification/specification/logs/api.mdL99-L155 - OTel Logs API §Concurrency:
opentelemetry-specification/specification/logs/api.mdL167-L176 - OTel Logs API No-Op:
opentelemetry-specification/specification/logs/noop.md(fallback when no SDK is installed)
Summary
Types
One option accepted by enabled?/2, per §Enabled
(logs/api.md L137-L142)
A keyword list of enabled_opt/0 values.
A logger value — a {module, config} tuple where module
implements the Otel.API.Logs.Logger behaviour and
config carries logger-specific configuration (resource,
log limits, processors, scope).
Callbacks
SDK (OTel API MUST) — "Emit a LogRecord"
(logs/api.md L111-L131).
SDK (OTel API SHOULD) — "Enabled" (logs/api.md
L133-L154; Status: Stable — inherits file-level
Stable from logs/api.md L9 at v1.55.0).
Functions
Application (OTel API MUST) — Emit a LogRecord using
the implicit (process-local) context (logs/api.md
L119-L123 "When implicit Context is supported, then this
parameter SHOULD be optional and if unspecified then MUST
use current Context").
Application (OTel API MUST) — Emit a LogRecord with
an explicit context (logs/api.md L119-L121).
Application (OTel API SHOULD) — Enabled dispatch
(logs/api.md L133-L154).
Types
@type enabled_opt() :: {:severity_number, Otel.API.Logs.severity_number()} | {:event_name, String.t()} | {:ctx, Otel.API.Ctx.t()}
One option accepted by enabled?/2, per §Enabled
(logs/api.md L137-L142):
:severity_number— severity the caller would emit (0..24, L141):event_name— event name the caller would emit (L142):ctx— evaluation context (L137-L140; defaults toOtel.API.Ctx.current/0when omitted)
Unlike Otel.API.Trace.Tracer.enabled_opt/0 which is left
open (keyword()) because the Trace spec does not define
common keys, Logs §Enabled enumerates these three keys at
the API level — enumeration is appropriate here because it
mirrors a spec contract, not an SDK assumption
(.claude/rules/code-conventions.md §Layer independence).
@type enabled_opts() :: [enabled_opt()]
A keyword list of enabled_opt/0 values.
@type primitive_any() :: primitive() | [primitive_any()] | %{required(String.t()) => primitive_any()}
A logger value — a {module, config} tuple where module
implements the Otel.API.Logs.Logger behaviour and
config carries logger-specific configuration (resource,
log limits, processors, scope).
Per spec L101-L102 configuration is the LoggerProvider's
responsibility; obtain a logger via
Otel.API.Logs.LoggerProvider.get_logger/1 rather than
constructing the tuple directly.
Callbacks
@callback emit( logger :: t(), ctx :: Otel.API.Ctx.t(), log_record :: Otel.API.Logs.LogRecord.t() ) :: :ok
SDK (OTel API MUST) — "Emit a LogRecord"
(logs/api.md L111-L131).
Emits the given log_record to the processing pipeline.
All fields of log_record are optional per L117-L131; the
empty struct %Otel.API.Logs.LogRecord{} is the "all
fields absent" form.
Per spec L119-L121 the ctx parameter is the Context
associated with the LogRecord. The API-layer dispatch
functions (emit/2, emit/3) handle the implicit /
explicit context split; this callback always receives an
explicit context.
@callback enabled?( logger :: t(), opts :: enabled_opts() ) :: boolean()
SDK (OTel API SHOULD) — "Enabled" (logs/api.md
L133-L154; Status: Stable — inherits file-level
Stable from logs/api.md L9 at v1.55.0).
Returns whether the logger is enabled for the supplied
opts. Per L148-L153 the returned value is not static
— it can change over time as configuration or sampling
state evolves. Instrumentation authors SHOULD call this
function each time before they
emit a LogRecord to have the most
up-to-date response.
opts keys are spec-defined (L137-L142): :ctx,
:severity_number, :event_name. The API-layer
dispatch (enabled?/2) fills in :ctx from the current
context when omitted per L137-L140.
Functions
@spec emit(logger :: t(), log_record :: Otel.API.Logs.LogRecord.t()) :: :ok
Application (OTel API MUST) — Emit a LogRecord using
the implicit (process-local) context (logs/api.md
L119-L123 "When implicit Context is supported, then this
parameter SHOULD be optional and if unspecified then MUST
use current Context").
Injects Otel.API.Ctx.current/0 as the context and
delegates to the Logger's emit/3 callback. log_record
defaults to %Otel.API.Logs.LogRecord{} — an empty
record with proto3 zero-value defaults for every field
— so all fields are truly optional at the call site.
@spec emit( logger :: t(), ctx :: Otel.API.Ctx.t(), log_record :: Otel.API.Logs.LogRecord.t() ) :: :ok
Application (OTel API MUST) — Emit a LogRecord with
an explicit context (logs/api.md L119-L121).
Delegates directly to the Logger's emit/3 callback
without context injection. Use when the caller wants a
specific ctx instead of the process-local current one.
@spec enabled?(logger :: t(), opts :: enabled_opts()) :: boolean()
Application (OTel API SHOULD) — Enabled dispatch
(logs/api.md L133-L154).
Delegates to the Logger's enabled?/2 callback after
ensuring :ctx is set. When opts does not supply
:ctx, the current context is injected per spec
L137-L140 "if unspecified then MUST use current
Context".
Per spec L148-L153 the result is not static — it reflects sampling/configuration state at the moment of call and may change over time. Instrumentation authors SHOULD call this each time before emitting to have the most up-to-date answer.