Skip to main content
Codex (OpenAI’s coding agent, in its CLI, TUI and Desktop forms) ships native, opt-in OpenTelemetry export. Voight runs an OTLP receiver, so connecting the two takes one config block: no plugin, no hooks, no code changes. Once connected, every Codex session streams in as a single trace: the prompt that started it, each tool call with duration and outcome, every model call with token usage (input, output, cached, reasoning), permission decisions, and API failures. The Smart Traces tooling (waterfall view, deterministic diagnosis, AI explain) works on Codex sessions out of the box. Verified against codex-cli 0.146.
The wizard asks for your privacy level and your Voight API key (vk_..., from voight.xyz/dashboard → Settings → Generate key), then writes the [otel] block into ~/.codex/config.toml. A one-time backup of your previous config is kept at config.toml.voight-backup. Restart Codex (quit the Desktop app, or start a new CLI session) and run any task. The session appears in your dashboard within seconds. Running inside a Codex terminal? Plain npx -y @voightxyz/sdk setup auto-detects the target.

Manual setup

Append this to ~/.codex/config.toml:
Two details matter:
  • protocol = "json" is required. Voight’s receiver answers binary protobuf with a 415 telling you exactly this.
  • log_user_prompt = true exports the text of your prompts so traces show what each session was about. Set it to false and Codex sends a redacted placeholder instead (Voight never stores the placeholder).

What gets captured

Each record carries Codex’s conversation.id, which becomes the Voight trace id: one session, one trace. Streaming deltas, websocket chatter and startup phases are deliberately dropped: they would bury the timeline in noise without telling you anything a token summary does not.

Privacy

Codex attaches your OpenAI account id and email to every telemetry record. Voight’s receiver strips user.email, user.account_id and all auth.* attributes before anything touches storage; they are never persisted.

Troubleshooting

  • Nothing shows up: make sure you restarted Codex after editing the config, and that the block says protocol = "json".
  • You already export OTel elsewhere: Codex supports one exporter per signal. The wizard detects a foreign [otel] section and refuses to overwrite it; you choose which backend keeps the logs signal.
  • codex exec (non-interactive) sessions: log export works; Codex does not emit metrics there, which Voight does not use anyway.