o11y-logging について
o11y-loggingは、システム、Worker、Gatewayのコードで構造化オブザーバビリティを追加・調査するJoelClawスキルです。イベント規約、送信経路、検証手順を定め、サイレント障害やリプレイ時の重複を抑えます。
主な機能
- 01標準化された構造化イベント契約
- 02WorkerとGatewayの送信パターン
- 03イベント項目と重大度の規約
- 04OTEL配信とスモークチェック
- 05Inngestのリプレイとハングの調査
活用シーン
- 01WorkerやGatewayの変更へのテレメトリー追加
- 02オブザーバビリティデータの配信先確認
- 03Inngestリプレイ後のイベント重複の調査
- 04停止または失敗した永続実行の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ joelhooks/ joelclaw --skill o11y-loggingインストール後、Claude Code で/o11y-loggingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlassets/small-logo.svgreferences/implementation-checklist.mdscripts/otel-smoke.sh詳細
JoelClaw のオブザーバビリティとログ記録
デフォルトでサイレント障害を防ぎます。オブザーバビリティは任意の仕上げではなく、完了に不可欠な要素です。
必須ルール
- 正式なイベント契約のみを使用します。
packages/system-bus/src/observability/otel-event.tspackages/system-bus/src/observability/emit.tspackages/system-bus/src/observability/store.ts
- Worker/Inngest のコードは、
emitOtelEventまたはemitMeasuredOtelEventを通じてイベントを出力します。 - Gateway のコードは、
emitGatewayOtelを通じてイベントを出力します。 - 内部での取り込みには、アドホックな書き込みではなく、
POST /observability/emit(packages/system-bus/src/serve.ts)を使用します。 console.logを主要なオブザーバビリティ手段として扱ってはいけません。構造化イベントを信頼できる唯一の情報源として維持します。- カーディナリティの高い値は、ファセットフィールド(
source、component、level、success)ではなく、metadataに格納します。 - 失敗時は、意味のある
errorとともにsuccess: falseを設定します。 - 現在のテレメトリ設定で必要なシンクへの配信を確認します。まずミラーが有効かどうかを調べます。廃止済みまたは任意のミラーは、無関係な作業の妨げにはなりません。
- Inngest の耐久関数では、「一度だけ出力する」テレメトリは必ず
step.run(...)内に置き、再開後のリプレイによる重複を防ぎます。
イベントの規約
source:サブシステム(worker、gateway、webhook、memory、verificationなど)component:安定したモジュール/サービス名(check-system-health、redis-channel、observe)action:安定したドット区切りのアクション(system.health.checked、events.immediate_telegram)metadata:リクエスト ID、デプロイ ID、関数 ID、セッション ID、ペイロード識別子duration_ms:時間を計測する操作には含めます
イベントごとに、幅広いコンテキストを持つイベントを各主要な境界/操作で 1 つ出力します。文字列ログをあちこちに散在させる方式は使いません。
実装ワークフロー
- 変更対象の境界を特定します。
- Inngest 関数、gateway チャネル、webhook ルート、API ルート、バックグラウンドジョブ、同期ステップ。
- 成功時と失敗時のエンベロープを追加します。
- 長時間のタスクでは開始時と完了時、短時間のタスクでは完了時に 1 つのイベントを出力します。
- 運用上およびビジネス上のコンテキストを
metadataに含めます。- 例:関数 ID、イベント ID、プロバイダー、キューの深さ、影響を受けるリソース ID。
- 重大度は適切に設定します。
- 通常の動作には
debug/info、復旧可能な劣化にはwarn、失敗にはerror/fatalを使用します。
- 通常の動作には
- 完了前に検証ゲートを実行します。
チェックリストとコマンドの詳細については、references/implementation-checklist.md を参照してください。
クイックパターン
Worker/Inngest の時間計測対象の操作
import { emitMeasuredOtelEvent } from "../../observability/emit";
await emitMeasuredOtelEvent(
{
level: "info",
source: "worker",
component: "content-sync",
action: "content_sync.run",
metadata: { trigger: event.name },
},
async () => {
await runSync();
}
);
Gateway からのイベント出力
import { emitGatewayOtel } from "../observability";
await emitGatewayOtel({
level: "error",
component: "redis-channel",
action: "events.immediate_telegram",
success: false,
error: "telegram_send_failed",
metadata: { sessionId, queueDepth },
});
CLI からのイベント出力
JSON コンテキストには --metadata を使用します。--attributes フラグはありません。
joelclaw otel emit "task.completed" \
--source system \
--component skills \
--success true \
--metadata '{"session":"NimbleBadger","task":"install wzrrd-publish skill"}'
完了の定義
- 変更したパスに構造化 OTEL イベントが追加されている。
- オブザーバビリティデータを Typesense/Convex に直接書き込む、機能レベルの処理がない。
- スモークプローブが成功する(
scripts/otel-smoke.sh)。 joelclaw otel listとjoelclaw otel statsが想定どおりの動作を示す。- 新たな失敗モードを
source、component、actionで検索できる。
Inngest のリプレイとハングのトリアージ
ステップのコードが実行されているように見えるにもかかわらず、実行が RUNNING/CANCELLED のまま Finalization エラーになる場合に使用します。
- まず実行トレースを調べます。
joelclaw run <run-id>
errors.Finalization.stack に Unable to reach SDK URL が含まれているか確認します。
- 実際のネットワーク到達性の問題か、Worker 側のブロックかを確認します。
joelclaw inngest status
joelclaw logs worker --lines 200
joelclaw logs errors --lines 200
- OTEL のリプレイノイズを確認します。
一度だけ出力されるはずのアクション(例:manifest.archive.prereqs-passed)が 1 回の実行ウィンドウ内に数百回現れる場合は、そのイベント出力を独立した step.run 内に移します。
joelclaw otel search "manifest.archive.prereqs-passed" --hours 1
Unable to reach SDK URLは、原因を特定できない症状として扱います。
イングレスの問題を示す場合もありますが、実際には、関数ハンドラーがローカル I/O や依存関係の処理で長時間ブロックし、ファイナライズが完了できない場合にも発生します。
ヘルパースクリプト
すばやくエンドツーエンドのプローブを行うには、scripts/otel-smoke.sh を使用します。
./skills/o11y-logging/scripts/otel-smoke.sh verification o11y-skill probe.emit
Key Files
packages/system-bus/src/observability/otel-event.tspackages/system-bus/src/observability/emit.tspackages/system-bus/src/observability/store.tspackages/system-bus/src/serve.tspackages/gateway/src/observability.tspackages/system-bus/src/inngest/functions/check-system-health.tspackages/cli/src/commands/otel.tsapps/web/app/api/otel/route.ts