オブザーバビリティ
監視できない監視システムは、ダッシュボード付きの死角にすぎません。そのため Yagra のすべての
バイナリ — コアとすべてのポーラー — は、追加設定なしで 3 つのシグナルを出力します。stdout への
構造化ログ、Prometheus の /metrics エンドポイント、そして(オプトインの)OpenTelemetry
トレースです。このページではそれぞれのシグナルに加えて、それらを判定結果としてまとめてくれる
組み込みの設定 ▸ システムヘルスページを扱います。
Yagra は自分自身を監視する
Section titled “Yagra は自分自身を監視する”自己観測のためのシグナルを一覧すると次のとおりです。
| シグナル | コア | ポーラー | 既定 |
|---|---|---|---|
| 構造化ログ(stdout) | ✔ | ✔ | 有効(info レベル) |
Prometheus /metrics |
✔ — API ポート上 | ✔ — ポート 9100 上 |
有効 |
ヘルスプローブ /healthz / /readyz |
✔ | — | 有効 |
| OpenTelemetry トレース | ✔ | ✔ | 無効 — YAGRA_OTEL_ENDPOINT でオプトイン |
| ホストリソース(CPU / ロード / メモリ / ディスク) | ✔ | ✔ | 有効 — 設定 ▸ システムヘルスにグラフ表示 |
ここに挙げたものはどれも追加のコンテナを必要としません。単一ノードのスタックは
docker compose logs と 2 つの HTTP エンドポイントのスクレイプだけで完全に観測できます。
コレクタが必要なのはトレーシングだけで、それも向け先を指定するまでは無効のままです。
Prometheus メトリクス
Section titled “Prometheus メトリクス”コアは API ポート(同梱の compose ファイルでは 8080)上で、REST API とヘルスプローブと
並べて /metrics を提供します。追加で公開するポートはありません。API に到達できるものなら
何でもコアをスクレイプできます。
各ポーラーは 0.0.0.0:9100 固定で自分の /metrics を提供します。既定の単一ノード compose は
このポートをホストに公開しません。ポーラーをホストネットワーキング(リモート拠点ポーラーの構成が
これに当たります)またはネイティブで実行したときに到達できます。ポートの全一覧は
ポートとファイアウォールを参照してください。
何が公開されているかの感触をつかむために、代表的な系列をいくつか挙げます。
| メトリクス | 何がわかるか |
|---|---|
yagra_core_is_leader |
アクティブなコアで 1、スタンバイで 0 — 高可用性のリーダーゲージであり、/readyz が答えているのと同じシグナルです |
yagra_mcp_tool_calls_total{tool,outcome} |
MCP を有効にしているときの、ツール別・結果別の MCP ツール呼び出し数 |
yagra_forward_dropped_total{reason} |
転送で破棄したレコード数と理由(queue_full、rate_limit、circuit_open など) — 中継先が遅れ始めたときに最初に見る場所です |
yagra_llm_calls_total{provider,outcome} |
AI 根本原因分析のプロバイダ別呼び出し数 — 課金される外部呼び出しなので、アラートを張る価値があります |
yagra_core_backfill_results_total |
ネットワーク分断のあと store-and-forward のリプレイ経路で取り込まれたポーリング結果 |
これはカタログではなくサンプルです — 集合は機能追加のたびに増えます。動作中のバージョンが 公開しているすべてを見るには、エンドポイントをスクレイプしてください。
ヘルスプローブ
Section titled “ヘルスプローブ”コアの API ポート上にある 2 つの認証不要なプローブが、「プロセスは生きているか」と 「トラフィックをここへ送ってよいか」を切り分けます。
GET /healthz— 死活。 高可用性のスタンバイを含め、動作中のコアなら常に200 okを 返します。バックエンドストアには一切触れないため、データベース障害でオーケストレータが まったく健全なプロセスを再起動してしまうことはありません。コンテナの再起動ポリシーに 使ってください。GET /readyz— リーダーとしてのレディネス。 現在リーダーを保持しているコアだけが200を返し、スタンバイは503を返します。ロードバランサのヘルスチェックをここに向ければ、 フェイルオーバー時にトラフィックがリーダーに追随します — 高可用性を参照してください。
単一コアのデプロイ(HA 無効、既定)では区別すべきスタンバイが存在しないため、/readyz は
コアが起動していれば単純に 200 です。
コアのコンテナイメージはこれを使った実際のヘルスチェックを備えており、同梱の compose ファイルは コアが応答を始めてから web コンテナを起動します — そのためコールドスタートで最初のリクエストが エラーになることはありません。
System health ページ
Section titled “System health ページ”設定 ▸ システムヘルスは、「Yagra 自身は大丈夫か」に対する WebUI の答えです。ブラウザ側で 判定を組み直すのではなく、サーバー自身の判定をそのまま表示します。
- バックエンドサービスへの到達性 — ストアごとに 1 行(PostgreSQL、Redis、VictoriaMetrics、 そして任意の VictoriaLogs と ClickHouse)とバスの行があり、サーバー側で計算した 「All reachable」/「Degraded」の総合バッジが付きます。将来の依存先をページが取りこぼしても、 黙って健全と読ませるのではなくバッジとの食い違いが目に見える形で現れます。
- ポーリングループの健全性 — スケジューラと受信のカウンタ。プールがどう処理されているか (作業セットか、レガシーなジョブ単位のフォールバックか。プールに生存する登録済みポーラーが いなければ後者は琥珀色になります)も含みます。
- ホストリソース — コアとすべてのポーラーについて、CPU・ロード・メモリ・ディスクを時系列で グラフ表示します。スナップショットを見るだけでなく、リソース逼迫が積み上がる様子を追えます。
ディスクのグラフがどのファイルシステムを対象にするかは、プロセスごとに
YAGRA_DISK_WATCH_PATHS で設定します — path または path=alias の項目をカンマ区切りで並べた
もので(既定は /=root)、alias が系列ラベルになります。詳細は
設定リファレンスにあります。
どちらのバイナリも構造化ログ(Rust の tracing 形式)を stdout に書き出すため、保持と転送は
コンテナランタイムが受け持ちます。
docker compose logs -f coredocker compose logs -f poller詳細度は標準の RUST_LOG 変数(既定 info)でフィルタします。コンポーネント単位の指定も
可能です。
RUST_LOG=yagra-core=debug,yagra-poller=debugログ行に認証情報が含まれることはありません — SNMP コミュニティ、SNMPv3 の認証情報、API トークンは、 ログでも API レスポンスでもメトリクスのラベルでも同様に伏せられます。
ディスク上のログ
Section titled “ディスク上のログ”docker logs を読むにはホスト上のシェルが要りますが、それはまさに閉じた環境で許可されていないものです。
そのままではパニックや OOM の痕跡が一切残りません。そこでコアは stdout に加えて、YAGRA_LOG_DIR へ
1 時間ごとの JSON Lines ファイルを書き、YAGRA_LOG_RETAIN_HOURS 本(既定 48、自動で刈られます)を保持
します。このディレクトリを名前付きボリュームに置けばログはコンテナより長生きするので、復旧後に取った
サポートバンドルにも、落ちた実行のログが含まれます。
同梱の compose ファイルでは既定で有効です。無効にするには .env で YAGRA_LOG_DIR を空にしてください。
書き込みはノンブロッキングで、ポーリングループを止めるくらいならログを落とします。ディレクトリが書けない
場合も起動失敗ではなく、警告のうえ stdout のみに縮退します。
ポーラーも同じ方法で有効にできますが、compose ファイルはポーラー用のディレクトリをマウントしていません (サポートバンドルが運ぶのはコアのログだけです)。ポーラーのハートビートカウンタ・ポーリングループ統計・ ホストリソースは、すでにバンドルに含まれています。
サポートバンドル
Section titled “サポートバンドル”外部から到達できない環境では、診断で一番厄介なのは「全体像を 1 つにまとめて外へ出すこと」です。
設定 ▸ システムヘルスからサポートバンドルをダウンロードできます(GET /api/v1/system/support-bundle?since_hours=N でも取得可)。中身は、実際に動いているバイナリの正体
(バージョンだけでなくイメージの source ref とビルドプロファイル)、システムヘルスの全セクション、
許可リスト方式の環境変数、チェックサム付きの適用済みマイグレーション、テーブル別サイズと接続数、
アクティブアラート、監査ログの末尾、コアの Prometheus スクレイプ、そしてコア自身のローテートログです。
データが軽々しく外へ出ない現場のための機能なので、アーカイブは外に出す前に中身を確認できるように
設計されています。全エントリが JSON かプレーンテキストで、MANIFEST.json には何を収録したかに加えて
何を意図的に外したかが理由付きで記載されます。
秘匿値の扱いは 2 段構えです。環境変数は許可リストで運びます — パスワードらしい名前を弾く拒否リスト
では、YAGRA_DATABASE_URL の userinfo に埋まった認証情報(実際に漏れるのはこれです)を取りこぼすから
です。そのうえで組み立てた全バイトを走査し、一致した場合は伏字ではなく書き出し自体を中止します。
想定外の経路で入り込んだ認証情報も捕まえるためです。中止時は 500 support_bundle_redaction_failed を、
どのファイルのどのルールかを添えて返します(値そのものは返しません)。
生成には ManageConfig + ManageCredentials + ViewAudit の 3 つすべてが必要です。監査ログや認証情報 レポートを、そのどちらの名前も冠していないエンドポイント経由で読む抜け道にしないためです。実質的には 管理者のみ、ということになります。
分散トレーシング
Section titled “分散トレーシング”トレーシングはオプトインです。YAGRA_OTEL_ENDPOINT(または標準の
OTEL_EXPORTER_OTLP_ENDPOINT)に OTLP/HTTP のコレクタを設定すると、コアとポーラーの両方がスパンを
エクスポートします。未設定のままならトレーシングのオーバーヘッドはゼロで — ログのみ — 単一ノードの
スタックにコレクタは要りません。
得られるのは、プロセス境界をまたぐポーリング 1 回ぶんのトレースです。コアのディスパッチスパン → ポーラーのプローブスパン → コアの結果取り込みスパン、加えてノースバウンド API リクエストごとのスパン。 トレースコンテキストはジョブと結果に相乗りしてバスを流れ、トレーシングが無効ならワイヤから 省かれ、古いポーラーからは無視されます — そのためローリングアップグレード中も安全です。
ローカルで試す。 同梱の compose ファイルには Jaeger のプロファイルが入っています。
docker compose --profile tracing upそのうえで docker-compose.yml の core と poller の両方のサービスで
YAGRA_OTEL_ENDPOINT: http://jaeger:4318 のコメントを外し、Jaeger UI を
http://localhost:16686 で開きます。
大規模ではサンプリングを。 そうしなければ、数万ノードが間隔ごとにポーリングするたびに トレースが 1 本ずつ出てしまいます。次を設定してください。
OTEL_TRACES_SAMPLER=parentbased_traceidratioOTEL_TRACES_SAMPLER_ARG=0.01parentbased_* のサンプラは、トレース 1 本ぶんのサンプリング判断をコア⇄ポーラーのホップを
またいで一貫させるため、断片ではなく完全なトレースの 1% が得られます。
本番では、エンドポイントを OpenTelemetry Collector に向け、そこから自分のトレーシング バックエンド(Tempo、Jaeger、Honeycomb など)へ転送してください。リモート拠点のポーラーには 到達可能な自分用のコレクタエンドポイントが必要です — トレースのエクスポートは NATS バスの上を 流れません。
- 設定リファレンス —
YAGRA_OTEL_ENDPOINT、YAGRA_DISK_WATCH_PATHS、RUST_LOG、そしてこのページで挙げたその他すべての変数。 - 高可用性 — 2 コア構成で
/readyzとリーダーゲージが どう振る舞うか。 - ポートとファイアウォール —
8080、9100、そしてコレクタの エンドポイントがファイアウォールルールのどこに収まるか。