Skip to content

otlp export + obs.init for observability#450

Merged
kacy merged 1 commit into
mainfrom
feat/o11y-otlp
Jul 17, 2026
Merged

otlp export + obs.init for observability#450
kacy merged 1 commit into
mainfrom
feat/o11y-otlp

Conversation

@kacy

@kacy kacy commented Jul 17, 2026

Copy link
Copy Markdown
Owner

summary

phase 3 of the observability sprint: OTLP export and a one-call obs.init.

  • std.otlp encodes std.trace spans and std.metrics samples as OTLP
    protobuf (ExportTraceServiceRequest / ExportMetricsServiceRequest),
    hand-built on std.protobuf the way the db drivers hand-write their wire
    protocols, and POSTs them to an OTLP/HTTP collector at /v1/traces and
    /v1/metrics with content-type: application/x-protobuf.
  • std.obs init() reads the standard OTEL_* environment variables,
    turns tracing and metric collection on, and spawns a background exporter
    that periodically flushes finished spans and the current metric snapshot.
    with no OTEL_EXPORTER_OTLP_ENDPOINT set it does nothing, so the call is
    free to leave in.

public api:

  • otlp.target(service_name, endpoint, protocol) -> Target
  • otlp.encode_traces(service_name, spans) -> Bytes
  • otlp.encode_metrics(service_name, samples) -> Bytes
  • otlp.export_traces(target, spans) -> Bool / otlp.export_metrics(target, samples) -> Bool
  • obs.init(), obs.start(service_name, endpoint, protocol, metric_interval_ms, span_delay_ms), obs.active(), obs.shutdown()

scope

spans with string attributes and status, counter and gauge metrics in full,
histograms as a count+sum data point (per-bucket boundaries omitted — noted in
the code), OTLP/HTTP only (grpc fails with a clear message).

tested

  • pith test std/otlp.pith (6 tests): endpoint parsing plus reader round-trips
    of a trace request, a monotonic-sum counter with an int data point and its
    label attribute, and a histogram count+sum.
  • pith test std/obs.pith (3 tests): stays off with no endpoint, loop tick
    picks the smaller interval, empty endpoint is a no-op.
  • doc --check clean on both modules.
  • end-to-end: ran obs.init against a local stub collector that decodes the
    posted protobuf; it received /v1/traces (service.name + span name) and
    /v1/metrics (service.name + metric name) as expected.
  • make run-examples: 86 passed, 0 failed.

design notes

otlp.Target is named Target rather than Config to avoid a cross-module
struct-name clash with tls.Config (E219). histograms map to a
count+sum data point for v1; a fuller mapping with bucket boundaries can follow.

std.otlp encodes std.trace spans and std.metrics samples as OTLP protobuf
(ExportTraceServiceRequest / ExportMetricsServiceRequest, hand-built on
std.protobuf) and POSTs them to an OTLP/HTTP collector at /v1/traces and
/v1/metrics. std.obs.init reads the standard OTEL_* environment variables,
turns tracing and metric collection on, and spawns a background exporter that
periodically flushes spans and the current metric snapshot. one call wires up
observability; with no endpoint configured it stays off.

scope for this pass: spans with string attributes and status, counter and
gauge metrics in full, histograms as a count+sum data point (per-bucket detail
omitted), OTLP/HTTP transport only (grpc fails with a clear message).

tested:
- pith test std/otlp.pith (6 tests): endpoint parsing, and round-trips of a
  trace request, a monotonic-sum counter with an int data point and its label
  attribute, and a histogram count+sum, all decoded back with protobuf.reader.
- pith test std/obs.pith (3 tests): init stays off with no endpoint, the loop
  tick picks the smaller interval, an empty endpoint is a no-op.
- doc --check clean on both modules.
- end-to-end: ran obs.init against a local stub collector that decodes the
  posted protobuf; the stub received /v1/traces (service.name + span name) and
  /v1/metrics (service.name + metric name) as expected.
- make run-examples: 86 passed, 0 failed (no regression).
@kacy
kacy merged commit ee91911 into main Jul 17, 2026
2 checks passed
@kacy
kacy deleted the feat/o11y-otlp branch July 17, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant