Logs export pipeline — timer-driven take from
LogRecordStorage + OTLP encode + HTTP POST. Single GenServer
collapsing what was previously a separate LogRecordProcessor
(queue + timer + drain) plus a passive HTTP-only Exporter.
Lifecycle
| Trigger | Action |
|---|---|
:loop self-message every @scheduled_delay_ms | take one batch (@max_export_batch_size) of records, encode, POST |
force_flush/1 | drain all records synchronously |
terminate/2 | drain remaining records before exit |
OTLP HTTP transport
POSTs OTLP/protobuf via Req.
User config is read from
Application.get_env(:otel, :req_options, []) on every export
and forwarded to Req.post/1 — anything Req accepts (TLS,
auth, timeouts, retry overrides, mock plugs) works.
The SDK only forces :body (the encoded protobuf). Defaults
via Keyword.put_new:
:base_url→http://localhost:4318if absent:url→/v1/logsif absent:retry→ predicate matching the OTLP-spec retryable response codes (opentelemetry-proto/docs/specification.mdL564-575: 429 / 502 / 503 / 504 SHOULD be retried, all other 4xx / 5xx MUST NOT) plus network-level exceptions. Backoff strategy (exponential + jitter) andRetry-Afterhonoring come from Req's default:retry_delay, which satisfies the spec MUST inopentelemetry-specification/specification/protocol/exporter.mdL182-202.content-type: application/x-protobufanduser-agentheaders merged into the user's:headers
:max_retries is left to Req's default (3 retries = 4
attempts) — the OTLP spec mandates the strategy but not a
specific attempt count.
References
- OTel Logs SDK §LogRecordProcessor:
opentelemetry-specification/specification/logs/sdk.mdL468-L545 - OTel Logs SDK §LogRecordExporter:
opentelemetry-specification/specification/logs/sdk.mdL546-L660 - OTLP retryable response codes:
opentelemetry-proto/docs/specification.mdL565-L573
Summary
Functions
Returns a specification to start this module under a supervisor.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec force_flush(timeout :: timeout()) :: :ok
@spec start_link(opts :: keyword()) :: GenServer.on_start()