Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fintegrations%2Fai-observability%2Fcodex-cli.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fcoralogix.com%2Fdocs%2Fintegrations%2Fai-observability%2Fcodex-cli.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

# Codex CLI and Desktop integration with Coralogix

Codex ships with built-in OpenTelemetry (OTel) support. You can send API requests, tool activity, user activity, turn metrics, and traces directly to Coralogix without adding application instrumentation.

Codex CLI and Codex inside the ChatGPT desktop app share the same runtime and configuration system. A single OTel configuration covers both surfaces, and the `originator` and `session_source` attributes distinguish them in Coralogix.

Validated with Codex 0.149

Coralogix validated this integration with Codex `0.149`. The tested ChatGPT desktop app bundles `codex-cli 0.149.0-alpha.4.1`. Earlier clients can lack the OTLP metrics exporter, and Windows managed-file paths changed in `0.149`. Upgrade before troubleshooting missing data.

## Supported environments[​](#supported-environments "Direct link to Supported environments")

* **Codex CLI:** macOS, Linux, and Windows. Use `bash` or `zsh` on macOS and Linux, and PowerShell for native Windows setup.
* **ChatGPT desktop app:** macOS and Windows.
* **Fleet deployment:** a system-managed Codex configuration file on all supported platforms, or macOS managed preferences delivered through mobile device management (MDM).
* **Per-developer setup:** OTel settings in the user's Codex configuration file.

For Windows runtime and shell options, see OpenAI's [Windows app documentation](https://learn.chatgpt.com/docs/windows/windows-app).

## What you need[​](#what-you-need "Direct link to What you need")

* A Coralogix account with a **Send-Your-Data [API key](https://coralogix.com/docs/user-guides/account-management/api-keys/send-your-data-api-key.md)**. In Coralogix, navigate to **Settings**, then **API Keys**.
* Your Coralogix OTLP endpoint: `https://ingress.eu2.coralogix.com`. Use the domain selector at the top of this page to select your region.
* A current Codex CLI or ChatGPT desktop app installation.
* Network access from developer machines to the Coralogix ingress host on port `443`.

## How telemetry flows[​](#how-telemetry-flows "Direct link to How telemetry flows")

**The OTel exporters run inside the Codex client and send each signal directly to the Coralogix endpoint you configure.** Telemetry for this integration does not pass through OpenAI's servers.

When `metrics_exporter` is not configured, Codex sends metrics to OpenAI's internal analytics pipeline (`statsig`). Setting `metrics_exporter` to `otlp-http` replaces that destination with Coralogix. Codex exports each signal to a single destination.

## Set up[​](#set-up "Direct link to Set up")

### Deploy organization-wide[​](#deploy-organization-wide "Direct link to Deploy organization-wide")

Codex reads OTel settings from its TOML configuration files. To roll the Coralogix destination out to a fleet, deploy a completed configuration file to each machine with your device-management tooling.

#### Distribution layers[​](#distribution-layers "Direct link to Distribution layers")

OpenAI provides two administrative layers. Only **managed defaults** can carry the `[otel]` block:

| Layer                      | What it controls                                               | Delivery                                                                                 | Supports `[otel]` |
| -------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------- |
| Cloud-managed requirements | Enforced policy: approvals, sandbox, permissions, MCP, plugins | ChatGPT [Managed configuration](https://chatgpt.com/codex/settings/managed-configs) page | No                |
| Managed defaults           | Starting values from the regular Codex `config.toml` schema    | A managed file deployed to each machine, or macOS MDM using `config_toml_base64`         | Yes               |

The cloud page, including its **Raw TOML** editor, distributes `requirements.toml`-compatible policy only. The requirements schema has no `otel` key, so you cannot set or enforce the `[otel]` exporters there. Do not place the Coralogix endpoint or API key in that editor.

OpenAI does not currently provide a console for uploading managed defaults. Codex on eligible ChatGPT Enterprise plans also fetches cloud-delivered configuration defaults, but OpenAI does not document an admin surface for them and a user's `config.toml` overrides them. Deploy the managed file with the software your organization already uses: for example, Microsoft Intune or Group Policy on Windows, Jamf Pro or another MDM provider on macOS, and configuration management or a system package on Linux.

Amazon Bedrock and custom model providers

This integration supports the built-in OpenAI provider using ChatGPT sign-in or an OpenAI API key. Amazon Bedrock is not supported: on that path the OpenAI-hosted Responses API is not in the request loop, and during validation Codex did not emit the required OTel signals. Treat organization gateways and other custom model providers as not validated until you confirm they emit the required logs, metrics, and traces.

#### Distribute the managed configuration[​](#distribute-the-managed-configuration "Direct link to Distribute the managed configuration")

1. Copy the template in [Complete configuration](#complete-configuration), then replace `<your-region>` and `<YOUR_CX_API_KEY>` with literal values. Do not deploy unresolved `<...>` placeholders.

2. Deploy the completed file to the platform path:

   | Platform        | Path                                     | Behavior                                                             |
   | --------------- | ---------------------------------------- | -------------------------------------------------------------------- |
   | macOS and Linux | `/etc/codex/managed_config.toml`         | Managed defaults that override the user's `config.toml`.             |
   | Windows         | `%ProgramData%\OpenAI\Codex\config.toml` | Machine-wide defaults. A user's own `config.toml` can override them. |

3. Restrict who can modify the deployed file. On Unix systems, make it root-owned and not group- or world-writable, while keeping it readable by the Codex user.

4. Fully restart each client. For the ChatGPT desktop app on macOS, use **Cmd+Q** rather than closing only the window.

Windows managed path changed in Codex 0.149

Since Codex `0.149`, Windows ignores `managed_config.toml` under `%USERPROFILE%\.codex` and logs a startup warning. Use `%ProgramData%\OpenAI\Codex\config.toml` for deployed defaults. Some OpenAI documentation still shows the old per-user path.

Codex applies configuration in this order, highest precedence first:

1. macOS MDM payload (`config_toml_base64`)
2. `/etc/codex/managed_config.toml`
3. CLI `--config` overrides
4. The user's `config.toml`
5. Cloud-delivered workspace defaults
6. The machine-wide system `config.toml`

See OpenAI's [managed configuration documentation](https://learn.chatgpt.com/docs/enterprise/managed-configuration) for current details.

#### Deploy on macOS with MDM[​](#deploy-on-macos-with-mdm "Direct link to Deploy on macOS with MDM")

If your organization already manages Macs with an MDM provider, prefer a managed preference:

1. Save the completed configuration as `managed_config.toml` and encode it as base64 without line wrapping:

   ```
   base64 < managed_config.toml | tr -d '\n'
   ```

2. Create a configuration profile with preference domain `com.openai.codex`, key `config_toml_base64`, type String, and the base64 output as the value.

3. Push the profile and fully restart the ChatGPT desktop app, Codex CLI, or IDE extension.

The MDM preference has the highest precedence. Use `config_toml_base64` for OTel defaults. The `requirements_toml_base64` key carries security requirements, not telemetry settings, and both keys are macOS-only.

### Per-developer setup[​](#per-developer-setup "Direct link to Per-developer setup")

Use this path for an individual developer or a small unmanaged deployment.

#### Install[​](#install "Direct link to Install")

Clone the Coralogix AI agent instrumentation repository and navigate to the Codex directory:

```
git clone https://github.com/coralogix/ai-agent-instrumentation.git

cd ai-agent-instrumentation/codex
```

Before using the cloned `config.toml.example`, confirm that it contains `[otel.metrics_exporter.otlp-http]`. If it does not, use the template in [Complete configuration](#complete-configuration) instead. Older copies of the template configure only logs and traces.

#### Configure on macOS or Linux[​](#configure-on-macos-or-linux "Direct link to Configure on macOS or Linux")

1. Copy the template in [Complete configuration](#complete-configuration) and replace `<your-region>` and `<YOUR_CX_API_KEY>` with literal values.

2. Merge the completed OTel blocks into `~/.codex/config.toml`.

   Warning

   Do not append duplicate `[otel]`, exporter, or header tables to an existing TOML file. Duplicate table names make the configuration invalid. Back up `~/.codex/config.toml` before merging.

3. Start Codex CLI, or fully restart the ChatGPT desktop app:

   ```
   codex
   ```

Because the endpoint and headers live in `~/.codex/config.toml`, the same configuration reaches the desktop app even though applications launched from the Dock do not read `.zshrc` or `.bashrc`.

#### Configure on native Windows[​](#configure-on-native-windows "Direct link to Configure on native Windows")

Create the Codex configuration directory if it does not exist:

```
New-Item -ItemType Directory -Force "$HOME\.codex" | Out-Null
```

Merge the completed OTel blocks into `$HOME\.codex\config.toml` without creating duplicate TOML tables. Fully exit and relaunch the Windows desktop app, or start a new Codex CLI process.

## Application name and subsystem[​](#application-name-and-subsystem "Direct link to Application name and subsystem")

Coralogix routes incoming telemetry by the `CX-Application-Name` and `CX-Subsystem-Name` OTLP headers. Use these values:

| Header                | Value                                                             | Purpose                                          |
| --------------------- | ----------------------------------------------------------------- | ------------------------------------------------ |
| `CX-Application-Name` | `codex`                                                           | Groups all Codex surfaces under one application. |
| `CX-Subsystem-Name`   | A team or deployment name, such as `platform` or `codex-sessions` | Separates teams or rollout groups.               |

Use the same values for logs, metrics, and traces. To separate CLI and Desktop in dashboards, group by Codex's `originator` and `session_source` attributes instead of assigning different Coralogix applications.

## Complete configuration[​](#complete-configuration "Direct link to Complete configuration")

Use this template for the user `config.toml`, the managed paths from [Distribute the managed configuration](#distribute-the-managed-configuration), or the macOS `config_toml_base64` MDM payload. Replace `<your-region>` and `<YOUR_CX_API_KEY>` with literal values before deploying.

```
[otel]

environment = "production"

log_user_prompt = false



# Logs

[otel.exporter.otlp-http]

endpoint = "https://ingress.<your-region>.coralogix.com/v1/logs"

protocol = "binary"



[otel.exporter.otlp-http.headers]

"Authorization" = "Bearer <YOUR_CX_API_KEY>"

"CX-Application-Name" = "codex"

"CX-Subsystem-Name" = "codex-sessions"



# Metrics

[otel.metrics_exporter.otlp-http]

endpoint = "https://ingress.<your-region>.coralogix.com/v1/metrics"

protocol = "binary"



[otel.metrics_exporter.otlp-http.headers]

"Authorization" = "Bearer <YOUR_CX_API_KEY>"

"CX-Application-Name" = "codex"

"CX-Subsystem-Name" = "codex-sessions"



# Traces

[otel.trace_exporter.otlp-http]

endpoint = "https://ingress.<your-region>.coralogix.com/v1/traces"

protocol = "binary"



[otel.trace_exporter.otlp-http.headers]

"Authorization" = "Bearer <YOUR_CX_API_KEY>"

"CX-Application-Name" = "codex"

"CX-Subsystem-Name" = "codex-sessions"
```

Codex has separate OTel pipelines for logs (`otel.exporter`), metrics (`otel.metrics_exporter`), and traces (`otel.trace_exporter`). Each signal needs its own endpoint path and header block.

For the source template, see [Codex in the Coralogix AI agent instrumentation repository](https://github.com/coralogix/ai-agent-instrumentation/tree/master/codex). For the supported Codex keys, see OpenAI's [configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference).

### Activate prompt logging[​](#activate-prompt-logging "Direct link to Activate prompt logging")

Prompt logging is off by default. Set `log_user_prompt = true` in the `[otel]` block to include prompt text in `codex.user_prompt` log events:

```
[otel]

log_user_prompt = true
```

Enable it only when your security, access, and retention policies allow raw prompt contents in Coralogix.

## Validate the integration[​](#validate-the-integration "Direct link to Validate the integration")

### Confirm the Codex version[​](#confirm-the-codex-version "Direct link to Confirm the Codex version")

For Codex CLI:

```
codex --version
```

For a standard macOS ChatGPT desktop installation, inspect the bundled runtime:

```
"/Applications/ChatGPT.app/Contents/Resources/codex" --version
```

If the CLI is earlier than `0.149`, update it with `npm install -g @openai/codex@latest`. Desktop updates replace the bundled Codex binary, so update the ChatGPT desktop app itself rather than installing a separate CLI for Desktop.

### Generate telemetry[​](#generate-telemetry "Direct link to Generate telemetry")

1. Start Codex CLI or open a Codex task in the ChatGPT desktop app.

2. Submit a prompt, wait for the turn to complete, and allow time for the periodic OTel export.

3. Confirm each signal independently:

   <!-- -->

   * **Metrics:** In **Metrics Explorer**, search for the `codex_` prefix. For recent completed turns, query:

     ```
     sum(increase(codex_turn_e2e_duration_ms_count[5m]))
     ```

   * **Logs:** In **Logs**, filter by application `codex` and your subsystem, then find `codex.user_prompt`, `codex.api_request`, or `codex.tool_result`.

   * **Traces:** In **Explore**, select **Tracing** and filter by application `codex` and your subsystem.

To identify which Codex surface produced completed turns, group by the labels available in your account:

```
sum by (originator, session_source, app_version) (

  increase(codex_turn_e2e_duration_ms_count[5m])

)
```

OTel attribute names can appear normalized as Prometheus labels: for example, `app.version` commonly appears as `app_version`. Use the Metrics Explorer label browser to confirm the exact names.

## Data reference[​](#data-reference "Direct link to Data reference")

The AI Center Code Agents dashboard surfaces the most common session, API, and tool-call signals out of the box. To explore every log event, metric, and span attribute that Codex emits (and to use those signals in your own Custom Dashboards or alerts) see OpenAI's [observability and telemetry reference](https://learn.chatgpt.com/docs/config-file/config-advanced#observability-and-telemetry).

Every OTel metric includes default metadata such as `auth_mode`, `originator`, `session_source`, `model`, and `app.version`. Log events add conversation and event-specific context, including `conversation.id` and `user.email`. The `auth_mode` attribute distinguishes ChatGPT sign-in from OpenAI API-key authentication.

### Metrics[​](#metrics "Direct link to Metrics")

Codex metric names use dots in OTel. Coralogix exposes Prometheus-compatible names with dots converted to underscores. Counters receive `_total`, and histograms expose `_count`, `_sum`, and `_bucket` series.

| OTel metric                     | Type      | What it tracks                                                                                    |
| ------------------------------- | --------- | ------------------------------------------------------------------------------------------------- |
| `codex.api_request`             | Counter   | API requests by status and success.                                                               |
| `codex.api_request.duration_ms` | Histogram | API request latency.                                                                              |
| `codex.turn.e2e_duration_ms`    | Histogram | Completed turns and end-to-end turn duration. Use its `_count` series for recent turn activity.   |
| `codex.turn.token_usage`        | Histogram | Per-turn token usage by token type.                                                               |
| `codex.tool.call`               | Counter   | Tool invocations by tool and success.                                                             |
| `codex.tool.call.duration_ms`   | Histogram | Tool execution duration.                                                                          |
| `codex.thread.started`          | Counter   | New Codex threads.                                                                                |
| `codex.conversation.turn.count` | Counter   | Turns in a thread, recorded when that thread/session shuts down. Do not use it for live activity. |

### Log events[​](#log-events "Direct link to Log events")

| Event                       | What it captures                                                               |
| --------------------------- | ------------------------------------------------------------------------------ |
| `codex.conversation_starts` | Model, reasoning settings, sandbox, and approval policy.                       |
| `codex.api_request`         | Attempt, duration, HTTP status, success, and error details.                    |
| `codex.sse_event`           | Stream event type, success, duration, and token counts on completed responses. |
| `codex.websocket_request`   | Request duration and outcome.                                                  |
| `codex.websocket_connect`   | WebSocket connection attempts and outcome.                                     |
| `codex.user_prompt`         | Prompt length. Codex redacts prompt content unless `log_user_prompt = true`.   |
| `codex.tool_decision`       | Tool approval or denial and its source.                                        |
| `codex.tool_result`         | Tool name, duration, success, and output metadata.                             |

### Traces[​](#traces "Direct link to Traces")

With `otel.trace_exporter` configured, Codex exports spans for the session and turn lifecycle, including model requests and tool execution. The `service.name` resource attribute identifies the surface: Codex CLI emits `codex_cli_rs`, and the ChatGPT desktop app emits `codex-app-server`. Filter first by the Coralogix application and subsystem headers, then use `service.name`, `originator`, and `session_source` to break down the surface.

## Troubleshoot[​](#troubleshoot "Direct link to Troubleshoot")

No logs, metrics, or traces appear

Work from the client toward Coralogix:

* Confirm the running version with `codex --version`. For Desktop on macOS, run `"/Applications/ChatGPT.app/Contents/Resources/codex" --version`. Upgrade clients earlier than `0.149`.
* In Codex CLI, open `/status` and confirm the active model provider. This integration does not support `amazon-bedrock`. Validate any other custom provider before troubleshooting the Coralogix pipeline.
* Confirm the effective configuration contains all three exporter blocks and that no higher-precedence layer overrides the user's file.
* Confirm each endpoint uses HTTPS and the correct signal path: `/v1/logs`, `/v1/metrics`, or `/v1/traces`, and that every exporter has a valid Send-Your-Data key plus `CX-Application-Name` and `CX-Subsystem-Name` headers.
* Check firewall, DNS, proxy, and TLS inspection rules for the Coralogix ingress host on port `443`.
* In **Data Flow**, inspect **Parsing Rules** for a **Block** rule that matches Codex logs, and check for Logs or Traces TCO policies with a **Blocked** result. In **Metrics Usage**, enable the **Blocked** view and search for `codex_` metrics. Parsing rules affect only logs; TCO and metrics blocking are signal-specific too, so check the control that matches the missing signal.
* Fully restart the client and complete a new turn. Closing only the Desktop window does not restart its Codex process.

Test logs, metrics, and traces independently so that a working signal does not hide a signal-specific problem.

Logs do not appear but metrics or traces do

* Confirm `[otel.exporter.otlp-http]` points to `/v1/logs` and has its own header table.
* In **Data Flow**, inspect **Parsing Rules** for an account-wide **Block** rule, or a rule group with no application, subsystem, or severity matcher.
* Inspect Logs TCO policies for a first-matching policy that routes application `codex` or your subsystem to **Blocked**.
* If raw logs exist but the Code Agents dashboard is empty, inspect a recent raw record. The dashboard expects the OTLP `logRecord` object. A **Remove Fields** rule that deletes it breaks the dashboard without preventing the log from being stored.

Parsing changes affect only new logs. Generate a new turn after changing a rule.

Metrics do not appear but logs do

* Upgrade Codex to `0.149` or later and confirm `[otel.metrics_exporter.otlp-http]` points to `/v1/metrics` with its own header table.
* In **Settings**, open **Usage & Plans**, then **Metrics Usage**. Enable the **Blocked** view and unblock required `codex_*` metrics.
* Search Metrics Explorer for the `codex_` prefix without application filters first. Add application, subsystem, `originator`, or `session_source` filters after confirming the labels available in your account.
* Complete a Codex turn and allow time for the periodic metrics export.

Log parsing rules do not process metrics and cannot be the cause of a missing metric.

Traces do not appear but logs or metrics do

* Confirm `[otel.trace_exporter.otlp-http]` points to `/v1/traces` and its header table contains the Send-Your-Data key, application, and subsystem.
* Inspect Traces TCO policies. A **Blocked** result drops matching spans at ingestion.
* Query traces by application and subsystem before filtering by a CLI-specific service name. Desktop and CLI can use different service values.
* For full AI Center support, route Codex spans to a priority that reaches the required archive-backed views. Medium is the safest default for AI Center spans.

Log parsing rules do not process spans and cannot be the cause of missing traces.

Conversation turn counts are delayed or incomplete

Cause: `codex.conversation.turn.count` is recorded at the end of a thread/session, not after every prompt. Open Desktop tasks might not emit it until their runtime session shuts down, and a crash or forced termination can prevent the final flush.

Fix: use `codex_turn_e2e_duration_ms_count` for completed-turn activity. Use `codex_conversation_turn_count_total` only for end-of-thread analysis, and close CLI sessions cleanly with `/exit` when testing shutdown telemetry.

Only CLI or only Desktop usage appears

Cause: the surfaces load different configuration layers, or one client has not restarted.

Fix:

* Store the completed OTel configuration in the user `config.toml`, or deploy it through the managed paths in [Distribute the managed configuration](#distribute-the-managed-configuration).
* Fully restart the ChatGPT desktop app with **Cmd+Q** on macOS, or fully exit and relaunch it on Windows. Start a new CLI process.
* Group recent turn metrics by `originator`, `session_source`, and `app_version` to identify which surface is reporting.
* If multiple copies of the Desktop app exist, inspect the running process path and update the copy users actually launch.

After changing the configuration, complete a new turn from each surface and compare the resulting labels.

Windows Desktop or CLI sends no telemetry

Cause: the OTel configuration is in a location Codex does not read on this version.

* For per-developer setup, use `$HOME\.codex\config.toml` in the account that runs Codex.

* For managed deployment, use `%ProgramData%\OpenAI\Codex\config.toml`. Since Codex `0.149`, `%USERPROFILE%\.codex\managed_config.toml` is ignored on Windows.

* Confirm that `<your-region>` and `<YOUR_CX_API_KEY>` were replaced with literal values.

* Configuration loads only at process start, and a Codex process that started before your edit keeps running with the old settings even after you open a new session. In PowerShell, stop any leftover processes before relaunching:

  ```
  Get-Process codex* -ErrorAction SilentlyContinue | Stop-Process -Force
  ```

Relaunch the desktop app or CLI and complete a new turn.

The Code Agents dashboard is empty but Codex logs exist

Check storage routing first. The Codex dashboard reads session data from your S3 archive, so data held only in Frequent Search does not populate archive-backed widgets.

If routing is correct, inspect the log shape:

* In **Logs**, open a recent Codex log, select its more actions menu, then select **View Raw Log**.
* Confirm the record still contains the `logRecord` object.
* In **Data Flow**, open **Parsing Rules** and inspect account-wide rule groups for a **Remove Fields** rule that deletes `logRecord`.

To fix it, scope the rule group to the applications it serves, disable an obsolete group, or keep `logRecord`. Keeping both nested and flattened fields can increase stored log volume, so prefer scoping the unrelated rule when possible.

Parsing and routing changes apply to newly ingested telemetry only. Existing records are not backfilled.

## Next steps[​](#next-steps "Direct link to Next steps")

Once your integration is set up, explore [Code agents](https://coralogix.com/docs/user-guides/ai/code-agents.md) to monitor token usage, tool calls, latency, and session activity across Codex CLI and Desktop.
