observability について
本番システムの設計者向けに、メトリクス、ログ、トレース、ヘルスチェック、アラートの方針を決める可観測性スキルです。ユーザー視点の症状や SLO を軸に、負荷時の信頼性も検討します。
主な機能
- 01メトリクス・ログ・トレースの選択
- 02RED、USE、ゴールデンシグナルの適用
- 03LivenessとReadinessの分離
- 04SLOベースのアラート設計
- 05サンプリングとカーディナリティの評価
活用シーン
- 01本番サービスの監視計画
- 02SLOとエラーバジェットの定義
- 03サービス間リクエストの遅延調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ proyecto26/ system-design-skills --skill observabilityインストール後、Claude Code で/observabilityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/deep-dive.mdreferences/providers/aws.mdazure.mdgcp.mdgeneric.md詳細
可観測性
本番環境でシステムを可視化し、アラートを発し、デバッグできるように、何を測定するかを決めます。これを誤ると、失敗モード #6「失敗の無視」に陥ります。ホワイトボード上では動作する設計でも、高負荷時に状況が見えなくなり、障害の最初の兆候がページ通知ではなくユーザーからの苦情になってしまいます。
いつ使うか
本番環境向けの設計では、「これが壊れたら、どうすれば、どれくらい早く気づけるか」への答えが必要です。システムが何を測定するか、誰にページ通知するか、許容可能なサービスレベル(SLO)は何か、リクエストをサービス間でどうトレースするかを定義するときに使います。これにより、ほかのすべてのブロックのストレスに関する記述が現実のものになります。見えないフラッシュクラウドやホットシャードには対処できません。
使わない場合
プロトタイプや、ユーザーに迷惑をかける心配のない内部ツールに、メトリクス・ログ・トレースの完全なスタックを構築しないでください(YAGNI)。ヘルスチェックとエラーログで十分です。誰も擁護しないSLOをでっち上げたり、重要な症状を把握する前にアラートを設定したりしないでください。担当者もランブックもないアラートはノイズであり、チームがページ通知を無視するようになります。このスキルが扱うのは、何を測定し、アラートを発するかです。大量ログのパイプライン(収集 → バッファリング → 送信 → インデックス化 → 保持)はdistributed-loggingで扱います。ここでは要約してリンクするだけにし、再構築しないでください。
まず確認すること
- ユーザーの視点で「健全」とは何ですか? 悪い体験を定義する症状(チェックアウトの遅延、アップロードの失敗など)です。アラートはCPUではなく、この症状を対象にします。
- SLOの目標値と期間は? 例:30日間におけるリクエストの99.9%が300 ms未満。この値によってエラーバジェットとアラートのしきい値が決まります。(→ 9の並びについては
back-of-the-envelopeを参照してください。) - リクエスト量とカーディナリティは? QPSによってメトリクスやトレースのサンプリング率が決まります。カーディナリティの高いラベル(ユーザーID、URLなど)は、メトリクスストアを肥大化させます。
- リクエスト駆動ですか、それともリソース駆動ですか? 測定の枠組みとしてRED(サービス)とUSE(CPU/ディスク/キュー)のどちらを使うかが決まります。
- 複数のサービスを通るリクエストパスですか? リクエストがサービス間を通るなら、トレースが役立ちます。単一のサービスでは、まだ必要ない場合もあります。
選択肢
3つの柱(相互補完的であり、どちらか一方ではありません):
- メトリクス — 安価な数値時系列データ(カウンター、ゲージ、ヒストグラム)です。ダッシュボード、傾向分析、アラートに使います。常時取得するシグナルです。
- ログ — コンテキストを含む個別のイベントです。アラート発生後、特定の障害をデバッグするために使います。(ログを移動するパイプラインは
distributed-loggingで扱います。) - トレース — サービス間における1つのリクエストの経路と、各ホップの所要時間です。どのサービスや依存先が遅延やエラーの原因なのかを特定するために使います。
何を測定するか(コンポーネントごとに枠組みを選択します):
- RED(リクエスト駆動のサービス):Rate(リクエスト率)、Errors(エラー)、Duration(所要時間)です。API、Web層など、リクエストを処理するものに使います。
- USE(リソース):Utilization(使用率)、Saturation(飽和度)、Errors(エラー)です。CPU、メモリ、ディスク、コネクションプール、キューに使います。
- 4つのゴールデンシグナル(レイテンシ、トラフィック、エラー、飽和度)は、より包括的な指標です。サービスのデフォルトダッシュボードとして使います。
ヘルスチェック(シグナルはload-balancing/オーケストレーターが利用します):
- ライブネス — プロセスが稼働していて、デッドロックしていませんか?失敗した場合は再起動します。低コストに保ち、依存先はチェックしないでください。停止したプロセスの復旧に使います。
- レディネス — このインスタンスは今すぐトラフィックを処理できますか(依存先に到達可能で、ウォームアップが完了しているか)?失敗した場合は振り分け対象から外し、再起動しないでください。起動直後や不調なインスタンスを振り分け対象にするかどうかの判断に使います。
アラート:
- 症状ベース(SLOのバーン) — ユーザー向けSLOが危険にさらされたときにページ通知します。実行可能なアクションにつながり、ノイズが少ないため、デフォルトとして使います。
- 原因ベース(リソースのしきい値) — CPU、ディスク、飽和度についてチケットを作成するか、警告を出します。キャパシティプランニングに使い、ページ通知には使いません。
トレードオフ
| 選択肢 | 解決する問題 | 悪化させる問題 | 切り替えるタイミング |
|---|---|---|---|
| メトリクス | 低コストで常時稼働するアラートとトレンド把握 | リクエストごとの詳細は分からず、高カーディナリティのラベルはストレージやコストを急増させます | 特定のリクエストをデバッグする必要がある場合 → トレース/ログを追加します |
| ログ | インシデントのデバッグに役立つ豊富なコンテキスト | 量とコストが増加し、規模を拡大するには distributed-logging パイプラインが必要です | ログ量を管理できない場合 → サンプリングするか、詳細をメトリクスに移します |
| トレース | サービス間で遅延や障害のあるホップを特定します | 計装に手間がかかり、高い QPS ではサンプリングが必要です | 単一サービスまたは低トラフィックの場合 → 後回しにします。メトリクスで十分です |
| RED | リクエストを処理するサービスに適した視点です | リクエストに影響が出ていないリソース枯渇は見逃します | コンポーネントがリソース(キュー、ディスク)の場合 → USE を使います |
| USE | ユーザーに影響が出る前に飽和を検出します | ユーザー中心ではなくリソース中心で、ノイズが多くなることがあります | これを基にアラートを出す場合 → 症状/SLO ベースに切り替えます |
| ライブネスチェック | デッドロックしたプロセスを復旧させます | 積極的すぎると再起動ループを招き、実際のバグを覆い隠します | 再起動によってクラッシュループが隠れている場合 → レディネス/根本原因を修正します |
| レディネスチェック | 起動直後や異常のあるインスタンスを負荷分散の対象から除外します | 不安定な依存先をチェックするとフラッピングし、容量が上下します | すべてのインスタンスで同時にレディネスチェックが失敗する場合 → 依存先の障害です |
| SLO/エラーバジェット | アラートとリリースのペースをユーザーへの影響に結び付けます | 定義と維持に手間がかかり、不適切な SLO は誤解を招きます | バジェットがまったく消費されない(緩すぎる)か、常に消費される(厳しすぎる)場合 |
| 症状ベースのアラート | ノイズが少なく、対応につながるページ通知 | 根本原因の特定がやや遅くなります | より迅速に原因を特定する必要がある場合 → 原因ベースのチケットを追加します(ページ通知ではありません) |
ストレス下での動作
オブザーバビリティが最も必要とされるのは、まさにそれが破綻したり、誤解を招いたりしやすいときです。
- モニタリングが障害を増幅します。 リクエスト処理経路上で同期ログを記録すると、ログバックエンドの遅延がリクエストのレイテンシに影響します。サンプリングなしでリクエストごとにトレースをエクスポートすると、スパイク時にコレクターがパンクします。テレメトリーは非同期かつサンプリングありにして、低下させるのはシグナルだけにし、サービスには影響させないようにします。
- ヘルスチェックの集中。 積極的すぎるライブネスプローブは、単に遅くなっているだけのインスタンスまで再起動します。また、レディネスがフラッピングすると、スパイクの最中に容量が引き抜かれ、スパイクをさらに悪化させます。ゲーティング/復旧の動作は
load-balancingとresilience-failureが担当し、このブロックでは安定したシグナル(適切な閾値、連続失敗回数、ライブネスではなくレディネスに依存先を含めること)を定義します。 - カーディナリティの爆発。
user_idや生の URL のようなラベルは時系列を数百万件に増やし、負荷時にメトリクスストアを OOM に陥らせます。高カーディナリティのディメンションは削除するか、バケット化します。 - アラートの嵐。 1 つの根本原因(DB 障害)から相関するアラートが 50 件も発火し、オンコール担当者が対応に追われます。ユーザーに見える症状を基にアラートを出し、下流のアラートをグループ化/抑制します。
- 復旧時の見落とし。 インシデント後のダッシュボードには、修正が機能したか、また復旧時のトラフィックがコールド状態のティアに過剰な負荷をかけていないかを表示する必要があります。
監視対象: サービスごとの 4 つのゴールデンシグナル(レート、エラー、レイテンシ p50/p95/p99、飽和度)、SLO エラーバジェットの消費率、正常なホスト数とプローブのフラップ率、そしてテレメトリーパイプライン自体の遅延/ドロップ率(監視対象を監視します)。
適用方法
- 入力を明確にする — ユーザーが直面している症状、SLO の目標値と期間、リクエスト量とカーディナリティ、経路が複数サービスにまたがるかどうかを確認します(「まず明確にする」を参照)。まだ SLO がない場合は、まず症状を定義します。数値はその後です。
- トレードオフ表をもとに柱を選び、方針を定める — アラートには常にメトリクスを使います。サービスには RED、リソースには USE を使い、リクエストがサービス間をまたぐ場合や、リクエスト量に見合う場合にのみトレースを追加します。
- 主要な設定値を決める — ライブネスとレディネスのエンドポイント(依存関係の確認はレディネスに含め、ライブネスには含めません)、連続失敗のしきい値、トレースのサンプリング率、SLO とエラーバジェットのポリシーを定義します。カーディナリティの高いラベルは最初から除外します。
- 選択をストレステストする — 「高負荷時の挙動」を確認し、テレメトリが非同期かつサンプリングされていること、プローブが一斉に集中しないこと、カーディナリティに上限があること、アラートが根本原因ごとにグループ化されていて、一度の障害で50件ものページが発生しないことを確認します。
- 数値を使って規模を見積もる — メトリクス系列数と保持期間、QPS に対するトレース/ログのサンプル量、SLO の 9 がアーキテクチャの冗長性と一致していることを妥当性確認します(→「重要な数値」)。
- プロバイダーを選ぶ — 既定では汎用レシピを使います。ユーザーがクラウドを指定した場合にのみ、プロバイダー別のファイルを開きます(「プロバイダーの選択」を参照)。
- 回答でトレードオフを示す — ここで行った選択ごとに1行を設けた
Decision | Solves | Worsens | Change it when…テーブルを提示します(例:選択肢、そのストア、障害時のポリシー)。最後の列には具体的な変更のきっかけ(数値または観測可能なシグナル)を記載します。その後、最初に破綻するものを明示します。
すべきこと、避けるべきこと
すべきこと
- ユーザーに影響する症状(SLO の消費)に対してアラートを発報し、すべてのページに実行可能なランブックを用意します。
- 依存関係の確認は readiness に含め、liveness は軽量で依存関係のない状態に保ちます。
- テレメトリは非同期でサンプリングして出力し、レイテンシの増加やコレクターの過負荷を防ぎます。
- 実際に維持する意思のある SLO とエラーバジェットを定義し、リリースのペースと連動させます。
- 4つのゴールデンシグナルを使った、サービスごとのダッシュボードを標準化します。
避けるべきこと
- 原因(CPU > 80%)をページの対象にしないでください。これらはチケットにし、ページはユーザーの痛みに対して発報します。
- カーディナリティの高いラベル(ユーザー ID、生の URL)をメトリクスのディメンションに使わないでください。
- ライブネスで下流の依存関係を確認しないでください。システム全体が再起動ループに陥ります。
- プロトタイプにフルスタックを構築したり、担当者のいないアラートを設定したりしないでください(YAGNI/アラート疲れ)。
- ここでログパイプラインを再実装しないでください。それは
distributed-loggingの役割です。
重要な数値
SLO がほかのすべてを決めます。30日間で 99.9% の場合、許容されるエラーバジェットは約43分です。アーキテクチャの冗長性でその 9 の数を達成できないなら、その SLO は現実離れしています(可用性の 9 の数の表については back-of-the-envelope を参照)。平均値ではなく p95/p99 に対してアラートを発報してください。平均値ではテールの痛みが隠れてしまいます。QPS が高い場合はトレースをサンプリングし(多くの場合 1~10%)、コストがトラフィックに対して劣線形に増加するようにします。メトリクスの カーディナリティ に注意してください(系列数 ≈ ラベル値の積)。上限のないラベルが1つあるだけで、数百万の系列が発生する可能性があります。レイテンシ/QPS/9 の数の表をここで再掲しないでください。それらは back-of-the-envelope にあります。
インターフェースの概要
テレメトリには、明確に定めておく価値のある契約があります。メトリクス:名前+ラベルのセット+型(http_requests_total{service,method,status} カウンター)。ラベルのカーディナリティは低く保ちます。ヘルスエンドポイント:デバッグ用にバージョン/ビルド情報を本文に含め、GET /livez → 200/503(プロセスのみ)、GET /readyz → 200/503(依存関係+ウォームアップ)を返します。トレースコンテキスト:すべてのインバウンド/アウトバウンド呼び出しで伝播される trace_id + span_id(例:W3C の traceparent ヘッダー)。これにより、トレースとログを関連付けられます。
プロバイダーの選択
既定では、上記の汎用レシピを使います(Prometheus + Grafana + Loki + Jaeger を OpenTelemetry で連携させます)。ユーザーがクラウドを指定した場合は、マネージドサービスへの対応付け、クォータ/制限、プロバイダー固有のトレードオフについて、references/providers/<provider>.md を確認します。そのプロバイダー用のファイルがない場合は、汎用レシピを回答とします。
図
テレメトリーのフロー(app → OpenTelemetry SDK → collector → metrics /
logs / traces backends → dashboard + alertmanager)や、アラートからページ通知までの経路を可視化するには、プラグイン内の architecture-diagram スキルを使用します。テレメトリーのエクスポートでは、リクエスト処理経路外であることを示すために破線の矢印を使用します。
関連する構成要素
distributed-logging— この概念の所有元はこちらです。大量ログのパイプライン(収集 → バッファリング → 送信 → インデックス化 → 保持)を扱います。このスキルは、何をログに記録してアラートの対象にするかを決め、そちらのスキルは、大規模環境でそれをどのように移動して保存するかを決めます。resilience-failure— このスキルと連携します。アラートと SLO のバーンは、グレースフルデグラデーションとサーキットブレーカーを作動させます。また、ここで定義するヘルスチェックのシグナルは、フェイルオーバーとload-balancingが使用するヘルスゲーティングへの入力になります。scaling-evolution— このスキルへの入力になります。飽和度メトリクスとゴールデンシグナルによって、次のスケーリング段階を正当化する次のボトルネックが明らかになります。back-of-the-envelope— このスキルへの入力になります。可用性のナインと QPS を提示し、SLO とサンプルレートを実数値に変換します。system-design— この概念の所有元はオーケストレーターです。推論ループ、トレードオフの手法、10 個の障害モード(このブロックは #6 に対処します)を扱います。
参考資料
references/deep-dive.md— 基盤となる仕組み(ヒストグラムとゲージの比較、プッシュとプルの比較、サンプリング)、SLI/SLO/エラーバジェットの計算とバーンレートアラート、RED/USE の詳細、ヘルスチェックの調整、アラート設計を解説します。可観測性レイヤーを詳しく設計する際にお読みください。references/providers/{generic,aws,azure,gcp}.md— 環境ごとのサービス対応関係、制限、注意点を説明します。