feat(metrics-sidecar): OTLP-logs exporter for webrtc.* events (FU #28) #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/otlp-logs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Wave 2 A4 closeout follow-up. The
chromeless-metrics-sidecarnowforwards every
chromeless.webrtc.*dot-named event to OTLP-logs inparallel to the existing Prometheus counter increments — closing the
gap flagged at the end of A4 (Triform's event bus / activity feed
needs the dot-named stream verbatim, not a Prometheus rollup).
This PR is based on
feat/wave-1-emitters(the open PR #1 head) soA4's
/webrtc-eventendpoint exists in the diff base. After PR #1merges, the base branch will rebase to
mainautomatically.What changed
otlp_logs.go—OTLPLoggerstruct with the same env-gated,no-op-stub shape as
tracing.go. ReadsOTEL_EXPORTER_OTLP_ENDPOINT(or the signal-specific
OTEL_EXPORTER_OTLP_LOGS_ENDPOINToverride),plus
OTEL_EXPORTER_OTLP_HEADERS, TLS, compression, timeout via theOTel SDK's standard env-var contract. Endpoint unset → no-op stub
that drops
Emit+Shutdowncleanly. Uses HTTP transport (/v1/logs)since SigNoz / OTel collectors ship both gRPC and HTTP on the same
listener and HTTP is the more portable default.
webrtc_handler.go—applyWebRTCEventandwebrtcEventHandlertake an
*OTLPLoggerand callotlp.Emit(event, attrs)alongsidethe existing Prometheus counter increment for every envelope.
element_idis stamped on the OTLP attrs so consumers don't have tore-derive it.
main.go— wiresnewOTLPLoggernext toinitTracing, deferredShutdownon graceful exit, passes the logger into the handler factory.go.mod/go.sum— addsotlplog/otlploghttp v0.8.0,log v0.8.0,sdk/log v0.8.0. The v0.8.0 minor pairs cleanly with the existingotel v1.32.0core; same Go 1.22 baseline.Test plan
go build ./...cleango vet ./...cleango test ./...— 27/27 passing (22 existing + 5 new)OTEL_EXPORTER_OTLP_ENDPOINTunset,
/metricsserves pre-registered series,/webrtc-eventaccepts events (HTTP 204), counters increment correctly, no
goroutine leaks, clean shutdown.
endpoint set, confirm
chromeless.webrtc.*records appear in SigNoz(Logs view filtered by
service.name = chromeless-metrics-sidecar).New tests added
TestOTLPLogger_NoOpWhenEnvUnset— env unset path produces a stubwhose
Emit/Shutdownare safe no-ops.TestOTLPLogger_NilReceiverIsSafe— typed-nil receivers don't panic.TestOTLPLogger_EmitsRecordWithBodyAndAttrs— body + severity +attribute round-trip via in-memory exporter.
TestOTLPLogger_DropsEmptyEvent— empty event string is dropped atthe exporter (mirrors handler-side guard).
TestWebRTCEventHandler_ForwardsToOTLP— cross-cutting wiring checkthat an
applyWebRTCEventcall drives both Prometheus and OTLP.Deploy-side env config
Production deploys (chromeless pod, dev or wtf) should set:
— typically the in-cluster collector that already terminates traces
(
tracing.go's OTLP-gRPC path). The logs path uses HTTP and will hit<endpoint>/v1/logsautomatically per the OTel SDK contract. Auth /TLS via the standard
OTEL_EXPORTER_OTLP_HEADERSandOTEL_EXPORTER_OTLP_LOGS_INSECUREenvs.Constraint compliance
webrtc_handler.go— the OTLPEmitis one extra line per event,plus a small attr-merge block at the top of
applyWebRTCEvent.webrtcEventHandler(...)factory call sites updated to passnilfor the OTLP logger argument.tracing.goexactly so deploy configs use thesame shape.
Closes the gap flagged at the end of Wave 2 A4: the dot-named WebRTC events POSTed to /webrtc-event were incrementing Prometheus counters but never reaching Triform's event bus / activity feed because the sidecar had only an OTLP-trace exporter (tracing.go) and Prometheus scrape — no OTLP-logs path. Adds: - otlp_logs.go — OTLPLogger struct with the same env-gated, no-op-stub shape as tracing.go. Reads OTEL_EXPORTER_OTLP_ENDPOINT (and the signal-specific OTEL_EXPORTER_OTLP_LOGS_ENDPOINT override) plus OTEL_EXPORTER_OTLP_HEADERS / TLS / compression / timeout via the OTel SDK's standard env-var contract. When endpoint is unset, construction returns a non-nil stub that drops Emit + Shutdown cleanly — dev compose without a collector pays no wire cost. - otlp_logs_test.go — 5 tests (no-op-on-unset-env path, nil-receiver safety, body+attribute round-trip via in-memory exporter, empty-event drop, and the cross-cutting wiring check that /webrtc-event drives both Prometheus + OTLP). Modifies: - webrtc_handler.go — applyWebRTCEvent + webrtcEventHandler take an *OTLPLogger and Emit(event, attrs) for every envelope, in parallel to the existing Prometheus counter increments. element_id is stamped onto the OTLP attrs so consumers can filter without re-deriving it. - main.go — wires newOTLPLogger alongside initTracing, deferred Shutdown on graceful exit, passes the logger into webrtcEventHandler. - go.mod / go.sum — adds otlplog/otlploghttp v0.8.0, log v0.8.0, sdk/log v0.8.0 (the v0.8.0 versions pair cleanly with the existing otel v1.32.0; same go 1.22 baseline as signaling/go.mod). Verification: go build ./... passes go vet ./... clean go test ./... 27/27 pass (22 existing + 5 new) Smoke run with OTEL_EXPORTER_OTLP_ENDPOINT unset: sidecar starts, /metrics serves pre-registered series, /webrtc-event accepts events with HTTP 204, counters increment correctly, no goroutine leaks, process shuts down cleanly. Deploy-side env config: production should set OTEL_EXPORTER_OTLP_ENDPOINT=<signoz-collector-url> on the chromeless pod (typically the in-cluster SigNoz / OTel collector that already terminates traces). The sidecar uses HTTP for logs (vs gRPC for traces) because /v1/logs is the OTel default and SigNoz collectors ship both protocols on the same listener. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>b2a63684e1ec82d79694