Otel.Logs.LogRecord (otel v0.4.1)

Copy Markdown View Source

LogRecord data model (logs/data-model.md §"Log and Event Record Definition" L155-L451; Status: Stable).

Represents a single log record flowing through the Logs API. Sibling to Otel.Logs.Logger — the Logger emits LogRecords (api.md L101), consistent with the spec's treatment of the two as peer concepts across api.md and data-model.md.

The struct mirrors the OTLP wire format: field defaults match the proto3 zero values for fixed64 *_unix_nano, SEVERITY_NUMBER_UNSPECIFIED, string, and repeated KeyValue. Nothing needs a || default fallback downstream — the struct IS the default.

Public API

Function / TypeRole
t/0Application (data model) — LogRecord struct type

Construct via Otel.Logs.LogRecord.new/1 — the canonical constructor that fills proto3-aligned defaults plus runtime-derived scope / resource. The defstruct declares only field names; defaults live exclusively in new/1 so all initialization flows through one place.

Field defaults — proto3-aligned

FieldDefaultBasis
timestamp0proto fixed64; logs.proto L141 "Value of 0 indicates unknown or missing timestamp"
observed_timestamp0proto fixed64; logs.proto L158 same language. SDK fills with current time at emit per proto MUST (L149)
severity_number0proto SeverityNumber enum; logs.proto L88 SEVERITY_NUMBER_UNSPECIFIED = 0; data-model.md L271 "MAY represent unspecified"
severity_text""proto string; logs.proto L167 "[Optional]"
bodynilproto AnyValue message type — proto3 messages use presence tracking; Elixir nil ≡ absent. Spec common.md L50 explicitly permits nil as a valid AnyValue ("empty value if supported by the language") — body: nil conflates "missing" and "null-as-AnyValue", but both mean the same thing to downstream processors and wire format
attributes%{}proto repeated KeyValue; empty map ≡ empty repeated after encoding
event_name""proto string; logs.proto L221 "Presence of event_name identifies this record as an event" — empty = non-Event
trace_id0proto bytes (16 bytes, all zeros = invalid); data-model.md §Field TraceId; logs.proto L199-L204. Populated by the SDK from the resolved Context per spec L208-L213
span_id0proto bytes (8 bytes, all zeros = invalid); data-model.md §Field SpanId; logs.proto L206-L211. Same SDK handling as trace_id
trace_flags0proto fixed32; data-model.md §Field TraceFlags; logs.proto L213. Sampled bit (0x01) per W3C Trace Context
exceptionnilNot in proto LogRecord; API-layer MAY-accepted field per api.md L131. SDK converts to exception.* attributes

nil appears as a default only for body (spec-permitted AnyValue null) and exception (sidecar sentinel). All other fields use proto3 zero-values, which are correctly distinguished by consumers as "missing" per the proto comments cited above.

Trace context fields

trace_id, span_id, trace_flags are LogRecord fields per data-model.md §Field TraceId / SpanId / TraceFlags (sections covered by L208-L232) and proto logs.proto L199-L213. They are present on the struct for data-model parity with the wire format and the SDK LogRecord — the SDK populates the SDK-side LogRecord from the resolved Otel.Ctx.t/0 per spec L208-L213 ("trace context fields MUST be populated from the resolved Context (either the explicitly passed Context or the current Context)"), not from these input fields. Callers do not need to set them and the SDK ignores any value supplied here.

References

  • OTel Logs Data Model: opentelemetry-specification/specification/logs/data-model.md
  • OTel Logs API §Emit a LogRecord: opentelemetry-specification/specification/logs/api.md L111-L131
  • OTLP proto LogRecord: opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto L136-L226
  • OTLP proto AnyValue nil: opentelemetry-proto/opentelemetry/proto/common/v1/common.proto L25-L53

Summary

Types

t()

A LogRecord — the data model flowing through the Logs API.

Functions

Application — Construct a LogRecord. Proto3 zero-value defaults plus runtime-derived scope / resource are applied; caller may override any field via opts.

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()}

t()

@type t() :: %Otel.Logs.LogRecord{
  attributes: %{required(String.t()) => primitive_any()},
  body: primitive_any(),
  dropped_attributes_count: non_neg_integer(),
  event_name: String.t(),
  exception: Exception.t() | nil,
  observed_timestamp: non_neg_integer(),
  resource: Otel.Resource.t(),
  scope: Otel.InstrumentationScope.t(),
  severity_number: Otel.Logs.severity_number(),
  severity_text: Otel.Logs.severity_level(),
  span_id: Otel.Trace.SpanId.t(),
  timestamp: non_neg_integer(),
  trace_flags: Otel.Trace.SpanContext.trace_flags(),
  trace_id: Otel.Trace.TraceId.t()
}

A LogRecord — the data model flowing through the Logs API.

Fields mirror data-model.md §"Log and Event Record Definition" L155-L451 plus the MAY-accepted exception sidecar from api.md L131.

Construct via new/1 to apply spec-aligned defaults (see module doc's Field defaults table). Direct %Otel.Logs.LogRecord{} literals leave every field as nil and are only suitable for pattern matches, never for emission.

Functions

new(opts \\ %{})

@spec new(opts :: map()) :: t()

Application — Construct a LogRecord. Proto3 zero-value defaults plus runtime-derived scope / resource are applied; caller may override any field via opts.