Otel.API.Logs.Logger behaviour (otel v0.2.0)

Copy Markdown View Source

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

FunctionRole
emit/2Application (OTel API MUST) — Emit via implicit context (L121-L123)
emit/3Application (OTel API MUST) — Emit via explicit context (L119-L121)
enabled?/2Application (OTel API SHOULD) — Enabled dispatch
@callback emit/3SDK (OTel API MUST) — Emit a LogRecord (L111-L131)
@callback enabled?/2SDK (OTel API SHOULD) — Enabled (L133-L154)

References

  • OTel Logs API §Logger: opentelemetry-specification/specification/logs/api.md L99-L155
  • OTel Logs API §Concurrency: opentelemetry-specification/specification/logs/api.md L167-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.

t()

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

enabled_opt()

@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 to Otel.API.Ctx.current/0 when 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).

enabled_opts()

@type enabled_opts() :: [enabled_opt()]

A keyword list of enabled_opt/0 values.

primitive()

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

primitive_any()

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

t()

@type t() :: {module(), term()}

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

emit(logger, ctx, log_record)

@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.

enabled?(logger, opts)

@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

emit(logger, log_record \\ %Otel.API.Logs.LogRecord{})

@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.

emit(logger, ctx, log_record)

@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.

enabled?(logger, opts \\ [])

@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.