{"slug": "qwen-code-observability-and-monitoring-with-opentelemetry", "title": "Qwen Code Observability and Monitoring with OpenTelemetry", "summary": "Alibaba's open-source terminal coding agent Qwen Code now supports full observability via OpenTelemetry, enabling users to monitor token usage, model calls, and tool executions in SigNoz. The feature, available in Qwen Code 0.21.15 or later, requires enabling telemetry in settings and setting an ingestion key, with traces, metrics, and logs emitted for every agent turn.", "body_md": "## What is Qwen Code Observability?\n\n[Qwen Code](https://github.com/QwenLM/qwen-code) is Alibaba's open-source terminal coding agent. It ships its own [OpenTelemetry](https://opentelemetry.io/) exporter, so instrumenting it is a matter of configuration: there is no library to install and no collector to run. Once enabled it emits all three signals, with traces covering every agent turn, model call, and tool execution, metrics covering token usage and runtime health, and structured log events for each session.\n\nWith full Qwen Code observability in SigNoz, you can see how many tokens your team is spending and on which models, how much of each prompt is served from cache, how many round trips a single request actually takes, which tools the agent reaches for, and how much you are paying for background work nobody asked for.\n\n## Prerequisites\n\n- SigNoz setup (choose one):\n[SigNoz Cloud account](https://signoz.io/teams/)with an active ingestion key- Self-hosted SigNoz instance\n\n- Qwen Code 0.21.15 or later, installed with\n`npm install -g @qwen-code/qwen-code`\n\n- Node.js 20 or later\n- A configured model provider, such as a DashScope API key or any OpenAI-compatible endpoint\n\n## Monitor Qwen Code with OpenTelemetry\n\nTelemetry is built into the CLI and turned off by default. Enabling it takes one settings block and one environment variable.\n\n**Step 1:** Enable telemetry in `.qwen/settings.json`\n\nCreate the file in your project directory, or in `~/.qwen/settings.json`\n\nto apply it to every project.\n\n```\n{\n  \"telemetry\": {\n    \"enabled\": true,\n    \"otlpProtocol\": \"http\",\n    \"otlpEndpoint\": \"https://ingest.<region>.signoz.cloud:443\",\n    \"metrics\": { \"includeSessionId\": true }\n  }\n}\n```\n\n**Step 2:** Set the ingestion key and service name\n\n```\nexport OTEL_EXPORTER_OTLP_HEADERS=\"signoz-ingestion-key=<your-ingestion-key>\"\nexport OTEL_SERVICE_NAME=qwen-code\n```\n\n**Verify these values:**\n\n`<region>`\n\n: Your[SigNoz Cloud region](https://signoz.io/docs/ingestion/signoz-cloud/overview/#endpoint).`<your-ingestion-key>`\n\n: Your SigNoz[ingestion key](https://signoz.io/docs/ingestion/signoz-cloud/keys/).\n\n**Step 3:** Run the agent\n\n```\nqwen \"list the files in this directory and summarise the project\"\n```\n\nSpans are batched, so allow a few seconds after the turn finishes before looking in SigNoz.\n\n## View Qwen Code Traces in SigNoz\n\nOpen the Traces explorer and filter on `service.name = 'qwen-code'`\n\n. Each turn arrives as its own trace.\n\nOpen any `qwen-code.interaction`\n\nspan to see the full turn. The waterfall shows each model call with the raw HTTP request underneath it, and each tool alongside the hook that fired for it.\n\nNote that the trace above reports three errors even though the root span status is `Ok`\n\n. All three are hook spans, and the warning below explains why that is expected.\n\nQwen Code emits six span names, and the hierarchy matters when you write queries:\n\n```\nqwen-code.interaction                 root, one per user turn\n├── qwen-code.llm_request             the model call\n│   └── POST                (CLIENT)  auto-instrumented HTTP to the provider\n└── qwen-code.tool\n    ├── qwen-code.tool.execution      child of qwen-code.tool, not a sibling\n    └── qwen-code.hook                fires per tool call\n```\n\n| Span | What it covers |\n|---|---|\n`qwen-code.interaction` | One user turn, the root span |\n`qwen-code.llm_request` | One model call, with tokens, finish reason, and time to first chunk |\n`POST` | The raw HTTP request to the provider, with status code |\n`qwen-code.tool` | One tool call, with the tool name and outcome |\n`qwen-code.tool.execution` | The execution phase of that same tool call |\n`qwen-code.hook` | The hook runner, invoked per tool call |\n\n## Attributes Worth Knowing\n\n`qwen-code.llm_request`\n\ncarries the token counts and model metadata. A few names differ from what you may expect from other agents:\n\n**There is no** Sum`gen_ai.usage.total_tokens`\n\n.`gen_ai.usage.input_tokens`\n\nand`gen_ai.usage.output_tokens`\n\ninstead.holds cached input tokens, and the segment is dotted rather than underscored.`gen_ai.usage.cache_read.input_tokens`\n\n, so values render as`gen_ai.response.finish_reasons`\n\nis a real array`[\"stop\"]`\n\nand`[\"tool_calls\"]`\n\nrather than as plain strings.**Reasoning tokens are**, not a`thoughts_token_count`\n\n`gen_ai.*`\n\nname. On current builds it reports zero.filters correctly when you quote the value (`success`\n\non`qwen-code.tool`\n\n`success = 'false'`\n\n) but does not group reliably, so build success-versus-failure breakdowns from two filtered queries rather than a`groupBy`\n\n.\n\n`session.id`\n\n, `gen_ai.conversation.id`\n\n, and `qwen-code.prompt_id`\n\ncorrelate spans across a whole session.\n\n## Background Subagents Spend Tokens You Did Not Ask For\n\nQwen Code runs background subagents, such as the auto-memory extractor and the dreamer, that make their own model calls. On a measured sample of 80 model calls, 18 of them, or 22%, came from background subagents rather than from a user prompt. A single \"What is 2+2?\" prompt triggered a subagent that consumed 7,004 input tokens on its own.\n\nNone of this is visible in the terminal. `llm_request.context`\n\nseparates the two cleanly: `interaction`\n\nfor calls made for a user turn, `standalone`\n\nfor background work. `subagent_name`\n\nnames the subagent on the calls that have one. Group token sums by `llm_request.context`\n\nto see what background work actually costs you.\n\n## Metrics and Logs\n\nAlongside traces, Qwen Code exports a full metric set including `qwen-code.token.usage`\n\n, `qwen-code.api.request.count`\n\n, `qwen-code.api.request.latency`\n\n, `qwen-code.tool.call.count`\n\n, `qwen-code.session.count`\n\n, `qwen-code.file.operation.count`\n\n, `qwen-code.cpu.usage`\n\n, and `qwen-code.memory.usage`\n\n. Histograms arrive split into `.bucket`\n\n, `.count`\n\n, `.sum`\n\n, `.min`\n\n, and `.max`\n\nseries.\n\nIt also emits structured log events per session, including `session.start`\n\n, `qwen-code.user_prompt`\n\n, `qwen-code.api_request`\n\n, `qwen-code.api_response`\n\n, `qwen-code.subagent_execution`\n\n, and `session.end`\n\n.\n\n## Qwen Code Observability Dashboard\n\nThe [Qwen Code dashboard](https://signoz.io/docs/dashboards/dashboard-templates/qwen-code-dashboard/) gives you token spend and cache efficiency, turn and session volume, model latency and time to first chunk, tool activity, and the user-driven versus background split out of the box.\n\n## Troubleshooting Qwen Code Observability\n\n### No data in SigNoz\n\nAn expired or wrong ingestion key fails silently. The CLI answers normally and exits successfully while the exporter receives a 401, so nothing in the terminal tells you anything is wrong. Test the key directly:\n\n```\ncurl -i -X POST \"https://ingest.<region>.signoz.cloud/v1/traces\" \\\n  -H \"content-type: application/json\" \\\n  -H \"signoz-ingestion-key: <your-ingestion-key>\" \\\n  -d '{\"resourceSpans\":[]}'\n```\n\nA working key returns `200`\n\nwith `{\"partialSuccess\":{}}`\n\n. An expired one returns `401`\n\nwith `Expired key`\n\n.\n\n### Telemetry is not being sent at all\n\nConfirm the settings file the CLI actually loaded. A `.qwen/settings.json`\n\nin a different project directory has no effect on the run you are debugging. Check that `telemetry.enabled`\n\nis `true`\n\nand that `otlpEndpoint`\n\ncarries no path: the exporter appends `/v1/traces`\n\nitself.\n\n### Everything looks like it is failing\n\nCheck whether the errors are `qwen-code.hook`\n\nspans. Those report an error by design with no hooks configured and are usually the large majority of error spans. Filter them out with `name != 'qwen-code.hook'`\n\n.\n\n### Tool call counts look twice as high as expected\n\n`qwen-code.tool.execution`\n\nis a child of `qwen-code.tool`\n\nand both carry `gen_ai.tool.name`\n\n. Scope tool queries to `name = 'qwen-code.tool'`\n\n.\n\n### Token totals come out empty\n\nThere is no `gen_ai.usage.total_tokens`\n\nattribute on Qwen Code spans. Sum `gen_ai.usage.input_tokens`\n\nand `gen_ai.usage.output_tokens`\n\ninstead.\n\n### Grouping by `success`\n\nreturns nothing\n\nFilter it with a quoted value instead, and use two filtered queries for a success-versus-failure split.\n\n## Related integrations\n\nInstrument the other AI coding agents your team runs, using the same OpenTelemetry pipeline:\n\n[Monitor Claude Code with OpenTelemetry](https://signoz.io/docs/claude-code-monitoring/)- token usage, cost, session activity, and tool decisions[Grok Build observability with OpenTelemetry](https://signoz.io/docs/grok-build-observability/)- another agent with a native exporter and no library to install[DeepSeek Harness observability with OpenTelemetry](https://signoz.io/docs/deepseek-harness-observability/)- an agent that instruments through a plugin instead[Monitor OpenAI Codex with OpenTelemetry](https://signoz.io/docs/codex-monitoring/)- trace Codex runs from the IDE extension and the CLI[Monitor GitHub Copilot with OpenTelemetry](https://signoz.io/docs/github-copilot-monitoring/)- trace Copilot chat requests, models, and token spend\n\nLooking for the Qwen model API rather than the CLI agent? See [Qwen observability](https://signoz.io/docs/qwen-observability/).\n\nBrowse [all LLM observability integrations](https://signoz.io/docs/llm-observability/) to instrument the rest of your stack.", "url": "https://wpnews.pro/news/qwen-code-observability-and-monitoring-with-opentelemetry", "canonical_source": "https://signoz.io/docs/qwen-code-observability", "published_at": "2026-08-24 00:00:00+00:00", "updated_at": "2026-08-25 04:43:37.307349+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-tools"], "entities": ["Alibaba", "Qwen Code", "OpenTelemetry", "SigNoz"], "alternates": {"html": "https://wpnews.pro/news/qwen-code-observability-and-monitoring-with-opentelemetry", "markdown": "https://wpnews.pro/news/qwen-code-observability-and-monitoring-with-opentelemetry.md", "text": "https://wpnews.pro/news/qwen-code-observability-and-monitoring-with-opentelemetry.txt", "jsonld": "https://wpnews.pro/news/qwen-code-observability-and-monitoring-with-opentelemetry.jsonld"}}