otel-instrument-feature について
既存プロジェクトの新しい業務処理に OpenTelemetry の計装を追加するスキルです。スパン、メトリクス、ログの選定や既存規約への準拠、出力されたテレメトリーの検証を支援します。
主な機能
- 01既存の OTel 設定を確認
- 02スパン、メトリクス、ログの指針
- 03低カーディナリティのメトリクス属性
- 04PII とエラー処理の規則
- 05テレメトリーのエンドツーエンド検証
活用シーン
- 01新しい HTTP ルートやジョブの計装
- 02エージェントツールへのテレメトリー追加
- 03業務処理に使うメトリクスの選定
- 04出力された OTLP シグナルの検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ superloglabs/ skills --skill otel-instrument-featureインストール後、Claude Code で/otel-instrument-featureを入力して読み込まれたか確認します。
詳細
新機能に OpenTelemetry を導入する
ユーザーのプロジェクトで新しい業務処理を書こうとしているとき、または書き終えた直後には、必ずこのスキルを使用してください。「新機能」とは、問題が起きたときに人間のオペレーターが後から見つけたいと思うものすべてです。新しい HTTP ルート、RPC ハンドラー、GraphQL リゾルバー、バックグラウンドジョブ、キューコンシューマー、cron タスク、CLI サブコマンド、エージェントツール、スケジュールされたワークフロー、またはユーザー向けフローの意味のあるステップを表すモジュールレベルの関数などが該当します。
単なる配線コード(純粋なヘルパー、型、設定など)の追加では、このスキルは必要ありません。リクエストを受け取り、処理を行って、副作用またはレスポンスを生成するコードを追加する場合は必要です。
ステップ 0 — OTel がすでに設定されているか確認する
計装する前に、既存のブートストラップを探してください。よくある例としては、telemetry.ts / observability.ts / instrumentation.ts / init_observability() モジュール、@vercel/otel の registerOTel(...)、NodeSDK/sdk-node の設定、Python の LoggerProvider + OTLPLogExporter、superlogHeaders(...)、または sl_public_ トークンを含むインラインの https://intake.superlog.sh エンドポイントなどがあります。
ブートストラップが見つからない場合、新機能のファイル内に独自のものを追加しないでください。プロジェクトにはまだ OTel の設定が必要であり、それは superlog-onboard スキルの役割であることをユーザーに伝えてください。そのうえで、新機能の実装を続け、ブートストラップの箇所に簡潔な TODO を 1 つだけ残します(各スパン/メトリクス/ログの呼び出し箇所には残さないでください)。これを理由に作業を止めないでください。
ブートストラップがある場合、コードを書く前に該当する補助スキルを読んでください。
otel-onboarding-style— 一般的な OTel の方針と属性の規約。otel-python-style— Python。otel-fastapi-style— FastAPI。otel-livekit-style— LiveKit エージェント。otel-nextjs-style— Next.js / Vercel。otel-expo-style— Expo / React Native。otel-supabase-edge-style— Supabase Edge Functions。otel-generic-style— その他(Go、Java、Ruby、Rust、.NET、PHP、Elixir、プレーンな Node など)。
ローカルの規約に合わせてください。編集するファイルですでに @superlog/otel-helpers の withSpan を使っている場合は、そのまま使い続けてください。tracer.startActiveSpan を直接使っている場合も、同じ方法を使い続けてください。既存の方法と併せて、別のスタイルを導入しないでください。
ステップ 1 — 新機能に必要なものを決める
計装を書く前に、新しい操作ごとに次のチェックリストを明確に確認してください。それぞれの質問への回答が「いいえ」で、その理由を説明する形でも構いませんが、必ず回答してください。
スパン — ほとんどの場合に必要
操作を 1 つのスパンで囲み、名前を domain.verb にしてください(order.submit、interview.create、email.send、job.reconcile、agent.run、voice.session、llm.generate_copy など)。スパンはヘルパーの内部ではなく、機能のエントリーポイントに置きます。
操作全体が既存の自動計装(HTTP サーバーのエントリー、DB クエリ、フレームワークのライフサイクル)でカバーされ、業務上意味のある処理が追加されない場合に限り、カスタムスパンを省略します。判断に迷う場合はスパンを追加してください。自動計装には、ドメイン操作に適切な名前や属性が設定されていないことがほとんどです。
スパンに設定する属性(利用可能なもののみ、PII は含めないでください)。
- オペレーターが検索に使うエンティティ ID:
tenant.id、workspace.id、org.id、user.id、order.id、job.id、request.id。範囲が限定された ID のみを使用してください。メールアドレス/電話番号/リクエスト本文全体は絶対に記録しないでください。 - 範囲が限定されたカテゴリ属性:
outcome(success/failure/skipped)、channel、kind、route、action。 - レイテンシーの説明に役立つ件数とサイズ:
batch.size、items.count、payload.bytes。 - プロバイダーの計装でまだカバーされていない LLM 呼び出し箇所:
gen_ai.provider.name、gen_ai.request.model、app.gen_ai.use_case、app.gen_ai.call_site。OpenInference/プロバイダーの計装で既に取得されている属性を重複して追加しないでください。
エラー時には、例外を記録し、スパンのステータスをエラーに設定します。その後、例外を再送出してください。握りつぶしてはいけません。
Metric — 意味のある状態遷移である場合、または重要なレイテンシーがある場合に追加します
カテゴリは3つあります。新機能に該当するものを判断してください。
- ビジネスカウンター — 意味のある結果が発生するたびに記録します:
orders.submitted、jobs.completed、emails.delivered、interviews.started、payments.failed。カーディナリティの低いディメンション(tenant.id、outcome、channel)をタグ付けします。生のユーザー ID や注文 ID はタグ付けしないでください。 - パフォーマンスヒストグラム — 人がテールレイテンシーを気にするような操作の所要時間を記録します。SDK が計測値を提供する場合は、二重に計測せず、既存のスパンのタイミングを再利用してください。そうでない場合は、スパンが対象とする境界と同じ範囲で
time.perf_counter/performance.now()を使って記録します。 - コスト — LLM の呼び出し箇所に限り、プロバイダーの計装がトークン使用量をすでに取得していない場合にのみ記録します。
unit="tokens"を指定したllm.tokens.input/llm.tokens.outputカウンターを使います。llm.cost_usdやアプリ側の料金メトリクスは追加しないでください。Superlog はプロバイダー、モデル、トークンのデータからコストを一元的に計算します。
メーターを取得し、計測器をモジュールスコープで作成してください。ホットパス内でメーターや計測器を作成しないでください。
Log — 人が経緯を知りたい場合に追加します
ログは、経緯(「バッチの照合を開始」「5xx の後、3回中2回目の再試行」など)や、対応が必要な例外的イベントに使います。プロジェクトで既存のロガーを使い、新しいロギングライブラリを導入したり、ログ呼び出しをヘルパーでラップしたりしないでください。
error レベルのログは、手動で介入しなければ操作を復旧できない場合に限ります。復旧可能な状況は warn 以下にしてください。
スパン内で出力されたログには、ブートストラップのログブリッジが正しく接続されていれば、trace_id / span_id が自動的に付与されます。相関付けを強制するために、ログ呼び出しの周囲に使い捨てのスパンを作成しないでください。
属性とメトリクスのディメンション
スパン属性では高カーディナリティ(個別の ID、件数など)を使用できますが、メトリクスのディメンションには使用できません。ディメンションの範囲を限定してください。メトリクスに order.id や request.id をタグ付けしたくなった場合、そのデータはカウンターではなくスパンに記録してください。
ステップ 2 — 計装を新機能と併せて実装する
新しい操作のエントリーポイントにスパンを追加してください。操作内のすべてのヘルパーに細かなスパンをばらまかないでください。適切な名前を付け、豊富な属性を持たせたスパン1つの方が、汎用的なスパン5つよりも有用です。サブスパンが有用なのは、人が個別に切り分けて把握したい実際のサブ操作がある場合に限ります(外部 API 呼び出し、レイテンシーが分かりにくい DB トランザクション、parse / validate / dispatch のような独立したフェーズなど)。
操作の成功時と失敗時の境界に、outcome をタグ付けしたカウンターを追加してください。テールレイテンシーが重要な箇所にはヒストグラムを追加してください。時間のかかる処理の経緯の開始時と終了時、および例外的な分岐にはログを追加してください。
個々の呼び出し箇所に、後方互換性のためのシム、機能フラグ、「テレメトリーのオン/オフ」切り替えを追加しないでください。プロバイダーが登録されていない場合は、SDK にすでに何もしない経路があります。必要な切り替えはそれだけです。
recordCounter、sendSuperlogSpan、withTelemetry、trackEvent のようなヘルパー API を独自に作らないでください。ネイティブの OTel API を使ってください(TS/JS では、ローカルのスタイルですでに使われている場合に限り、@superlog/otel-helpers の公開済み withSpan を使います)。
ステップ 3 — 新機能が説明した内容を出力することを確認する
プロジェクトの通常のエントリーポイントから機能をエンドツーエンドで実行します。curl でルートにアクセスする、CLI のサブコマンドを呼び出す、ジョブをキューに登録する、エージェントのツールを実行する、といった方法です。トレーサーをモックするユニットテストでは不十分です。目的は、実際の OTLP ペイロードがプロセスから送信されることを確認することです。
開発サーバーが OTLP エクスポーターの動作をログに出力する場合(またはプロジェクトにデバッグエクスポーターがある場合)は、次の点を確認します。
- 追加したスパンが、説明した名前と属性で出力されていること。
- 追加したカウンターが少なくとも一度は増加したこと。
- オペレーション内で出力されたログ行に
trace_id/span_idが設定されていること。
ブートストラップで生成された sl_public_ トークンを使用していて、サインアップがまだ完了していない場合、取り込み処理が 401/403 を返すのは想定どおりです。ここで確認したいのは「SDK がペイロードを生成して送信を試みた」ことであり、「取り込みが受け付けた」ことではありません。
スパンだけが出力され、メトリクスやログが出力されない場合、ブートストラップの配線に不備があります。これは superlog-onboard の問題であり、このスキルの問題ではありません。ユーザーにその旨を伝え、機能の作業を続けてください。
厳守事項
- スパン属性、メトリクスのディメンション、ログフィールドに PII を入れないでください。メールアドレス、電話番号、パスワード、トークン、リクエスト本文全体、メッセージの平文コンテンツは含めないでください。
- 生のユーザー ID/注文 ID/リクエスト ID をメトリクスにタグ付けしないでください。これらはスパンに記録してください。
- テレメトリー用のラッパー API を独自に作らず、ネイティブの OTel SDK と、ローカルのスタイル規約を使用してください。
- ログ行に
trace_idを付けることだけを目的として、使い捨てのスパンを開始しないでください。代わりにブリッジを修正するか、相関のないログを受け入れてください。 - 呼び出し箇所に LLM のコスト計算や価格表を追加しないでください。コスト計算は Superlog が一元的に行います。
- ブートストラップがない場合でも機能の作業を止めないでください。TODO を 1 つだけ残し、
superlog-onboardを実行するようユーザーに伝えてください。