observability について
サービスのテレメトリー、アラート、SLOを設計するエンジニアリングスキルです。構造化されたワイドイベントを軸に、OpenTelemetryやメトリクス、サンプリングのコスト面も扱います。
主な機能
- 01リクエスト単位の構造化ワイドイベント
- 02OpenTelemetryの計装ガイダンス
- 03メトリクスのカーディナリティとサンプリング
- 04SLI、SLO、エラーバジェットの実践
- 05アラート設計とテレメトリーテスト資料
活用シーン
- 01バックエンド、ワーカー、APIの計装
- 02SLOとエラーバジェット方針の策定
- 03アラート、サンプリング、テレメトリー費用のレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ citypaul/ .dotfiles --skill observabilityインストール後、Claude Code で/observabilityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
resources/node-patterns.mdreferences.mdslo-alerting.mdtesting-telemetry.md詳細
可観測性
まだ尋ねていない疑問に備えて計装しましょう。 モニタリングは予測した障害モードを検証しますが、可観測性があれば、予想もしなかった障害についてシステムに問いかけることができます。効果的なテレメトリは、「何が壊れているのか」(症状)と「なぜなのか」(原因)という2つの疑問に答えます。そのための労力の配分には偏りがあり、原因を列挙することよりも、症状の検出にずっと多くの労力をかけるべきです(Google SRE、分散システムのモニタリング)。
このスキルでは、テレメトリに何を含めるか、またそれをどう利用するかを扱います。twelve-factor スキルでは、ログの転送方法と形式(プラットフォームが収集するプロセスストリーム上の構造化レコード、レベル、タイムスタンプ)を扱います。hexagonal-architecture スキルでは、ポートとアダプターによるコードベースで計装コードをどこに配置するかを扱います。
詳細リソースは resources/ ディレクトリにあります。必要に応じて読み込んでください。
| リソース | 読み込むタイミング… |
|---|---|
node-patterns.md | Node/TypeScript サービスに OpenTelemetry を組み込む場合 — NodeSDK のセットアップ、--import による読み込み、ワイドイベントのミドルウェア、ログとトレースの相関、Collector の設定、セマンティック規約のチートシート |
slo-alerting.md | SLI/SLO の定義、バーンレートの計算、複数ウィンドウ・複数バーンレートのアラートルールの作成、ランブックの作成 |
testing-telemetry.md | 計装の Vitest テストを作成する場合 — インメモリーエクスポーター、ワイドイベントのフィールドの検証、テレメトリポート用のフェイク |
references.md | このガイダンスの根拠や原典を確認する場合 |
使用する場面
- 新規または既存のサービス(バックエンド、ワーカー、API)を計装する
- SLI/SLO またはエラーバジェットポリシーを定義する
- アラートを設計、レビュー、または整理する
- 「本番環境で何が起きているのか見えない」—未知の未知をデバッグする
- テレメトリのコスト、メトリクスのカーディナリティ、またはサンプリング戦略をレビューする
このスキルの対象外: 失敗している CI 実行の診断(ci-debugging)、ローカル環境と本番環境の差異(production-parity-skill-builder)、Core Web Vitals の最適化(インストールされている場合は core-web-vitals)。
ワイドイベント(標準ログ行)
推奨されるデフォルトは、サービスごと・リクエストごとに、構造化された情報密度の高いイベントを1件出力することです。 これはStripeの標準ログ行です。つまり、「主要な特徴を数多く含む、最後に出力する1本の長いログ行」です(Stripe)。また、最新の可観測性の中核となる「任意に幅を広げられる構造化イベント」でもあります(Charity Majors)。
仕組み:
- リクエストがサービスに入ると、ミドルウェアがリクエストスコープのアキュムレーターを作成します
- ビジネスロジックとミドルウェアは、処理の進行に応じてフィールドを追加します
- イベントはリクエストの終了時に一度だけ、
finally/ティアダウン処理で出力します。例外経路でも必ず出力されなければなりません。まさにそのときに必要だからです
構築ルール — 退出箇所は1つにし、例外で検証します。 Promiseベースのハンドラーでは、リクエストの解析やボディの読み取りも含め、例外が発生する可能性のある処理を始める前にtryを開きます。ビジネス処理の呼び出しだけでは不十分です。イベントを完了させる唯一の呼び出し箇所、つまり結果属性の設定、例外の記録、スパンの終了、またはレコードの出力は、対応するfinally内に置きます。この3つすべてを実行するヘルパーを使ってもかまいませんが、そのヘルパーはfinallyから呼び出し、ほかの場所からは呼び出しません。成功経路でヘルパーを呼び出し、finallyではスパンの終了やフラッシュだけを行う構成では、例外発生時にすべてのフィールドが失われます。作業完了と判断する前に、ハンドラー自身のcatchの外で例外を発生させるテストを実行し、結果を含むイベントが1件記録されることを確認してください。
含める情報:
| カテゴリ | フィールドの例 |
|---|---|
| リクエスト | メソッド、正規化されたルートテンプレート(利用できない場合は省略)、ステータス、所要時間 |
| アイデンティティ | ユーザー/プリンシパルID、認証方式、APIキーID |
| レート制限 | 許可の有無、クォータ、残量 |
| パフォーマンス | DBクエリ数、キャッシュヒット数、外部呼び出しの所要時間 |
| ビジネスコンテキスト | 該当したルール、拒否理由、機能フラグ |
| エラー | エラーコード、エラークラス、再試行回数 |
| 相関情報 | トレースID、リクエストID、ビルド/デプロイID |
高カーディナリティの識別子は、プライバシーポリシーに従ってイベントに含めます。リクエストID、ビルドID、プライバシー上の承認を得た、または仮名化された主体識別子があると、イベントの有用性が高まります。高カーディナリティはイベントにとっては利点ですが、メトリクスではコストの急増につながります。ただし、イベントに適していることは、個人データを出力してよい理由にはなりません(以下の「サンプリングとコストの経済性」および「テレメトリの衛生」を参照してください)。
ログ行をあちこちに分散させるよりも、この方法が優れているのは、データが結合済みの状態で届くためです。正規表現と推測を使って断片からリクエストを再構成するのではなく、完全な行をクエリできます。豊富な属性を持つOpenTelemetryのルートスパンも、同じパターンの有効な実装です。スパンを使って計測すれば、ワイドイベント派と分散トレーシング派の両方の要件を同時に満たせます。
柱について、率直に
業界では「三本柱」、すなわちログ、メトリクス、トレースと位置づけられています。これに対する本格的な批判は次のとおりです(Majors、「Observability 1.0 vs 2.0」)。三本柱は、ツールごとに散在する複数の信頼できる情報源、複数回保存される各リクエスト、エンジニアによる手作業での関連付け、そして柱ごとに増大するコストを意味します。代替案は、単一の信頼できる情報源である幅広い構造化イベントを用意し、そこからメトリクス、トレース、SLO を読み取り時に導出することです。
このプロジェクトの方針:
- 幅広いイベントを計装のデフォルトとします。 重複する計装を避け、将来の疑問に対応できる情報をより多く残せます。ただし、エクスポート、処理、保存には、明示的なテレメトリコストの予算が必要です。
- メトリクスにも依然として役割があります。 低コストで長期間保持できる集計やアラートの計算に役立ちます。ただし、ラベルの種類は厳密に制限します。
- トレースは構造を持つ幅広いイベントです。 サービス間の親子関係と因果関係を表します。OTel スパンで計装すれば、その両方を得られます。
正直な限界: すべてを読み取り時に導出するには、生イベントを大規模に集計できるバックエンドが必要です。どのスタックにもそのようなバックエンドがあるわけではありません。どちらの陣営にも盲目的に追従せず、幅広いイベントは常に出力してください(データこそ資産であり、バックエンドは変わります)。そのうえで、ダッシュボードとアラートルール用に、種類を限定した少数のメトリクスを維持してください。
OpenTelemetry:基盤
OpenTelemetry(OTel)は、ベンダーに依存しないテレメトリ生成の標準です。採用することで、計装を特定のバックエンドの選択に縛られずに済みます。
構成要素:
- シグナル — トレース、メトリクス、ログ。すべて OTLP 経由でエクスポートします。
- リソース属性 —
service.nameは必須です。すべてのバックエンドで、テレメトリを出力するサービスを識別します。 - セマンティック規約 — テレメトリをチームやツール間で関連付けられるようにする、標準化された属性名(
http.request.method、db.system)(セマンティック規約)。セマンティック規約で定義済みの属性名を独自に考案しないでください。 - コンテキスト伝播 — W3C の
traceparentヘッダーは、サービスをまたぐすべてのホップでトレース ID と親スパン ID を伝達します。これによって、分散トレースが初めて成立します(コンテキスト伝播)。ベンダー SDK、生成されたクライアント、手書きのヘッダーのいずれを介する場合でも、別のサービスへの送信リクエストをコードで構築するときは、独自の相関ヘッダーを書き込むのではなく、アクティブなコンテキストをそのリクエストのヘッダーに注入してください(propagation.inject(context.active(), headers))。 下流チームから「こちらの呼び出しと対応付けるために検索できるものがほしい」と求められた場合、相手が名前を知っているかどうかにかかわらず、それはtraceparentのことです。x-trace-id、x-correlation-id、または独自のキーに格納した単独のトレース ID では親スパン ID とサンプリングフラグが欠落し、標準ツールで何かと関連付けることもできません。 - Collector — 受信 → 処理 → エクスポートのパイプラインで、サービスのそばで動作します。コードを変更せずにバッチ処理、再試行、秘匿化、バックエンドの切り替えを行えるため、本番環境で推奨されるデフォルトです。デプロイが単純で、SDK/バックエンドの経路がバッファリング、再試行、バックプレッシャー、フィルタリング、運用上の要件を満たすことが明確に確認できる場合は、直接エクスポートの設計を文書化して採用してもかまいません(Collector)。
TypeScript での最小構成の導入: @opentelemetry/sdk-node + @opentelemetry/api + @opentelemetry/auto-instrumentations-node、node --import ./instrumentation.mjs(または開発時にレビュー済みでリポジトリにインストールされた TypeScript ランナー)を使ってアプリケーションコードより前に読み込む計装ファイル、OTLP エクスポーターです。自動計装によって HTTP/フレームワーク/DB のスパンを追加コストなしで取得できます。手動で属性を追加すると、トレースがクエリ可能になるビジネス上の意味を付与できます。初期化順序は重要です。アプリのモジュールより後に計装を読み込むと、何も取得できないまま気づかれずに動作します。resources/node-patterns.md を参照してください。
サンプリングとコストの経済性
カーディナリティのルール
メトリクス上のラベルの組み合わせが一意であるごとに、別の時系列が作成されます。既存の時系列が1,000本あるメトリクスに tenant_id(値が10,000個)を追加すると、時系列は11,000本ではなく1,000万本になります。アクティブな時系列ごとにメモリが必要となり、多くのベンダーは時系列ごと、またはカスタムメトリクスごとに課金します(Grafanaの高カーディナリティに関する記事)。
ルール:値の範囲が限定された低カーディナリティのディメンションはメトリクスに、値の範囲が限定されない高カーディナリティのディメンションはイベント/スパンに含めます。 リクエスト由来のラベルを安全に使えるのは、固定の許可リスト(既知のメソッドや結果カテゴリなど)に正規化した場合だけです。不明な値は _OTHER にマッピングするか、省略してください。ID、パス、クエリ文字列、任意のヘッダー、本文のフィールドなど、生の値や範囲が限定されない攻撃者制御の値は決して使用しないでください。「このメトリクスを顧客ごとに分けて表示できますか?」と聞かれたら、「その質問にはイベントストアが適しています」と答えます。
サンプリングの段階
| 段階 | タイミング | 方法 |
|---|---|---|
| サンプリングなし | ボリュームが小さい場合 | すべて保持します。サンプリングはコスト削減の手段であり、目的ではありません |
| ヘッドサンプリング | ボリュームが増えた場合 | トレース開始時に決定します(トレースIDに基づく確率的な判断)。一貫して伝播され、低コストですが、エラーを確実に捕捉することはできません |
| テールサンプリング | 完了したトレースの属性に基づく判断が必要な場合 | トレース全体の到着後に決定します。選択したエラーや外れ値を優先的に保持できますが、ステートフルなCollector層が必要です。バッファリング、スケーリング、運用コスト、ロックインの可能性が伴います |
SLOの計算に使用するストリームを、決して気付かれないままサンプリングしてはいけません。 そこでサンプリングが避けられない場合は、SLIの計算に反映してください。エラートレースの保持は個別に設定して確認してください。実際に保持される内容は、テールサンプリングのポリシーと容量によって決まります。
SLI、SLO、エラーバジェット
Google SRE本の定義では、SLIはサービスレベルを慎重に定義して定量化した指標、SLOはそのSLIの目標値、SLAは結果を伴うSLOです。エラーバジェットは100%からSLOを差し引いた値です。その目的はリリースを可能にすることです。ユーザーには違いが分からない100%を追い求めるのではなく、リリースにバジェットを使います。
SLIの選択肢(選ぶ際の参考となる指標であり、必須ではありません):
- RED — Rate(リクエスト数)、Errors(エラー)、Duration(処理時間)。リクエスト駆動型サービスごとに使用します。ユーザーエクスペリエンスを明示的に示す指標です(Tom Wilkie)
- USE — Utilization(使用率)、Saturation(飽和度)、Errors(エラー)。ハードウェアリソースごとに使用する、インフラストラクチャ中心の指標です(Brendan Gregg)
- 4つのゴールデンシグナル — レイテンシ、トラフィック、エラー、飽和度。見落とされがちな注意点が2つあります。失敗したリクエストのレイテンシは別に追跡してください(遅い500は、速い500とは異なる問題です)。また、平均値は裾の部分を隠してしまうため、ヒストグラムを使用してください。平均が100msで1,000 rpsの場合でも、リクエストの1%が5sかかることは十分にあり得ます(SRE本)
SLOの運用原則: SLOの数は絞り、それぞれを一文で説明できるほどシンプルにしてください。可用性、正確性、新鮮さは、有効なイベントに対する正常なイベントの割合として定義します。レイテンシ目標は、明示的な閾値を下回る有効なイベントの割合として定義します。レイテンシ分布の診断には、平均値ではなくパーセンタイルを使用してください。社外に公開する目標より、社内の目標をわずかに厳しく設定してください。目標を過剰に達成しないでください。ユーザーが依存するようになるのは、約束した信頼性ではなく、実際に提供する信頼性です。
アラート:症状、ページ通知、バーンレート
原因ではなく症状に対してページ通知します。「MySQL サーバーが停止しても、ユーザーは気にするでしょうか? いいえ、気にするのはクエリが失敗するかどうかです」(Rob Ewaschuk, My Philosophy on Alerting — SRE 書籍の第 6 章となった文書です)。原因に関するデータは、ページ通知ではなくダッシュボードやチケットに記録します。まれな例外は、差し迫っていて確実な原因(4 時間後のクォータ枯渇など)です。
**すべてのページ通知は、**緊急性があり、対応可能で、ユーザーに影響が見え、人間の判断が必要でなければなりません。ページ通知への対応をスクリプト化できるなら、スクリプト化してページ通知を削除します。誤ったページ通知を測定し、対応者の注意を繰り返し無駄にするアラートを修正または削除します。
デフォルトのアラート構成は、複数のウィンドウとバーンレートを組み合わせたアラートです(SRE Workbook)。バーンレートは、SLO に対してエラーバジェットを消費する速さです(バーンレートが 1 の場合、期間終了時にちょうど予算を使い切ります)。30 日間で 99.9% の SLO の場合:
| 重大度 | バーンレート | 長いウィンドウ | 短いウィンドウ | 消費した予算 |
|---|---|---|---|---|
| ページ通知 | 14.4 | 1 h | 5 m | 2% |
| ページ通知 | 6 | 6 h | 30 m | 5% |
| チケット | 1 | 3 d | 6 h | 10% |
短いウィンドウ(長いウィンドウの 1/12)は、問題がまだ発生していることを確認し、単純な閾値アラートで発生するリセット時の誤検知を解消します。精度、再現率、検出時間、リセット時間をすべて同時に高い水準にできる構成はこれだけです。その導出は resources/slo-alerting.md に記載されています。
**すべてのページ通知にはランブックへのリンクを付けます。**網羅的なトラブルシューティング手順ではなく、「このアラートの意味と、現在の緩和策」を簡潔に説明します。
構造化ログの作法
十二要素スキルでは、転送方法と形式(プラットフォームが収集するプロセスストリーム上の構造化レコード、認識されるレベル、ISO タイムスタンプ)を定めています。このセクションでは、内容の規律を扱います。
レベルのテスト(Dave Cheney より):定義上、問題は起きていないため「警告を読む人はいない」、そして「エラーをログに記録することで処理するなら、定義上、それはもうエラーではありません」。標準の 4 つのレベルは維持します。ただし、各行に Cheney のテストを適用します。すべての warn には明確な読み手が必要です。すべての error ログは、処理済みの失敗を二重に報告するものではなく、実際に未処理の失敗に対応していなければなりません。
**境界でログを記録し、その間は蓄積します。**リクエスト内で記録する info の雑多なログの多くは、個別の行ではなく、幅広いイベントのフィールドにします。40 行のログを出力するリクエストでも、標準イベント 1 件と、本当に独立した事実を記録する少数の行だけで済みます。
**相関付け:**すべてのログレコードにアクティブなトレース ID(W3C トレースコンテキスト)を含め、ログをトレースや標準イベントにそのまま関連付けられるようにします。
PII とシークレットの衛生管理:
- パスワード、トークン、API キー、Cookie、セッション ID を、いかなるシグナルにも出力しないでください
- 個人識別情報を出力するのは、明示された運用上の必要性があり、適用されるプライバシーポリシーで許可されている場合に限ります。最小化または仮名化し、適切な保持、アクセス、削除の管理を適用してください
- 名前を指定したフィールドを許可リストに登録します — リクエスト、ユーザー、設定の各オブジェクト全体をシリアライズしないでください。JSON シリアライザーは認証ヘッダーも簡単に出力してしまいます
- アプリ内の発生源で編集します。パイプラインは第 2 の防御線であり、第 1 の防御線ではありません
- 規制対象の環境では、PII を含むログ行はすべて、保持、アクセス制御、消去権に関するコンプライアンス上の義務を伴います
Effect のロギング
Effect ベースのランタイムでは、コンポジションから提供される Logger レイヤーを使って、ネイティブのロギングとアノテーションを優先します。単にこれらの機能を再現しているだけなら、受け渡し式の JavaScript ロガーコールバックや診断用ラッパーは削除してください。ドメインの観測は、以下のアーキテクチャルールに従ってください。ネイティブのロギングを理由に、純粋なドメイン上の判断へロガーを導入してはいけません。
成功だけでなく、失敗や中断も対象とする広域イベントには、スコープ付きファイナライザーまたは終了状態を認識する同等の仕組みを使います。Effect の構築を囲む JavaScript の finally では、その実行を監視できません。その境界イベントのために、安全なアノテーションをプログラム内で蓄積してください。
導入時には、ソースのリダクションとシンク障害の隔離を維持してください。JSON 出力だけでは、どちらも保証されません。インストール済みの本番用ロガーを確認し、操作を通じたテストで、シンクが失敗してもプロダクトの結果が変わらず、元の失敗が覆い隠されないことを確認してください。ネイティブの動作で隔離できない場合は、範囲を絞ったシンクアダプターを使います。固定バージョンの API 検証とランタイムのライフタイムルールについては、Effect ランタイムのコンポジションを参照してください。
計装を配置する場所(アーキテクチャ上の配置)
ポートとアダプターを用いるコードベースでは、可観測性コードには4つの配置場所があります。これは4層モデルです(詳しくは、hexagonal-architecture スキルの resources/cross-cutting-concerns.md を参照してください)。
- 技術的なテレメトリー → アダプター。 リクエスト/レスポンスのロギング、SQL の実行時間、リトライ、自動計装などです。ドメインコードには決して配置しません。
- ドメイン上重要な観測 → 明示的な駆動ポート(Domain Probe)またはドメインイベント。 中間のビジネス上の事実(「どの価格ルールが適用されたか」など)が重要な場合や、観測が要件(サポートログ、ビジネスメトリクスなど)である場合、可観測性バックエンドは、機能ごとに定義された、重要度を持たず、呼び出し後の結果を待たないポートの背後に置く駆動側のアクターです。汎用的な
Loggerポートを使ってはいけません。ドメインイベントがすでにある場合は、別のチャネルを増やすよりも、可観測性のサブスクライバーを使う方が適切です。 - 相関付けと広域イベントの組み立て → ミドルウェア/アダプターのみ。 ドメインがトレース ID を認識することはありません。ドメインの属性は、結果型、プローブ、またはイベントを通じて広域イベントに渡します。
- 計装はテスト対象の振る舞いです。 プローブは駆動ポートです。すべての駆動ポートにフェイクを用意してください(「可観測性のテスト」を参照)。
ヘキサゴナルアーキテクチャでなくても、同じ考え方が当てはまります。ビジネスロジックはデータを返し、事実を通知します。エッジがそれらをテレメトリーに変換します。
可観測性のテスト
計装は振る舞いであるため、振る舞いと同様にテスト駆動で開発します(tdd スキルと testing スキルを参照してください)。
- インメモリーエクスポーター — OTel SDK に付属しています — を使えば、ネットワーク呼び出しなしで、すべてのスパン、属性、ステータスを Vitest で検証できます。「このリクエストは
pledge.rejection_reasonを含む正規イベントを1つ出力する」「この失敗はスパンのステータスをエラーにする」などを確認できます。resources/testing-telemetry.mdを参照してください。 - テレメトリーポートにはフェイクを用意します。 ほかの駆動ポートと同様です。記録用フェイクで観測内容を蓄積し、公開 API を通じてテストで検証します。具体例は、
hexagonal-architectureスキルのresources/testing-hex-arch.mdを参照してください。 - アラートルールはコードです。 スタックが対応している場合(Prometheus ルールの単体テスト、SLO-as-code ツールなど)は、合成データでバーンレートの式が発火することをテストしてください。
- ミューテーションテストに関する注意: 検証されていないプローブ/テレメトリー呼び出しは、生き残るミュータントの温床です。これ自体が、観測内容を検証すべき理由です。
正直な限界: サンプリング率、Collector パイプライン、バックエンドの保持期間を有意義な形で単体テストすることはできません。実際の Collector を使ってステージング環境で検証してください。また、サンプリング設定も環境間の同等性に影響する要素です(ステージングが100%、本番が1%では、デバッグ時の挙動が異なります)。
フロントエンドに関する注記(v1の対象外)
ブラウザーのオブザーバビリティはRUM(リアルユーザーモニタリング)であり、Core Web Vitalsを標準のSLIとして使用します。実際のページ読み込みの75パーセンタイルで、LCP ≤ 2.5s、INP ≤ 200ms、CLS ≤ 0.1が基準です。ラボツールは「フィールド測定の代わりにはなりません」(web.dev)。このスキルではサービスを対象としています。ユーザー向けの部分については、インストールされている場合、core-web-vitalsおよびperformanceスキルを参照してください。
アンチパターン
| # | アンチパターン | 誤りである理由 |
|---|---|---|
| 1 | メトリクスに無制限のラベルを付ける(ユーザーID、生のURL、コンテナーID) | カーディナリティの爆発を招き、メモリ、クエリ時間、料金が系列ごとに増加します |
| 2 | 蓄積されたワイドイベントではなく、ログ行をあちこちに分散させる | コンテキストが断片化して届き、調査が正規表現を使った考古学になります |
| 3 | 例外が発生した経路で正規イベントを出力しない | 最も重要なときにイベントが消えてしまいます。finallyで出力してください |
| 4 | 原因(CPU、ディスク、レプリカの遅延)に基づいてページングする | ユーザーが体験するのは原因ではありません。症状に基づくページングなら、ノイズを抑えながら、より多くの問題を捉えられます |
| 5 | ランブックがない、または実行可能な対応がないページ | 対応できないページを出し続けると、人々はページを無視するようになります |
| 6 | オブジェクト全体をログにシリアライズする | 認証ヘッダー、トークン、PIIまで一緒に記録されます。名前を指定したフィールドの許可リストを使ってください |
| 7 | semconvですでに定義されている属性名を独自に作る | 何のメリットもなく、チーム間やツール間の相関付けを損ないます |
| 8 | SLOの計算に使うストリームを、気付かれないようにサンプリングする | SLIの計算が現実を反映しなくなります。エラーを100%保持するか、計算方法を調整してください |
| 9 | デバッグ用のconsole.logを「計測」として残す | 構造化されず、クエリできず、相関付けもできません。削除するか、実際のフィールドに格上げしてください。削除の対象はリクエストではなくファイルです。すでに編集しているファイルに、依頼されていない経路のこのノイズが含まれている場合は、そのファイルからすべて削除してください。中途半端に片付けると、誰もクエリできず、誰も戻ってこない行が残ります |
| 10 | OTelではなく、シグナルごとにベンダーのエージェントを導入する | 計測がバックエンドに固定されます。OTelならバックエンドを切り替えられます |
| 11 | エラーが発生するたびに即座にアラートを送る | エラーバジェットがあるのは、バーンレートのしきい値を下回るノイズをページャーに送らないためです |
境界
| 対象 | 担当 |
|---|---|
| ログの転送、stdout、JSONの形式、ログレベルの有無、タイムスタンプ | twelve-factor |
| テレメトリーに何を含めるか、ワイドイベント、トレース、SLO、アラート | このスキル |
| 失敗したCI実行の診断 | ci-debugging |
| テレメトリーのポート、ドメインプローブ、4層の配置に関する詳細 | hexagonal-architecture |
| 環境の差異(ローカルでは動くが、本番環境では動かない) | production-parity-skill-builder |
| HTTPエラーレスポンスの本文(RFC 9457) | api-design |
| CLIの利用テレメトリーに関する同意 | cli-design |
| Core Web Vitals/フロントエンドRUM | core-web-vitals(外部。インストールされている場合) |
検証チェックリスト
- 例外経路を含め、すべてのリクエストで正規のワイドイベントが必ず1つだけ出力される
- プライバシー上承認されたカーディナリティの高い識別子(subject、request、build、tenant)はイベント/スパンに記録し、メトリクスラベルには決して使用しない
- メトリクスラベルには、範囲が限定された正規化済みの許可リストを使用する。未知のリクエスト値は
_OTHERにマッピングするか省略し、攻撃者が制御する生の値をラベルにしない -
service.nameとリソース属性を設定し、セマンティック規約の名前が存在する場合はそれを使用する - トレースコンテキスト(W3C
traceparent)をすべてのサービス間ホップで伝播させ、すべてのログレコードにも含める - OTel SDKをアプリケーションコードの読み込み前に初期化(
--import)し、自動計装を有効にする - 本番環境のテレメトリには推奨されるCollector経路を使用する。または、バッファリング、再試行、バックプレッシャー、フィルタリング、運用要件を満たすことを文書化したうえで、直接エクスポートの例外を適用する
- サンプリングとCollectorの処理能力が、明示されたエラートレース保持目標と損失予算を満たす。目標がサンプリングによる損失を許容できない場合は、サンプリングなしで収集する
- 各ユーザージャーニーの比率ベースのSLOは、最大でも数個にする。レイテンシのしきい値と診断用パーセンタイルを明示し、エラーバジェットポリシーを定める
- ページングアラートは症状ベースかつ複数ウィンドウのバーンレートに基づくものとし、それぞれにランブックをリンクする
- 人が直ちに対応する必要のない条件では、ページングを発生させない
- テレメトリにシークレットを含めない。個人識別子は必要性とポリシー上の承認を満たし、最小化または仮名化する。フィールドは許可リストに基づき、ソースで秘匿化する
- 計装をテスト(インメモリエクスポーターまたはフェイクプローブのアサーション)でカバーする
- メトリクスラベルや新しいシグナルを追加する際は、カーディナリティとコストの見積もりを文書化する