zerodds-observability-otlp v1.0 — OTLP/HTTP/JSON exporter — Spec coverage

Source: docs/specs/zerodds-observability-otlp-1.0.md (ZeroDDS vendor spec, OTLP/HTTP/JSON exporter, modelled on OpenTelemetry proto v1.4).

Context: crates/observability-otlp buffers traces/histograms/logs and pushes them as OTLP/HTTP/JSON to an OTel collector. Own Span/Histogram/ Event types (no dependency cycle to zerodds-monitor); 8 tests green.

Implementation:


§1 Architecture — buffer + flush

Spec: §1, “Architektur” — the exporter buffers telemetry and pushes it periodically / on flush() to an OTLP/HTTP/JSON collector; no collector = no panic.

Repo: crates/observability-otlp/src/lib.rs (OtlpExporter, ExporterBuffers).

Tests: crates/observability-otlp/src/lib.rs::tests::flush_drains_buffers_even_with_no_collector.

Status: done

§2.1 Endpoint /v1/traces

Spec: §2.1 — spans/events are sent as OTLP trace JSON to /v1/traces; spec-conformant string escaping.

Repo: crates/observability-otlp/src/lib.rs (add_span, add_event, trace JSON builder).

Tests: crates/observability-otlp/src/lib.rs::tests::traces_json_roundtrip_shape, json_escape_handles_quotes_and_newlines.

Status: done

§2.2 Endpoint /v1/metrics

Spec: §2.2 — histograms are sent as OTLP metric JSON to /v1/metrics.

Repo: crates/observability-otlp/src/lib.rs (add_histogram, metric JSON builder).

Tests: crates/observability-otlp/src/lib.rs::tests::metrics_json_roundtrip_shape.

Status: done

§2.3 Endpoint /v1/logs

Spec: §2.3 — structured logs are sent as OTLP log JSON to /v1/logs.

Repo: crates/observability-otlp/src/lib.rs (log JSON builder).

Tests: crates/observability-otlp/src/lib.rs::tests::logs_json_roundtrip_shape.

Status: done

§3 Configuration

Spec: §3, “Konfiguration” — OtlpConfig with a collector endpoint (default localhost) and exporter parameters.

Repo: crates/observability-otlp/src/lib.rs (OtlpConfig).

Tests: crates/observability-otlp/src/lib.rs::tests::config_default_points_to_localhost.

Status: done

§4 Lifecycle + HTTP error handling

Spec: §4, “Lifecycle” — flush() drains the buffers; an HTTP error status is reported as ExportError::HttpStatus, connect-refused as ExportError::Io — no panic.

Repo: crates/observability-otlp/src/lib.rs (flush, ExportError, HTTP status parser).

Tests: crates/observability-otlp/src/lib.rs::tests::flush_drains_buffers_even_with_no_collector, parse_http_status_extracts_code, parse_http_status_handles_500.

Status: done

§5 Bridge to zerodds-monitor::Registry

Spec: §5 — the caller exports via Registry::snapshot(); the exporter takes Histogram instances directly. Counter/gauge go through Prometheus only, by design (no OTLP double-export).

Repo: crates/observability-otlp/src/lib.rs (add_histogram = ingestion point for the caller-side snapshot bridge; deliberately no zerodds-monitor dependency, to avoid a cycle).

Tests: crates/observability-otlp/src/lib.rs::tests::metrics_json_roundtrip_shape.

Status: partial — histogram export and the caller-side snapshot bridge are built and checked; counters and gauges go only through Prometheus by design decision, the OTLP export for them is missing (§5.1).

§5.1 Counters and gauges over OTLP

Spec: §5 — “counters/gauges are currently not exported via OTLP — they only go through Prometheus” (design decision).

Repo: —

Tests: —

Status: open — OtlpExporter accepts only Histogram (add_histogram); OTLP Sum and Gauge data points are missing.

§6 Security

Spec: §6 — TLS is out-of-scope for the built-in HTTP/1.1 stub (the caller runs a local OTel collector sidecar with a TLS frontend); authentication headers are a major-additive extension.

Repo: —

Tests: —

Status: open — the built-in HTTP/1.1 export speaks no TLS and sets no authentication headers; the spec delegates TLS to a collector sidecar.

§7 Stability

Spec: §7 — public API stable; wire format modelled on OTel v1.4, schema change = major bump.

Repo: —

Tests: —

Status: n/a (informative) — stability commitment, not a property of the export.

Non-goal — OTLP/gRPC

Spec: Non-goals — “gRPC encoding (OTLP/gRPC) — deliberately left out, because it requires a Protobuf codegen pipeline. An add-on zerodds-observability-otlp-grpc is possible in future”.

Repo: —

Tests: —

Status: open — there is only OTLP/HTTP with JSON; OTLP/gRPC is missing.

§8 Test obligation

Spec: §8 — mandatory: config→JSON roundtrip smoke test, HTTP 500 error handling (ExportError::HttpStatus), connect-refused without panic.

Repo: crates/observability-otlp/src/lib.rs (test module).

Tests: crates/observability-otlp/src/lib.rs::tests::config_default_points_to_localhost, parse_http_status_handles_500, flush_drains_buffers_even_with_no_collector, traces_json_roundtrip_shape, metrics_json_roundtrip_shape, logs_json_roundtrip_shape.

Status: done


Audit status

7 done / 1 partial / 3 open / 0 blocked / 1 n/a (informative).

Test run: cargo test -p zerodds-observability-otlp — 8 tests green, 0 failed.

Open items: zerodds-observability-otlp-1.0.open.en.md.

zerodds-observability-otlp v1.0 — OTLP/HTTP/JSON-Exporter — Spec-Coverage

Quelle: docs/specs/zerodds-observability-otlp-1.0.md (ZeroDDS-Vendor-Spec, OTLP/HTTP/JSON-Exporter, an OpenTelemetry-Proto v1.4 angelehnt).

Kontext: crates/observability-otlp puffert Traces/Histogramme/Logs und pusht sie als OTLP/HTTP/JSON an einen OTel-Collector. Eigene Span/Histogram/ Event-Typen (kein Dep-Zyklus zu zerodds-monitor); 8 Tests grün.

Implementation:


§1 Architektur — Puffer + Flush

Spec: §1, „Architektur” — Exporter puffert Telemetrie und pusht sie periodisch/per flush() an einen OTLP/HTTP/JSON-Collector; kein Collector = kein Panic.

Repo: crates/observability-otlp/src/lib.rs (OtlpExporter, ExporterBuffers).

Tests: crates/observability-otlp/src/lib.rs::tests::flush_drains_buffers_even_with_no_collector.

Status: done

§2.1 Endpoint /v1/traces

Spec: §2.1 — Spans/Events werden als OTLP-Trace-JSON an /v1/traces gesendet; String-Escaping spec-konform.

Repo: crates/observability-otlp/src/lib.rs (add_span, add_event, Trace-JSON-Builder).

Tests: crates/observability-otlp/src/lib.rs::tests::traces_json_roundtrip_shape, json_escape_handles_quotes_and_newlines.

Status: done

§2.2 Endpoint /v1/metrics

Spec: §2.2 — Histogramme werden als OTLP-Metric-JSON an /v1/metrics gesendet.

Repo: crates/observability-otlp/src/lib.rs (add_histogram, Metric-JSON-Builder).

Tests: crates/observability-otlp/src/lib.rs::tests::metrics_json_roundtrip_shape.

Status: done

§2.3 Endpoint /v1/logs

Spec: §2.3 — strukturierte Logs werden als OTLP-Log-JSON an /v1/logs gesendet.

Repo: crates/observability-otlp/src/lib.rs (Log-JSON-Builder).

Tests: crates/observability-otlp/src/lib.rs::tests::logs_json_roundtrip_shape.

Status: done

§3 Konfiguration

Spec: §3, „Konfiguration” — OtlpConfig mit Collector-Endpoint (Default localhost) und Exporter-Parametern.

Repo: crates/observability-otlp/src/lib.rs (OtlpConfig).

Tests: crates/observability-otlp/src/lib.rs::tests::config_default_points_to_localhost.

Status: done

§4 Lifecycle + HTTP-Fehlerbehandlung

Spec: §4, „Lifecycle” — flush() leert die Puffer; HTTP-Fehlerstatus wird als ExportError::HttpStatus gemeldet, Connect-Refused als ExportError::Io — kein Panic.

Repo: crates/observability-otlp/src/lib.rs (flush, ExportError, HTTP-Status-Parser).

Tests: crates/observability-otlp/src/lib.rs::tests::flush_drains_buffers_even_with_no_collector, parse_http_status_extracts_code, parse_http_status_handles_500.

Status: done

§5 Bridge zu zerodds-monitor::Registry

Spec: §5 — der Caller exportiert via Registry::snapshot(); der Exporter nimmt Histogram-Instanzen direkt. Counter/Gauge laufen per Designentscheidung nur über Prometheus (kein OTLP-Doppel-Export).

Repo: crates/observability-otlp/src/lib.rs (add_histogram = Ingestions- Punkt für den caller-seitigen Snapshot-Bridge; bewusst kein Dep auf zerodds-monitor, um einen Zyklus zu vermeiden).

Tests: crates/observability-otlp/src/lib.rs::tests::metrics_json_roundtrip_shape.

Status: partial — Histogramm-Export und die aufrufseitige Snapshot-Brücke sind gebaut und geprüft; Counter und Gauge gehen laut Designentscheidung nur über Prometheus, der OTLP-Export dafür fehlt (§5.1).

§5.1 Counter und Gauge über OTLP

Spec: §5 — „counters/gauges are currently not exported via OTLP — they only go through Prometheus“ (Designentscheidung).

Repo: —

Tests: —

Status: open — OtlpExporter nimmt nur Histogram an (add_histogram); OTLP-Sum- und Gauge-Datenpunkte fehlen.

§6 Sicherheit

Spec: §6 — TLS ist out-of-scope für den built-in HTTP/1.1-Stub (Caller setzt einen lokalen OTel-Collector-Sidecar mit TLS-Frontend); Authentication-Header sind eine Major-additive Erweiterung.

Repo: —

Tests: —

Status: open — der eingebaute HTTP/1.1-Export spricht kein TLS und setzt keine Authentifizierungs-Header; die Spec verweist TLS an einen Collector-Sidecar.

§7 Stabilität

Spec: §7 — Public-API stabil; Wire-Format an OTel-v1.4 angelehnt, Schema-Änderung = Major-Bump.

Repo: —

Tests: —

Status: n/a (informative) — Stabilitätszusage, keine Eigenschaft des Exports.

Nicht-Ziel — OTLP/gRPC

Spec: Nicht-Ziele — „gRPC encoding (OTLP/gRPC) — deliberately left out, because it requires a Protobuf codegen pipeline. An add-on zerodds-observability-otlp-grpc is possible in future“.

Repo: —

Tests: —

Status: open — es gibt nur OTLP/HTTP mit JSON; OTLP/gRPC fehlt.

§8 Test-Pflicht

Spec: §8 — verpflichtend: Config→JSON-Roundtrip-Smoketest, HTTP-500-Fehlerbehandlung (ExportError::HttpStatus), Connect-Refused ohne Panic.

Repo: crates/observability-otlp/src/lib.rs (Test-Modul).

Tests: crates/observability-otlp/src/lib.rs::tests::config_default_points_to_localhost, parse_http_status_handles_500, flush_drains_buffers_even_with_no_collector, traces_json_roundtrip_shape, metrics_json_roundtrip_shape, logs_json_roundtrip_shape.

Status: done


Audit-Status

7 done / 1 partial / 3 open / 0 blocked / 1 n/a (informative).

Test-Lauf: cargo test -p zerodds-observability-otlp — 8 Tests grün, 0 failed.

Offene Punkte: zerodds-observability-otlp-1.0.open.md.