Skip to content

Add optional in-VM OTLP telemetry export sink#303

Draft
archandatta wants to merge 11 commits into
mainfrom
hypeship/otlp-telemetry-sink
Draft

Add optional in-VM OTLP telemetry export sink#303
archandatta wants to merge 11 commits into
mainfrom
hypeship/otlp-telemetry-sink

Conversation

@archandatta

@archandatta archandatta commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds an optional in-VM OTLP/HTTP export sink that converts browser telemetry events into OTLP log records and forwards them to a configured endpoint (an OTLP relay/collector), running alongside the existing S2 sink. Gated on OTLP_RELAY_ENDPOINT — no behavior change when unset.
  • Converter maps each telemetry envelope to an OTLP log record: event type → EventName (also mirrored to a kernel.event.type attribute for backends that drop EventName), structured JSON body, derived severity, and kernel.* attributes. High-value network/console fields are promoted to semantic-convention attributes (http.response.status_code, url.full, http.request.method). Screenshot/monitor categories are excluded from export.
  • Sink mirrors S2StorageWriter: an independent ring reader feeds records through the OTel log SDK (otlploghttp + batch processor). Runs independently of S2 (both can be enabled). Export failures are surfaced via a logging exporter wrapper (the SDK otherwise reports them only through an uninstalled global logger).

Testing

  • Unit tests for the converter (field mapping, severity, structured body, promoted attributes, category exclusion) and an end-to-end sink test that decodes the exported OTLP payload and asserts an excluded category never reaches the receiver.
  • Validated locally against otelcol-contrib (config under server/dev/otelcol/), including a real headless-Chromium CDP run confirming live events convert and export correctly.
  • go build ./..., go vet, and the events test suite pass.

Notes

  • Draft: the export sink is gated off by default and depends on a reachable OTLP relay endpoint in production; not yet wired into deploy config.
  • Delivery-substrate benchmarking (relay vs a durable server-side pusher) lives on a separate branch, hypeship/otlp-substrate-bench, to keep this PR reviewable in isolation.

Pure mapping from telemetry envelopes to OTLP log records: event type to
EventName, structured JSON body, severity, and kernel.* attributes. Excludes
screenshot/monitor categories from export.
Mirrors S2StorageWriter: reads the event stream via an independent ring reader
and exports records over OTLP/HTTP through the OTel log SDK. Configurable
endpoint, path, headers, and resource attributes; drops excluded categories
and oversized envelopes.
Adds OTLP_RELAY_* config and starts the OTLP storage writer at boot when an
endpoint is set, alongside the existing S2 sink, with matching graceful
shutdown. JWT is redacted in logs.
Receives OTLP/HTTP on :4318 and prints decoded records to stdout for local
validation of the telemetry export path.
EventName is dropped by some backends (Datadog, Loki), and a structured body
is only flattened by some (Honeycomb), so mirror the event type into
kernel.event.type and lift high-value network/console fields into queryable
attributes using semantic-convention names. Full payload stays in the body.
Envelopes are already capped at ~1MB at publish, so a 4MB per-record check
could never fire. Removes the dead guard, its drop counter, and the unused
storage logger.
Substrate-independent harness: a measurement OTLP receiver (record count,
end-to-end lag p50/p99, bytes, slow-upstream delay) and a relay-shape load
driver (light/heavy profiles at a target rate) feeding the shared converter.
Reused unchanged by the server-side substrates; only the driver differs.
The Temporal and claim-goroutine substrates share the relay's convert/batch/POST
hot path but add an S2 read hop. The knob injects that hop so end-to-end lag can
be compared against the relay baseline.
Adds a durable-pusher mode (unbounded log + resumable cursor) and a delivery
outage knob, plus unique-record counting in the receiver, so the relay's
best-effort loss can be measured head-to-head against at-least-once recovery.
@socket-security

socket-security Bot commented Jul 2, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: golang golang.org/x/tools is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?golang/go.opentelemetry.io/proto/otlp@v1.10.0golang/github.com/s2-streamstore/s2-sdk-go@v0.16.1golang/github.com/nrednav/cuid2@v1.1.0golang/github.com/docker/go-connections@v0.6.0golang/github.com/samber/lo@v1.52.0golang/github.com/testcontainers/testcontainers-go@v0.40.0golang/golang.org/x/tools@v0.44.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore golang/golang.org/x/tools@v0.44.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Wraps the exporter to log delivery failures (the SDK otherwise reports them
only through an uninstalled global logger, so loss was silent). Removes the
unused MaxBatchRecords knob, omits empty resource attributes, logs the two
missing OTLP config fields, decodes the exported payload in the sink test to
prove category exclusion, and notes the producer-schema tie in the converter.
The otlpbench rig (including the alternative-substrate durable-pusher model and
fault injection) is delivery-substrate exploration, not part of the in-VM
exporter. Moved to its own branch to keep this PR reviewable in isolation.
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