Skip to Content
デベロッパーガイドDaemonオブザーバビリティとデバッグ

オブザーバビリティとデバッグ

概要

qwen serve は現在、OpenTelemetry スパン計装構造化ファイルログDaemonLogger)、リクエストごとのアクセスログ、デバッグ用 stderr ログ、構造化プリフライトセル、およびインメモリのパーミッション監査リングを備えています。このページは、現在のオブザーバビリティの全体像と、トリアージ時に注意すべきギャップについての実践的なガイドです。

現在利用できる機能

サーフェス場所目的
QWEN_SERVE_DEBUG stderr ログbridge.ts および各呼び出し箇所環境変数の値が 1 / true / on / yes(大文字小文字不問)の場合、qwen serve debug: ... の行を stderr に出力します。
OpenTelemetry スパン計装server.ts daemonTelemetryMiddleware各 HTTP リクエストは withDaemonRequestSpan でラップされます。属性にはルート、sessionId、clientId、ステータスコードが含まれます。パーミッションルートには専用のスパンがあります。プロンプトのライフサイクルはエンドツーエンドでトレースされます。設定は settings.jsontelemetry にあります。
DaemonLogger 構造化ファイルログserve/daemon-logger.ts構造化された JSON 形式のログ行がファイルに書き込まれます。起動時に daemon log -> <path> が出力されます。info / warn / error レベルをサポートし、routesessionIdclientIdchildPidchannelId などの構造化フィールドを持ちます。
リクエストごとのアクセスログミドルウェアserver.tsbearerAuth の前に登録)各リクエスト後に methodpathstatusdurationMssessionIdclientId をログに記録します。GET /health とハートビートはスキップします。4xx 以上は warn、成功時は info を使用します。
/healthserver.ts ルート死活確認プローブ。?deep=1 で拡張詳細を返します。
/capabilitiesserver.ts ルートプリフライトによる機能検出。11-capabilities-versioning.md を参照してください。
/workspace/preflightルート -> DaemonStatusProvider構造化された準備状態セル: Node バージョン、CLI エントリ、ripgrep、git、npm、および子プロセスが起動した後の ACP レベルのセル。
/workspace/envルート -> DaemonStatusProviderデーモンプロセスの環境変数スナップショット。シークレット環境変数は存在の有無のみ報告されます。プロキシ URL のクレデンシャルは除去されます。
/workspace/mcpルート -> bridge の extMethodプール、バジェット、および拒否状態のスナップショット。
/workspace/skills/workspace/providersルートACP 側のライブスナップショット。セッションが存在しない場合は空のアイドルデータを返します。
セッションごとの SSEGET /session/:id/eventsリアルタイムのイベントストリーム。
/demo デバッグコンソールGET /demopackages/cli/src/serve/demo.tsブラウザからアクセス可能なシングルページコンソール: チャット、イベントログ、ワークスペースインスペクター、パーミッション UX。ループバックでは http://127.0.0.1:4170/demo が SDK コードを書かずにエンドツーエンドを検証する最速の手段です。登録ルールは 02-serve-runtime.md にあります。
PermissionAuditRingpermission-audit.ts512 件のパーミッション決定をインメモリ FIFO で保持します。
Mediator の decisionReason 監査permissionMediator.tsパーミッションリクエストが解決された理由を説明する内部の構造化レコード。

現在存在しない機能

  • Prometheus / メトリクスエンドポイントはありません。 process_cpu_seconds_totalhttp_requests_totalevent_bus_queue_depth などは存在しません。
  • PermissionAuditRing 向けの外部監査シンクはありません。 リングは存在しますが、SIEM や外部ストレージへのファンアウトフックは実装されていません。

デバッグレシピ

1. デーモンは起動しているか?

curl -s http://127.0.0.1:4170/health # {"status":"ok"} curl -s 'http://127.0.0.1:4170/health?deep=1' | jq # {"status":"ok","workspaceCwd":"/path","sessions":N,...}

ループバックで 401 が返る場合は --require-auth が有効になっている可能性があります。起動時のログを確認するには、起動時に QWEN_SERVE_DEBUG=1 を設定してください。

2. どの機能がアドバタイズされているか?

curl -s http://127.0.0.1:4170/capabilities | jq

mcp_workspace_pool(F2 プールが有効か)、require_auth(強化されているか)、permission_mediation.modes(サポートされているポリシー)、および policy.permission(有効なポリシー)を確認してください。

3. デーモンホストの準備状態は正常か?

curl -s http://127.0.0.1:4170/workspace/preflight | jq

status: 'not_started' のセルは ACP レベルのものであり、最初のセッションがアタッチされた後にのみ表示されます。status: 'fail' のセルにはクローズドな errorKind が含まれます。18-error-taxonomy.md から構造化された修復手順を参照してください。

4. セッションの SSE ストリームをテールする

curl -N -H 'Accept: text/event-stream' \ -H 'Authorization: Bearer XYZ' \ -H 'X-Qwen-Client-Id: debug-tail' \ -H 'Last-Event-ID: 0' \ 'http://127.0.0.1:4170/session/<sid>/events'

-N は curl の出力バッファリングを無効にします。Last-Event-ID: 0id > 0 のリングイベントの再生をリクエストします。

5. パーミッションリクエストがこのように解決された理由は?

PermissionAuditRing はインメモリであり、現時点では HTTP エンドポイントがありません。QWEN_SERVE_DEBUG=1 を有効にして再現してください。メディエーターは各投票と決定に対して構造化された行を出力し、decisionReason.type も含まれます。後続の PR でリングを HTTP 経由で公開できます。

6. どのコンシューマーが遅いか?

キューが 75% に達したオーバーフローエピソードごとに slow_client_warning が一度発火します。セッションの SSE ストリームをサブスクライブして合成フレームを探してください。ペイロードには queueSizemaxQueuedlastEventId が含まれます。繰り返し警告が出る場合はスタックしたコンシューマー(通常はブロックされた SDK の for await ループ)を示しています。

7. MCP サーバーが拒否された理由は?

/workspace/mcp のセルごとの disabledReason: 'budget'refusedServerNames リスト、および mcp_child_refused_batch SSE イベントを組み合わせて確認してください。それらを /capabilitiesmcp_guardrails.modesenforce が有効か)および getReservedSlots() で確認できるライブの --mcp-client-budget 状態と比較してください。

8. デーモンがシャットダウンしない

最初のシグナルはグレースフルシャットダウンをトリガーします(02-serve-runtime.md を参照)。10 秒を超えてハングする場合は以下を確認してください:

  • ACP 子プロセスがグレースフルクローズに応答しなかった。
  • 長い SSE 接続が HTTP server.close()SHUTDOWN_FORCE_CLOSE_MS(5 秒)を超えて開き続けた。

2 回目の SIGTERM/SIGINT は意図的に bridge.killAllSync() + process.exit(1) をトリガーします。

フロー

典型的なトリアージフロー

状態とライフサイクル

  • QWEN_SERVE_DEBUGdebug-mode.tsisServeDebugMode() を通じてチェックのたびに読み取られます。変更に再起動は不要です。ただし、起動時に設定されていない場合、起動ログは利用できません。
  • PermissionAuditRing は 512 件の FIFO エントリに制限されており、古いレコードはサイレントに破棄されます。
  • DaemonStatusProvider はリクエストごとにセルを再構築しキャッシュしません。不必要な高頻度ポーリングは避けてください。

依存関係

  • デバッグ用 stderr には process.stderr.write を使用。
  • 構造化ファイルログには DaemonLogger を使用。
  • initializeTelemetry および createDaemonBridgeTelemetry を通じた OpenTelemetry SDK。
  • 環境変数とシグナル検査には node:process を使用。

設定

設定項目効果
QWEN_SERVE_DEBUG詳細な stderr ログを有効にします。17-configuration.md を参照。
settings.json telemetryOTel の動作を制御: enabledotlpEndpointotlpProtocol、およびシグナルごとのエンドポイント。
DaemonLogger ログパス起動時に生成され、daemon log -> <path> として stderr に出力されます。
PermissionAuditRing サイズ現在 512 にハードコードされています。
slow_client_warning しきい値0.75 / 0.375eventBus.ts にハードコードされています。

注意事項と既知の制限

  • DaemonLogger のファイルログは構造化されておりroutesessionIdclientId でフィルタリングできます。QWEN_SERVE_DEBUG の stderr ログは非構造化テキストのままです。
  • OpenTelemetry スパンにはリクエストごとの相関情報が含まれます。 各 HTTP リクエストのスパンはルート、sessionId、clientId の属性を持ち、トレーシングバックエンドで結合できます。
  • ACP レベルの /workspace/preflight セルはライブセッションが必要です。 アイドル状態のデーモンでは、auth / MCP / skills / providers が status: 'not_started' を示すことがありますが、これは想定された動作です。
  • /workspace/env はシークレットの存在のみ報告し、値は報告しません。 シークレットの存在自体が機密情報となる環境ではレスポンスを公開しないでください。
  • 監査リングはプロセスローカルであり、デーモン再起動時に履歴は失われます。
  • 負荷テストのレシピはここに記載されていません。 パフォーマンスベースラインは test/perf-daemon-baseline ブランチにあります。

参照

  • packages/cli/src/serve/daemon-status-provider.ts
  • packages/cli/src/serve/daemon-logger.tsDaemonLoggerbuildDaemonLogLine
  • packages/cli/src/serve/debug-mode.tsisServeDebugMode
  • packages/acp-bridge/src/permissionMediator.tsPermissionDecisionReason
  • packages/cli/src/serve/server.tsdaemonTelemetryMiddleware、アクセスログミドルウェア)
  • 設定: 17-configuration.md
  • エラー分類: 18-error-taxonomy.md
  • ユーザー操作ガイド: ../../users/qwen-serve.md
Last updated on