Skip to main content

OTLP proxy

Send agent telemetry to your OpenTelemetry collector first so you can enrich, filter, or reduce it before it reaches Willow.

This is not OTLP Export. OTLP proxy sits in front of Willow (agents → your collector → Willow). OTLP Export copies data after Willow has ingested it (Willow → Coralogix or another backend).

Prerequisites

  1. The OpenTelemetry beta is enabled for your organization (Admin > Settings > Beta Features).
  2. An OTLP/HTTP collector that accepts JSON (http/json), typically on port 4318.
  3. Network path from developer machines (or the Scan Agent) to that collector, and from the collector to your Willow connect URL.

Configure the proxy

  1. Open Admin > Settings > Log Settings.
  2. Turn on OTLP proxy.
  3. Enter the collector base URL without a signal path, for example https://otel.example.com:4318. Clients append /v1/logs, /v1/metrics, and /v1/traces themselves.
  4. Save. Claude Code policies, Codex config, Cowork copy-paste values, and the Scan Agent all start targeting this URL. Scan Agents pick up the change on the next scan-config refresh (within a few minutes).

The Log Settings card also lists the Willow receiver URLs your collector should forward to.

Willow receiver URLs

Forward OTLP/HTTP JSON to the receiver that matches the source. The OpenTelemetry SDK and Codex already append the signal path (/v1/logs, /v1/metrics, /v1/traces), so your exporter's endpoint should be the base below:

SourceWillow base
Claude Code / Coworkhttps://{org-connect}/otlp/claude
Codexhttps://{org-connect}/otlp/codex
Cursor (Scan Agent upload)https://{org-connect}/otlp/cursor

Replace {org-connect} with your organization connect hostname. The three URLs are shown on the OTLP proxy card and on Monitor > Analytics > Data sources when the proxy is enabled.

Preserve authentication headers

Agents still send Willow credentials so your collector can pass them through. Forward these headers unchanged:

HeaderPurpose
AuthorizationBearer org token. Willow rejects the payload without it.
X-Device-IdDevice attribution for Scan Agent–provisioned exporters.
X-User-EmailUser attribution when the Scan Agent knows the local account.

If the collector cannot pass inbound headers through, stamp Authorization: Bearer <org token> on the exporter instead, and still forward X-Device-Id and X-User-Email when present.

OpenTelemetry Collector example

Route by service.name so each source lands on the matching Willow path. Claude Code uses claude-code; Cursor uploads use cursor. Confirm Codex on a sample payload if you collect it.

receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318

processors:
batch: {}

exporters:
otlphttp/claude:
endpoint: https://YOUR_ORG_CONNECT/otlp/claude
encoding: json
otlphttp/codex:
endpoint: https://YOUR_ORG_CONNECT/otlp/codex
encoding: json
otlphttp/cursor:
endpoint: https://YOUR_ORG_CONNECT/otlp/cursor
encoding: json

connectors:
routing:
default_pipelines: [logs/claude, metrics/claude]
table:
- statement: route() where attributes["service.name"] == "cursor"
pipelines: [traces/cursor, metrics/cursor, logs/cursor]
- statement: route() where attributes["service.name"] == "codex"
pipelines: [logs/codex, metrics/codex, traces/codex]
- statement: route() where attributes["service.name"] == "claude-code"
pipelines: [logs/claude, metrics/claude]

service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [routing]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [routing]
traces:
receivers: [otlp]
processors: [batch]
exporters: [routing]
logs/claude:
receivers: [routing]
exporters: [otlphttp/claude]
metrics/claude:
receivers: [routing]
exporters: [otlphttp/claude]
logs/codex:
receivers: [routing]
exporters: [otlphttp/codex]
metrics/codex:
receivers: [routing]
exporters: [otlphttp/codex]
traces/codex:
receivers: [routing]
exporters: [otlphttp/codex]
logs/cursor:
receivers: [routing]
exporters: [otlphttp/cursor]
metrics/cursor:
receivers: [routing]
exporters: [otlphttp/cursor]
traces/cursor:
receivers: [routing]
exporters: [otlphttp/cursor]

Use encoding: json. Willow's receivers accept OTLP/HTTP JSON, not protobuf or gRPC.

Configure header passthrough on each otlphttp/* exporter so Authorization, X-Device-Id, and X-User-Email from the inbound request are sent to Willow. You can drop or redact payload fields in a processor before the exporter; do not strip those headers.

  • Log Settings: content logging, collection toggles, and OTLP Export
  • Analytics: data sources and OTLP copy-paste values