mcpField
O
opentelemetry

opentelemetry

github.com/mizchiクラウド・DevOps41644 回インストール2 週間前に更新
リポジトリ

opentelemetry について

OpenTelemetry の基本実践を扱うスキルで、シグナル選択、スパン設計、コンテキスト伝搬、サンプリング、OTLP エクスポートを解説します。サービス間のテレメトリー実装やトラブルシューティングを行う開発者向けです。

主な機能

  1. 01トレース、メトリクス、ログの選択
  2. 02スパン名、属性、イベント、エラー処理
  3. 03W3C コンテキスト伝搬
  4. 04サンプリング戦略の指針
  5. 05OTLP エクスポーター設定と注意点

活用シーン

  1. 01アプリケーションのシグナル選定
  2. 02分散リクエストのスパン設計
  3. 03コンテキスト断絶やエクスポート欠落の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mizchi/skills --skill opentelemetry

インストール後、Claude Code で/opentelemetryを入力して読み込まれたか確認します。

同梱ファイルREADME.md

詳細

OpenTelemetry — コアパターン

シグナルの選択

コードを書く前に、適切なシグナルを選びます。

シグナル用途コスト
Tracesリクエストのライフサイクル、レイテンシの帰属、分散システムにおける因果関係高(リクエストごと)
Metrics集計済みのカウント、レート、ヒストグラム — ダッシュボードやアラート低(事前に集計済み)
Logsコンテキストを伴う個別のイベント — エラー、監査、デバッグ中

目安:メトリクスは「どれくらいの頻度か/どれくらい速いか」、ログは「何が起きたか」、トレースは「なぜか」に答えます。メトリクスで十分な場合に、トレースを使わないでください。

スパンの設計

命名規則
<verb> <noun>         →  "fetch user", "send email"
<provider>.<operation> →  "db.query", "http.get", "cache.set"

可変データ(ID、値)をスパン名に含めないでください。代わりに属性を使います。スパン名はトレースインデックスのカーディナリティキーです。

属性
span.setAttributes({
  "db.system": "sqlite",
  "db.operation": "select",
  "db.sql.table": "users",
  "user.id": userId,          // high-cardinality: OK as attribute, not in name
});

既知の属性名(http.*、db.*、rpc.* など)には、OpenTelemetry Semantic Conventions に従ってください。バックエンドや APM はこれらを基準に処理します。

イベントと子スパン
  • イベント:現在の操作内の瞬間的な時点(span.addEvent("cache_miss"))
  • 子スパン:独自の所要時間を持ち、レイテンシが重要で、トレースのウォーターフォール表示に役立ちます
ステータスと例外
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
span.recordException(err);  // adds exception.type / exception.message / exception.stacktrace

エラー時には両方を呼び出してください。recordException だけではステータスは ERROR に変わらず、UI 上ではスパンが成功したように表示されます。

span.end() の保証
// ✓ callback form guarantees end()
tracer.startActiveSpan("operation", (span) => {
  try {
    return doWork();
  } catch (e) {
    span.recordException(e as Error);
    span.setStatus({ code: SpanStatusCode.ERROR });
    throw e;
  } finally {
    span.end();
  }
});

終了していないスパンはプロセッサーキューに残り、エクスポートされない可能性があります。

コンテキスト伝播

W3C TraceContext(traceparent / tracestate)が標準です。送信リクエストではインジェクトし、受信リクエストでは抽出します。

import { propagation, context } from "@opentelemetry/api";

// Outgoing HTTP
const carrier: Record<string, string> = {};
propagation.inject(context.active(), carrier);
fetch(url, { headers: carrier });

// Incoming (server handler)
const ctx = propagation.extract(context.active(), request.headers);
tracer.startActiveSpan("handle request", { context: ctx }, (span) => {
  // span is now a child of the upstream trace
});

最もよくあるバグ:受信したコンテキストを抽出せずにスパンを作成すると、トレースのウォーターフォールが、つながりのないルートスパンに分断されます。ルートのサーバースパンを開始する前に、必ず抽出してください。

サンプリング

戦略使用する場面
AlwaysOn開発環境/トラフィックの少ないステージング環境
TraceIdRatioBased(0.1)トラフィックの多い本番環境 — 新しいトレースの 10% をサンプリングします
ParentBased(root: TraceIdRatioBased)推奨されるデフォルト — 上流の判断を尊重し、新しいルートを指定した比率でサンプリングします
テールサンプリング(OTel Collector)ヘッドサンプリングの判断にかかわらず、エラーを 100% 取得する必要がある場合

ParentBased を使うと、上流がトレースをサンプリングしたのに下流が破棄するという失敗モード(ウォーターフォールの分断)を防げます。

OTLP エクスポーターの設定

import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";

const exporter = new OTLPTraceExporter({
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT + "/v1/traces",
  headers: { Authorization: `Bearer ${process.env.OTEL_API_KEY}` },
});

provider.addSpanProcessor(
  new BatchSpanProcessor(exporter, {
    maxQueueSize: 512,
    scheduledDelayMillis: 2000,
    exportTimeoutMillis: 10_000,
  })
);

本番環境では、非同期でオーバーヘッドの少ない BatchSpanProcessor を使ってください。SimpleSpanProcessor はイベントループをブロックするため、ローカルでのデバッグにのみ使用します。

よくある落とし穴

  • provider.register() が呼び出されていない:SDK は設定されていますが、何もエクスポートされません。インストルメンテーションが実行される前に呼び出してください。
  • ESM と自動インストルメンテーション(Node.js):ESM の静的インポートでは require-in-the-middle のフックが実行されません。回避策については otel-node を参照してください。
  • Cloudflare Workers:Node.js ランタイムがなく、fetch 境界でのインストルメンテーションが必要です。cloudflare-workers-otel-utels を参照してください。
  • スパン名に動的データが含まれている:トレースインデックスのカーディナリティが急増します。属性に移してください。
  • 送信呼び出しで W3C 伝播が行われていない:分散トレースが分断され、下流のスパンが孤立したルートとして表示されます。

コメント