# Cursor IDE Observability & Monitoring with OpenTelemetry

> Source: <https://signoz.io/docs/cursor-observability>
> Published: 2026-08-27 00:00:00+00:00

## What is Cursor IDE Observability?

[Cursor](https://cursor.com/) is an AI-native code editor whose agent plans and executes multi-step work: it reads files, runs shell commands, calls MCP servers, and edits code on your behalf. Cursor's own usage console shows what your team spent. What it does not show is what the agent actually did to spend it: which tools ran, how long each took, and which ones failed.

This guide closes that gap using [OpenTelemetry](https://opentelemetry.io/). Cursor's agent hooks fire on every step of the agent loop, and a hook runner turns those events into OTLP traces. The result is one trace per agent turn carrying both token counts and the full tool sequence, on any Cursor plan.

With Cursor IDE observability in SigNoz, you can see how many tokens your team is spending and on which models, how long a turn actually takes end to end, which tools the agent reaches for most, which ones fail and why, and how all of that breaks down per repository and branch.

## Prerequisites

- SigNoz setup (choose one):
[SigNoz Cloud account](https://signoz.io/teams/)with an active ingestion key- Self-hosted SigNoz instance

- Cursor IDE on macOS or Linux
- Python 3.11 or later

## Monitor Cursor IDE with OpenTelemetry

Cursor has no built-in OTLP exporter outside its Enterprise plan, and that path emits metrics and logs only, with no traces. Instead, this setup uses Cursor's agent hooks with [opentelemetry-hooks](https://github.com/o11y-dev/opentelemetry-hooks), an MIT-licensed runner that converts hook events into OTLP spans.

**Step 1:** Install the hook runner in its own environment so it does not touch your system Python.

```
python3 -m venv ~/.local/opt/otel-hook
~/.local/opt/otel-hook/bin/pip install opentelemetry-hooks
```

**Step 2:** Register it with Cursor. This writes `~/.cursor/hooks.json`

.

```
~/.local/opt/otel-hook/bin/otel-hook setup --agent cursor
```

**Step 3:** Add the event that carries token counts.

``` python
python3 - <<'EOF'
import json, os
p = os.path.expanduser("~/.cursor/hooks.json")
d = json.load(open(p))
h = d.get("hooks", d)
h["afterAgentResponse"] = json.loads(json.dumps(h["stop"]))
json.dump(d, open(p, "w"), indent=2)
print("events registered:", len(h))
EOF
```

You should see `events registered: 16`

. If `otel-hook`

is not on your `PATH`

, rewrite the commands in `~/.cursor/hooks.json`

to the absolute path of the binary, otherwise Cursor silently fails to run the hook.

**Step 4:** Point the exporter at SigNoz. Edit `~/.local/share/opentelemetry-hooks/otel_config.json`

, keeping the other keys already in the file.

```
{
  "OTEL_EXPORTER_OTLP_ENDPOINT": "https://ingest.<region>.signoz.cloud:443",
  "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
  "OTEL_EXPORTER_OTLP_HEADERS": "signoz-ingestion-key=<your-ingestion-key>",
  "OTEL_EXPORTER_OTLP_INSECURE": "false",
  "IDE_OTEL_BATCH_ON_STOP": "true"
}
```

**Verify these values:**

`<region>`

: Your[SigNoz Cloud region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint).`<your-ingestion-key>`

: Your SigNoz[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/).

The file holds your ingestion key, so restrict it with `chmod 600 ~/.local/share/opentelemetry-hooks/otel_config.json`

.

**Step 5:** Quit Cursor completely and reopen it. Cursor reads `~/.cursor/hooks.json`

only at startup, so a running instance will not pick up the change. Confirm the hooks are active under **Customize > Hooks**, then send a prompt that uses a tool.

## View Cursor IDE Traces in SigNoz

Allow a few minutes after your first prompt, then open the [Traces explorer](https://signoz.io/docs/userguide/traces/) and filter on `service.name = 'ide-agent'`

.

Opening a turn shows the full waterfall, with the agent's tool sequence nested under the turn and the `gen_ai.*`

attributes on the right.

## Attributes Worth Knowing

A turn produces a `gen_ai.client.generation`

span with one `gen_ai.client.hook.*`

child per hook event. Four details decide whether your queries are correct.

**Token counts arrive twice.**`afterAgentResponse`

and`Stop`

both carry identical`gen_ai.usage.input_tokens`

and`gen_ai.usage.output_tokens`

. Filter to one of them or every token figure doubles.**Turn duration is on** The`gen_ai.client.generation`

.`Stop`

span measures 1 ms on every turn and is a marker, not a measurement.**Tool failures are** A single failed tool call also sets error status on its`PostToolUseFailure`

.`PreToolUse`

and`PostToolUse`

spans, so counting error status roughly doubles the failure rate.The runner hardcodes it for every agent it supports, so group by`service.name`

is always`ide-agent`

.`gen_ai.client.name`

(`cursor`

) when you run more than one agent.

Every span also carries `gen_ai.request.model`

, `gen_ai.client.session_id`

, `gen_ai.client.generation_id`

, and, when the runner resolves it, `vcs.repository.name`

and `vcs.ref.head.name`

.

## View Cursor IDE Logs in SigNoz

The runner emits logs alongside the traces, one record per tool call, shell execution, and MCP call. Open the [Logs Explorer](https://signoz.io/docs/userguide/logs_query_builder/) and filter with `service.name = 'ide-agent'`

to see the event stream.

Logs carry detail the spans do not. Open a record to see it in the attributes.

Useful attributes include `gen_ai.client.command`

and `gen_ai.client.shell.stdout`

for shell executions, `gen_ai.client.tool_name`

and `gen_ai.client.duration_ms`

for tool calls, and `gen_ai.client.hook.event`

to separate the event types. Every record also carries `trace_id`

and `span_id`

, so a log line links back to the exact span in the turn's waterfall.

## Cursor IDE Observability Dashboard

The [Cursor IDE dashboard](https://signoz.io/docs/dashboards/dashboard-templates/cursor-dashboard/) turns these spans into token spend by model, turn and tool latency, tool mix, and failure tracking.

## Troubleshooting Cursor IDE Observability

### No spans arrive at all

Check delivery locally before assuming the export is broken:

```
cat ~/.local/share/opentelemetry-hooks/.state/delivery_health.json
```

A `last_success_at_ns`

newer than `last_failure_at_ns`

means export is working and you are looking at ingestion delay. Allow 2 to 4 minutes before re-checking SigNoz.

If there is no success timestamp, confirm Cursor was fully restarted after Step 2, and that **Customize > Hooks** lists the registered events.

### Spans arrive but every token panel is empty

`afterAgentResponse`

is not registered. Re-run Step 3 and confirm it prints `events registered: 16`

, then restart Cursor. A restart is required whenever the registered event set changes.

### Traces show a "missing span" placeholder

This is expected. The runner parents each turn to a session span that it never emits, so SigNoz shows the turn under a missing parent. The turn and its children are complete and every query works normally.

### Repository shows as N/A on some spans

The runner resolves repository context once per session and does not always succeed, so `vcs.repository.name`

can be absent even when the workspace is a git repository. Those spans are missing attribution rather than running outside a repository, which matters if you group token spend by repository.

### Nothing is emitted from the Cursor CLI

This cannot be fixed by configuration. The Cursor CLI omits the `beforeSubmitPrompt`

, `afterAgentResponse`

, and `stop`

hooks in non-interactive mode, and the runner builds a turn's spans only when `Stop`

arrives. Use the Cursor IDE, or query Cursor's Admin API for team-level token and cost totals without per-tool detail.

## Related integrations

Instrument the other AI coding agents your team runs, using the same OpenTelemetry pipeline:

[Monitor Claude Code with OpenTelemetry](https://signoz.io/docs/claude-code-monitoring/)[Monitor OpenAI Codex with OpenTelemetry](https://signoz.io/docs/codex-monitoring/)[OpenCode observability with OpenTelemetry](https://signoz.io/docs/opencode-observability/)[Monitor GitHub Copilot with OpenTelemetry](https://signoz.io/docs/github-copilot-monitoring/)

Browse [all LLM observability integrations](https://signoz.io/docs/llm-observability/) to instrument the rest of your stack.
