[PR #2735] Add OpenTelemetry instrumentation for the AI SDK #10427

Closed
opened 2026-02-16 18:15:04 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/2735

State: closed
Merged: No


Problem statement

opencode does not currently provide much visibility into the underlying behavior of the system as it relates to the AI SDK & API server.

The AI SDK integrates with OpenTelemetry to emit metrics & logs. This change-set enables support for those features, making it easy for developers and users of opencode to observe metrics & logs emitted by the AI SDK.

Summary of changes

  • What: Adds opt-in OpenTelemetry (OTEL) observability for traces/logs to the opencode CLI for the AI SDK
  • Why: Provide optional local observability for debugging and diagnostics while keeping telemetry disabled by default and avoiding Node-only imports in alternative runtimes.

Files Changed

  • Docs:
    • /README.md — adds an "OpenTelemetry logs & metrics" section with usage examples and recommendations.
  • Dependencies:
    • packages/opencode/package.json — adds @opentelemetry/sdk-node, @opentelemetry/exporter-trace-otlp-grpc, and @opentelemetry/exporter-trace-otlp-http.
  • Code:
    • packages/opencode/src/util/telemetry.ts — new module exporting aiSdkTelemetrySettings and initOpenTelemetry(); dynamically imports Node OTEL SDK and starts a NodeSDK when enabled.
    • packages/opencode/src/index.ts — calls initOpenTelemetry() during CLI startup so OTEL can initialize early (only when enabled).
    • AI SDK wiring: pass aiSdkTelemetrySettings into relevant requests so the AI SDK can emit telemetry when enabled
      • packages/opencode/src/agent/agent.ts
      • packages/opencode/src/session/compaction.ts
      • packages/opencode/src/session/prompt.ts
  • Developer tooling: convenience scripts for running otel-cli and pretty-print incoming telemetry
    • script/otel-listener.sh
    • script/otel-pretty-printer.jq

Implementation Details

  • Opt-in: Telemetry is enabled only when the USE_OTEL environment variable is set; otherwise aiSdkTelemetrySettings is undefined and behavior is unchanged.
  • Dynamic import: initOpenTelemetry() uses dynamic import() so Node-only OpenTelemetry packages are not loaded unless telemetry is requested.
  • Default exporter: If OTEL_EXPORTER_OTLP_PROTOCOL is not set, a default OTLP gRPC exporter is created; setting various OTEL env vars allows full exporter customization.
  • Safe failure: OTEL initialization errors are caught and emitted as warnings to stderr (no CLI crash).

Testing

  1. Start a local listener: script/otel-listener.sh (requires otel-cli and jq to be installed)
  2. Run the CLI with telemetry: USE_OTEL=1 opencode (or USE_OTEL=1 bun dev in development)
  3. Verify output: The listener should receive/print traces emitted by the AI SDK (note: currently only the AI SDK is configured to emit telemetry).

Notes for reviewers

  • Dependencies: New OTEL packages were added to packages/opencode; ensure CI/installers pick those up when running Node-based workflows.
  • Runtime safety: Confirm dynamic import behavior is correct for both Node and Bun
  • Telemetry scope: The implementation configures the AI SDK to emit telemetry via OpenTelemetry
  • Scripts: script/otel-listener.sh assumes otel-cli and jq are installed and that script/otel-pretty-printer.jq is executable.

Risk & Backwards compatibility

  • Experimental functionality: The AI SDK provides this functionality as an experimental feature (doc link), so this could stop working down the road without warning. Best case: it silently stops working, worst case it fails to run on a newer version of the SDK, though this would be observed by devs updating dependencies, not by users.
  • Default behavior preserved: No runtime change unless USE_OTEL is set
  • Installer size: OTEL was already a transitive dependency, so it's unlikely the size changed noticeably
  • Robustness: Initialization failures are non-fatal and surface as warnings only

Screenshots

image image image image image image
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/2735 **State:** closed **Merged:** No --- ### Problem statement `opencode` does not currently provide much visibility into the underlying behavior of the system as it relates to the AI SDK & API server. [The AI SDK integrates with OpenTelemetry](https://ai-sdk.dev/docs/ai-sdk-core/telemetry) to emit metrics & logs. This change-set enables support for those features, making it easy for developers and users of `opencode` to observe metrics & logs emitted by the AI SDK. ### Summary of changes - **What**: Adds opt-in OpenTelemetry (OTEL) observability for traces/logs to the `opencode` CLI for the AI SDK - **Why**: Provide optional local observability for debugging and diagnostics while keeping telemetry disabled by default and avoiding Node-only imports in alternative runtimes. #### Files Changed - Docs: - `/README.md` — adds an "OpenTelemetry logs & metrics" section with usage examples and recommendations. - Dependencies: - `packages/opencode/package.json` — adds `@opentelemetry/sdk-node`, `@opentelemetry/exporter-trace-otlp-grpc`, and `@opentelemetry/exporter-trace-otlp-http`. - Code: - `packages/opencode/src/util/telemetry.ts` — new module exporting `aiSdkTelemetrySettings` and `initOpenTelemetry()`; dynamically imports Node OTEL SDK and starts a NodeSDK when enabled. - `packages/opencode/src/index.ts` — calls `initOpenTelemetry()` during CLI startup so OTEL can initialize early (only when enabled). - AI SDK wiring: pass `aiSdkTelemetrySettings` into relevant requests so the AI SDK can emit telemetry when enabled - `packages/opencode/src/agent/agent.ts` - `packages/opencode/src/session/compaction.ts` - `packages/opencode/src/session/prompt.ts` - Developer tooling: convenience scripts for running `otel-cli` and pretty-print incoming telemetry - `script/otel-listener.sh` - `script/otel-pretty-printer.jq` ### Implementation Details - **Opt-in**: Telemetry is enabled only when the `USE_OTEL` environment variable is set; otherwise `aiSdkTelemetrySettings` is `undefined` and behavior is unchanged. - **Dynamic import**: `initOpenTelemetry()` uses dynamic `import()` so Node-only OpenTelemetry packages are not loaded unless telemetry is requested. - **Default exporter**: If `OTEL_EXPORTER_OTLP_PROTOCOL` is not set, a default OTLP gRPC exporter is created; setting various OTEL env vars allows full exporter customization. - **Safe failure**: OTEL initialization errors are caught and emitted as warnings to stderr (no CLI crash). ### Testing 1. **Start a local listener**: `script/otel-listener.sh` (requires `otel-cli` and `jq` to be installed) 2. **Run the CLI with telemetry**: `USE_OTEL=1 opencode` (or `USE_OTEL=1 bun dev` in development) 3. **Verify output**: The listener should receive/print traces emitted by the AI SDK (note: currently only the AI SDK is configured to emit telemetry). ### Notes for reviewers - **Dependencies**: New OTEL packages were added to `packages/opencode`; ensure CI/installers pick those up when running Node-based workflows. - **Runtime safety**: Confirm dynamic import behavior is correct for both Node and Bun - **Telemetry scope**: The implementation configures the AI SDK to emit telemetry via OpenTelemetry - **Scripts**: `script/otel-listener.sh` assumes `otel-cli` and `jq` are installed and that `script/otel-pretty-printer.jq` is executable. ### Risk & Backwards compatibility - **Experimental functionality**: The AI SDK provides this functionality as an experimental feature ([doc link](https://ai-sdk.dev/docs/ai-sdk-core/telemetry)), so this could stop working down the road without warning. Best case: it silently stops working, worst case it fails to run on a newer version of the SDK, though this would be observed by devs updating dependencies, not by users. - **Default behavior preserved**: No runtime change unless `USE_OTEL` is set - **Installer size**: OTEL was already a transitive dependency, so it's unlikely the size changed noticeably - **Robustness**: Initialization failures are non-fatal and surface as warnings only # Screenshots <img width="645" height="381" alt="image" src="https://github.com/user-attachments/assets/63f1cedf-768d-4eb0-918b-ec577a3be637" /> <img width="1739" height="411" alt="image" src="https://github.com/user-attachments/assets/c34ccbdb-5c05-42e5-a872-b00ec6df9cd0" /> <img width="1739" height="451" alt="image" src="https://github.com/user-attachments/assets/d9f9a8c6-dc73-48ae-b6ce-8b8f05111a8d" /> <img width="1743" height="613" alt="image" src="https://github.com/user-attachments/assets/629243bf-e366-44ea-812d-1ee862538bc0" /> <img width="1733" height="533" alt="image" src="https://github.com/user-attachments/assets/861a287c-1dc4-4da0-8cda-90dd8da01256" /> <img width="1165" height="487" alt="image" src="https://github.com/user-attachments/assets/71ac9b07-8c21-43dd-8872-ab7ec0432581" />
yindo added the pull-request label 2026-02-16 18:15:04 -05:00
yindo closed this issue 2026-02-16 18:15:04 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#10427