Skip to content

feat(server): export gateway OCSF events as OTLP log records - #4500

Merged
krishicks merged 1 commit into
mainfrom
feat/4499-gateway-ocsf-otlp-logs/krishicks
Oct 14, 2026
Merged

krishicks merged 1 commit into
mainfrom
feat/4499-gateway-ocsf-otlp-logs/krishicks

Conversation

@krishicks

@krishicks krishicks commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Export the gateway's OCSF events as OTLP log records when [openshell.gateway.otlp.ocsf] sets enabled = true, so they reach a collector instead of only the local JSONL file. OTLP endpoints become configurable per signal, so OCSF events can go to a collector that feeds a SIEM while spans go elsewhere. This is the first part of #2892: gateway-produced events only. Supervisor events follow in later PRs.

Related Issue

Closes #4499
Refs #2892
Refs #3224 (close manually once #4500 and #4545 have both landed)

Changes

  • Per-signal OTLP config:

    [openshell.gateway.otlp]
    endpoint = "http://collector:4317"   # default for every signal; on its own still enables traces
    
    [openshell.gateway.otlp.traces]      # optional: send spans elsewhere
    endpoint = "http://traces:4317"
    
    [openshell.gateway.otlp.ocsf]
    enabled = true                       # OCSF export is off unless set
    endpoint = "http://siem:4317"        # optional; defaults to otlp.endpoint
    schema_version = "1.3"               # optional
    • Existing configs with only endpoint behave as before.
    • OCSF export needs enabled = true, which defaults to false like [mtls_auth] enabled. Enabling traces never sends OCSF events, and an [otlp.ocsf] table without the flag exports nothing.
    • OCSF-only export is possible by setting enabled = true and endpoint in [otlp.ocsf] alone.
    • [otlp.metrics] is rejected until OTLP metric export exists, and so is any enabled signal without an endpoint.
  • OTLP log export (openshell-otel/src/ocsf.rs):

    • Each gateway OCSF event becomes a log record with the OCSF JSON as its body, the event time, a severity mapped from severity_id, and ocsf.* and openshell.sandbox.id attributes.
    • schema_version optionally downgrades the exported JSON to OCSF 1.1 or 1.3.
  • Delivery:

    • Records pass through a queue bounded at 10,000 records and 16 MiB to the SDK OTLP log exporter in batches of up to 100 records and 1 MiB, flushed every 500ms.
    • A record larger than 1 MiB on its own is dropped up front (reason="oversized").
    • Failed exports retry up to 4 times with backoff from 250ms to 2s.
    • Records lost to a full queue, an oversized body, or exhausted retries are counted under reason and reported to the collector in an openshell.ocsf.gap record on the next successful export.
    • A collector's partial success counts as exported; the SDK exporter logs the rejected count as a warning. The docs say so.
    • On shutdown, the worker drains within a time budget and is stopped if it overruns it.
  • Shared OTLP setup (openshell-otel):

    • The validated endpoint and resource are factored into OtlpTarget, so the trace provider and the log exporter share one resource identity and the same transport. An https:// endpoint uses TLS with the platform trust roots for both.
    • The OCSF exporter (OcsfOtlp) lives in openshell-otel so other processes can share it. OcsfSchemaVersion moves into openshell-ocsf.
    • OtlpTraceConfig is renamed OtlpExportConfig.
    • The server's OtlpExport owns an optional trace provider and an optional OCSF exporter, each with its own endpoint, and shuts both down.
  • Configuration and deployment:

    • Helm deployments set the traces and ocsf tables through gatewayConfig. Chart tests cover rendering them, including openshell.gateway.otlp.ocsf: {enabled: true} with the shared endpoint.
    • The local gateway:* tasks enable OCSF export when a collector is listening on 127.0.0.1:4317.
    • Drivers and supervisors keep receiving the trace endpoint.
  • Docs:

    • The OCSF Log Export section in the gateway configuration reference.
    • An OCSF OTLP export metrics table: openshell_ocsf_otlp_{queued,exported,dropped,export_errors,retries}_total.
    • A pointer from the OCSF JSON export page.
    • The startup log line in debug-openshell-cluster.

Testing

  • cargo fmt --check and cargo clippy --workspace --all-targets -D warnings
  • cargo nextest run -p openshell-ocsf -p openshell-otel -p openshell-otel-test-support -p openshell-server -p openshell-gateway (including the TLS and gzip integration tests): 2,390 passed
  • cargo nextest run -p openshell-otel --lib on its own: 36 passed
  • cargo nextest run -p openshell-server -p openshell-otel -p openshell-gateway after the enabled flag and rebase on main: 2,296 passed
  • helm unittest deploy/helm/openshell: 336 passed
  • Config tests for the per-signal tables, endpoint defaults, and rejected settings
  • Unit tests added for record mapping, schema downgrade, severity, batching, byte limits, retry, gap reporting, and the shutdown budget, plus an export over gRPC to a loopback OTLP collector
  • Ran the full branch stack against a local Docker gateway and an Aspire OTLP collector. Every queued record was exported (openshell_ocsf_otlp_exported_total matched queued_total).
  • E2E tests added/updated (the OCSF export e2e lands with the supervisor collection PRs)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)

@github-actions

Copy link
Copy Markdown

@krishicks
krishicks force-pushed the feat/4499-gateway-ocsf-otlp-logs/krishicks branch 4 times, most recently from 281fda6 to b087caa Compare October 13, 2026 23:36
@krishicks
krishicks added this pull request to stack #4546 October 14, 2026 14:15
@krishicks
krishicks force-pushed the feat/4499-gateway-ocsf-otlp-logs/krishicks branch from b087caa to 1d973d9 Compare October 14, 2026 17:02
Comment thread deploy/helm/openshell/tests/gateway_config_test.yaml Outdated
Comment thread docs/how-it-works/gateways/configuration.mdx
@krishicks
krishicks force-pushed the feat/4499-gateway-ocsf-otlp-logs/krishicks branch from 1d973d9 to 582bcd8 Compare October 14, 2026 17:49
Comment thread tasks/scripts/gateway.sh
Comment thread tasks/scripts/gateway-vm.sh
Comment thread tasks/scripts/gateway-podman.sh
The gateway only persisted its OCSF events to the JSONL file, so collectors had
to tail that file. Adding `[openshell.gateway.otlp.ocsf]` now also exports each
gateway OCSF event as an OTLP log record, using the same resource identity as
gateway traces. `schema_version` optionally downgrades the exported JSON to
OCSF 1.1 or 1.3.

OTLP endpoints are now configured per signal, so OCSF events can go to a
collector that feeds a SIEM while spans go elsewhere. The existing
`[openshell.gateway.otlp]` `endpoint` is the default for every signal and on
its own still enables trace export. `[otlp.traces]` overrides the trace
endpoint, and `[otlp.ocsf]` takes its own `endpoint` or falls back to the
default.

Each record carries the OCSF JSON as its body, the event time as its timestamp,
a severity mapped from `severity_id`, and `ocsf.*` and `openshell.sandbox.id`
attributes for filtering without parsing the body.

Records flow through a queue bounded by count and bytes to the SDK OTLP log
exporter in batches bounded the same way. Failed exports retry with backoff;
records lost to a full queue, an oversized body, or exhausted retries are
counted in metrics and reported to the collector in an `openshell.ocsf.gap`
record on the next successful export. The exporter lives in `openshell-otel` so
other processes can share it.

Helm deployments set the `traces` and `ocsf` tables through `gatewayConfig`,
and the local development gateway tasks enable OCSF export.

Closes #4499
Refs #2892

Signed-off-by: Kris Hicks <khicks@nvidia.com>
@krishicks
krishicks added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit 07fd238 Oct 14, 2026
81 of 83 checks passed
@krishicks
krishicks deleted the feat/4499-gateway-ocsf-otlp-logs/krishicks branch October 14, 2026 19:18
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.

feat: export gateway OCSF events as OTLP log records

2 participants