Proxy Monitor:リクエストログ、フィルタリング、詳細復元とエクスポート
ローカルリバースプロキシは起動しましたが、401/429/500、ストリーミング中断、あるいは「なぜ突然アカウント/モデルが変わった」が発生すると、トラブルシューティングはすぐに当てずっぽうになりがちです。
このレッスンでは 1 つのことだけを解説します:Proxy Monitor を使って各呼び出しを「再現可能な証拠」に復元し、リクエストがどこから来たか、どのエンドポイントに打たれたか、どのアカウントを使用したか、モデルがマッピングされたか、そして Token 消費がどれくらいかを知ることです。
このレッスンでできること
/monitorページで録画を開始/一時停止し、Token Stats に影響するかどうかを理解- 検索ボックス、クイックフィルタ、アカウントフィルタを使って 1 つのリクエスト記録を迅速に特定
- 詳細ポップアップで Request/Response メッセージを確認してコピーし、失敗原因を再検討
- Proxy Monitor のデータ保存場所(
proxy_logs.db)とクリア動作を知る - 現在バージョンの「ログエクスポート」の実際の能力境界(GUI vs バックエンドコマンド)を理解
現在の悩み
- 「呼び出し失敗/タイムアウト」しか見えないが、アップストリーム、プロキシ、クライアント設定のどこで失敗したかわからない
- モデルマッピングまたはアカウントローテーションがトリガーされたと疑うが、証拠チェーンがない
- 1 つのリクエストの完全な payload(特にストリーミング/Thinking)を再検討したいが、ログに見えない
この方法をいつ使うか
- トラブルシューティングが必要:401 認証失敗、429 レート制限、5xx アップストリームエラー、ストリーミング中断
- 確認したい:あるリクエストが実際にどのアカウントを使用したか(
X-Account-Email) - モデルルーティング戦略を策定中、「クライアントモデル名 → 実際マッピングモデル名」を検証したい
🎒 始める前の準備
前提条件
Proxy Monitor が記録するのは「リバースプロキシサービスが受信したリクエスト」です。したがって、少なくともまず次のことを完了させる必要があります:
- リバースプロキシサービスが起動し、
/healthzにアクセスできる - 現在のリバースプロキシの Base URL とポートを知っている
まだ動かない場合は、まず ローカルリバースプロキシを起動して最初のクライアントを接続する を見てください。
Proxy Monitor とは?
Proxy Monitor は Antigravity Tools 内蔵の「リクエストログダッシュボード」です。各リクエストがローカルリバースプロキシに入ると、時間、パス、ステータスコード、所要時間、モデルとプロトコルを記録し、可能な限りレスポンスから Token 使用量を抽出します。また、単一の記録を開いてリクエストとレスポンスメッセージを確認し、失敗原因とルーティング/アカウント選択結果を再検討できます。
データ保存場所
Proxy Monitor のログはデータディレクトリ以下の SQLite に書き込まれます:proxy_logs.db。データディレクトリの探し方とバックアップ方法は、先に 初回起動時の必知事項:データディレクトリ、ログ、トレイ、自動起動 を復習してください。
コアコンセプト:注意すべき 6 つのフィールド
Proxy Monitor の 1 つの記録(バックエンド構造体 ProxyRequestLog)で、最も実用的なのは以下のフィールドです:
| フィールド | それで何の質問に答えるか |
|---|---|
status | 今回のリクエストは成功か失敗か(200-399 vs その他) |
url / method | どのエンドポイントに打たれたか(例:/v1/messages、/v1/chat/completions) |
protocol | これは OpenAI / Claude(Anthropic) / Gemini のどのプロトコルか |
account_email | 今回のリクエストで最終的にどのアカウントが使われたか(X-Account-Email レスポンスヘッダから) |
model / mapped_model | クライアントがリクエストしたモデル名が別のモデルに「ルーティング/マッピング」されたか |
input_tokens / output_tokens | 今回のリクエストの Token 使用量(抽出できた場合のみ) |
まず「概要」を使い、必要に応じて「詳細」を開く
リストページは概要のみを表示(request/response body なし)。1 つの記録を開くと、バックエンドから完全な詳細を読み込みます。これでリストが一度に大きなフィールドを引きすぎることを避けます。
さあ、一緒にやってみよう:1 回の呼び出しで「モニタリングループ」を完成
ステップ 1:まず「必ず現れる」リクエストを作成
なぜ Proxy Monitor はリバースプロキシサービスが受信したリクエストのみを記録します。まず最もシンプルなリクエストで「記録があるか」を検証し、その後フィルタリングと詳細について話します。
## 1) ヘルスチェック(必ず存在するエンドポイント)
curl "http://127.0.0.1:PORT/healthz"
## 2) もう一度 models をリクエスト(認証を有効にした場合、header を忘れずに)
curl "http://127.0.0.1:PORT/v1/models"## 1) ヘルスチェック(必ず存在するエンドポイント)
curl "http://127.0.0.1:PORT/healthz"
## 2) もう一度 models をリクエスト(認証を有効にした場合、header を忘れずに)
curl "http://127.0.0.1:PORT/v1/models"期待される結果:端末から {"status":"ok"}(または類似の JSON)と /v1/models のレスポンス(成功でも 401 でも可)が返される。
ステップ 2:Monitor ページを開いて「録画状態」を確認
なぜ Proxy Monitor には「録画/一時停止」スイッチがあります。現在の状態をまず確認しないと、ずっとリクエストしているがリストがずっと空ということがあります。
Antigravity Tools でサイドバーの API モニタリングダッシュボード(ルートは /monitor)を開く。
ページ上部にドット付きボタンがあるはずです:
┌───────────────────────────────────────────┐
│ ● 録画中 [検索ボックス] [更新] [クリア] │
└───────────────────────────────────────────┘「一時停止中」が見えたら、一度クリックして「録画中」に切り替える。
期待される結果:ボタン状態が「録画中」に変わる;リストに直前のリクエスト記録が現れ始める。
ステップ 3:「検索 + クイックフィルタ」で 1 つの記録を特定
なぜ 実際のトラブルシューティングでは、通常 1 つのフラグメントしか覚えていません:パスに messages がある、またはステータスコードが 401 である、またはモデル名に gemini がある。検索ボックスはこのような記憶のために設計されています。
Proxy Monitor の検索は、あなたの入力を「ファジーキーワード」として扱い、バックエンドで SQL LIKE でこれらのフィールドにマッチします:
urlmethodmodelstatusaccount_email
いくつかの典型的なキーワードを試すことができます:
healthzmodels401(ちょうど 401 を作成した場合)
また「クイックフィルタ」ボタンをクリックすることもできます:エラーのみ / Chat / Gemini / Claude / 画像生成。
期待される結果:リストにあなたが期待した種類のリクエストのみが残る。
ステップ 4:詳細を開いて「リクエストメッセージ + レスポンスメッセージ」を復元
なぜ リストは「何が起きたか」に答えるには十分ですが、「なぜ」に答えるには、通常完全なリクエスト/レスポンス payload を見る必要があります。
任意の記録を開くと、詳細ウィンドウがポップアップします。以下を重点的に確認できます:
プロトコル(OpenAI/Claude/Gemini)使用モデルとマッピングモデル使用アカウントToken 消費 (入力/出力)
その後ボタンでコピー:
リクエストメッセージ (Request)レスポンスメッセージ (Response)
期待される結果:詳細に 2 つの JSON(またはテキスト)プレビューがある;コピー後、チケット/メモに貼り付けて再検討できます。
ステップ 5:「ゼロから再現」が必要な場合、ログをクリア
なぜ トラブルシューティング時、最も怖いのは「古いデータが判断を干渉する」ことです。クリア後にもう一度再現すると、成功/失敗が非常に明確になります。
上部の「クリア」ボタンをクリックすると、確認ダイアログがポップアップします。
これは不可逆操作
クリアは proxy_logs.db 内のすべての記録を削除します。
期待される結果:確認後リストがクリアされ、統計数字が 0 に戻る。
チェックポイント ✅
- [ ]
/monitorで自分が送ったばかりの/healthzまたは/v1/models記録が見える - [ ] 検索ボックスで 1 つの記録をフィルタリングできる(例:
healthzを入力) - [ ] 1 つの記録を開いてリクエスト/レスポンスメッセージを見てコピーできる
- [ ] ログをクリアするとすべての履歴記録が直接削除されることを知っている
よくある落とし穴
| シナリオ | あなたが理解するかもしれないこと(❌) | 実際の挙動(✓) |
|---|---|---|
| 「一時停止中」= モニタリングオーバーヘッドが完全にない | 一時停止後リクエストが解析されないと思っている | 一時停止は「Proxy Monitor ログに書き込むかどうか」のみに影響。しかしリクエスト/レスポンス解析(ストリーミングデータの SSE 解析を含む)は依然として発生し、解析後のデータは保存されないだけ。Token Stats も依然として記録(モニタリングが有効かどうかにかかわらず)。 |
| バイナリ/大きなペイロードログが空 | モニタリングが壊れたと思っている | バイナリリクエスト/レスポンスは [Binary Request Data] / [Binary Response Data] と表示される。レスポンスボディが 100MB を超えると [Response too large (>100MB)] とマーク;リクエストボディが制限を超えると記録されない。 |
| Monitor で「誰がリクエストを開始したか」を見つけたい | クライアントプロセスまで追跡できると思っている | Monitor は HTTP 層情報(メソッド/パス/モデル/アカウント)を記録し、「呼び出し元プロセス名」は含まない。クライアント自身のログまたはシステムネットワークキャプチャと組み合わせてソースを特定する必要がある。 |
| モニタリング有効時に Token Stats データが異常 | 統計エラーだと思っている | モニタリング有効時、Token Stats が 2 回記録される可能性がある(1 回はモニタリング関数の先頭、1 回は非同期でデータベースに書き込む時)。これは現在バージョンのソースコードの挙動です。 |
エクスポートと長期保存:まず能力境界を明確に
1) GUI で現在何ができるか
現在バージョンの Monitor UI(ProxyMonitor.tsx)では、以下ができます:
- 検索/フィルタリング/ページング参照
- 詳細を開いて payload を確認してコピー
- すべてのログをクリア
しかし 「エクスポートボタン」は見つからない(ソースコードに該当する UI が見つからない)。
2) バックエンドにどのようなエクスポート能力があるか(二次開発向け)
バックエンド Tauri コマンドは 2 種類のエクスポート方式を提供します:
export_proxy_logs(file_path):データベース内の「すべてのログ」を JSON ファイルにエクスポートexport_proxy_logs_json(file_path, json_data):あなたが入力した JSON 配列を整形してファイルに書き込み(入力は配列形式である必要がある)
GUI を二次開発したい場合、または自分の呼び出しスクリプトを書きたい場合、これらのコマンドを直接再利用できます。
3) 最もシンプルな「エクスポート」:proxy_logs.db を直接バックアップ
Proxy Monitor は本質的に SQLite なので、proxy_logs.db を「トラブルシューティング証拠パッケージ」として一緒にバックアップすることもできます(例:token_stats.db と一緒に)。データディレクトリ位置は 初回起動時の必知事項 を参照。
おすすめ関連記事
- モデルマッピングを明確にしたい場合:モデルルーティング:カスタムマッピング、ワイルドカード優先順位とプリセット戦略
- 認証問題をトラブルシューティングしたい場合:401/認証失敗:auth_mode、Header 互換性とクライアント設定チェックリスト
- Monitor とコスト統計を組み合わせたい場合:次のセクションで Token Stats(
token_stats.db)を解説
このレッスンのまとめ
- Proxy Monitor の価値は「再現可能」:ステータスコード/パス/プロトコル/アカウント/モデルマッピング/Token 使用量を記録し、リクエスト詳細を提供
- 検索とクイックフィルタがトラブルシューティングエントリ:まず範囲を縮小し、その後詳細を開いて payload を見る
- ログをクリアすることは不可逆操作;エクスポートは現在「二次開発能力」と「データベースファイルバックアップ」に傾いている
次のレッスン予告
次のレッスンでは Token Stats:コスト視点の統計指標とチャート解説 を学びます。「高い気がする」を定量化可能な最適化に変えます。
付録:ソースコード参考
クリックしてソースコードの位置を展開
更新日時:2026-01-23
| 機能 | ファイルパス | 行番号 |
|---|---|---|
| Monitor ページエントリ(ProxyMonitor をマウント) | src/pages/Monitor.tsx | 1-12 |
| Monitor UI:テーブル/フィルタ/詳細ポップアップ | src/components/proxy/ProxyMonitor.tsx | 13-713 |
| UI:設定を読み込み enable_logging を同期 | src/components/proxy/ProxyMonitor.tsx | 174-243 |
| UI:録画切り替え(config 書き込み + set_proxy_monitor_enabled) | src/components/proxy/ProxyMonitor.tsx | 254-267 |
| UI:リアルタイムイベント監視(proxy://request)と重複排除 | src/components/proxy/ProxyMonitor.tsx | 273-355 |
| UI:ログクリア(clear_proxy_logs) | src/components/proxy/ProxyMonitor.tsx | 389-403 |
| UI:単一詳細ロード(get_proxy_log_detail) | src/components/proxy/ProxyMonitor.tsx | 505-519 |
| モニタリングミドルウェア:リクエスト/レスポンス取得、token 解析、monitor に書き込み | src-tauri/src/proxy/middleware/monitor.rs | 13-337 |
| ProxyMonitor:enabled スイッチ、DB 書き込み、イベント送信 | src-tauri/src/proxy/monitor.rs | 33-194 |
| サーバー側モニタリングミドルウェアマウント(layer) | src-tauri/src/proxy/server.rs | 183-194 |
| Tauri コマンド:get/count/filter/detail/clear/export | src-tauri/src/commands/proxy.rs | 180-314 |
| SQLite:proxy_logs.db パス、テーブル構造とフィルタ SQL | src-tauri/src/modules/proxy_db.rs | 1-416 |
| モニタリング設計説明(実装と異なる可能性あり、ソースコードを優先) | docs/proxy-monitor-technical.md | 1-53 |
キー定数:
MAX_REQUEST_LOG_SIZE = 100 * 1024 * 1024:モニタリングミドルウェアが読み取れる最大リクエストボディ(超えると読み取り失敗)MAX_RESPONSE_LOG_SIZE = 100 * 1024 * 1024:モニタリングミドルウェアが読み取れる最大レスポンスボディ(画像など大きなレスポンス用)
キー関数/コマンド:
monitor_middleware(...):HTTP 層でリクエストとレスポンスを収集し、monitor.log_request(...)を呼び出すProxyMonitor::log_request(...):メモリ + SQLite に書き込み、proxy://requestイベントで概要をプッシュget_proxy_logs_count_filtered(filter, errors_only)/get_proxy_logs_filtered(...):リストページフィルタリングとページングget_proxy_log_detail(log_id):単一ログの完全な request/response body をロードexport_proxy_logs(file_path):全量ログを JSON ファイルにエクスポート(現在 UI はボタンを公開していない)