可観測性と構造化ログ
Redacted log、OpenTelemetry trace、queue readiness、alert を web と worker 間で相関します。
スターターのコミット
2a1a04aと同期済みです。
最初の障害が起きる前に、サポートとインシデント対応ができるよう設定します。Sushi SaaS は JSON を標準出力へ書きますが、ログ保存サービス、保持期間、ダッシュボード、警告サービスは意図的に選んでいません。
OpenTelemetry は optional で vendor-neutral です。OTEL_ENABLED=true、process ごとの OTEL_SERVICE_NAME、標準 OTLP endpoint/header を設定します。Request、fetch、job span が export され、span 内 log に trace_id と span_id が付きます。未設定なら no-op です。
/api/ready は payload を含まない queue count、failed/stale jobs、oldest due age を返します。Failed または 10 分超の job は queue を degraded にしますが traffic は止めず、dependency failure は 503 です。
三つの運用判断をする
- ホスティング側の収集機能を使うか、Datadog、Better Stack、Grafana などへ転送します。アプリケーション側のログ契約は変わりません。
- 本番は通常
infoにし、特定の調査中だけdebugにします。debugはログ量を増やし、実質的な保持期間を短くする可能性があります。 - サポート担当者が検索に使える ID を決めます。リクエスト、組織、ジョブ、注文、Stripe イベントの ID は有用ですが、メールアドレスと未加工のデータは通常不要です。
本番準備完了の条件: 一つのリクエストを ID から外部サービスまで追跡でき、テスト用シークレットが除去され、ユーザーには安全な翻訳済みエラーが返り、警告から必要なログ検索を開けることです。
Node.js ランタイムは Pino を使い、エッジ環境も同じ形の JSON を出力します。ログはホスティングが収集する標準出力へ送り、アプリ自身はログファイルを管理しません。LOG_LEVEL は debug、info、warn、error です。
リクエスト ID をルート、サービス、ジョブ、Stripe の注文・イベント、外部サービスの呼び出しへ引き継ぎます。イベント名、org_uuid、安全な UUID、ジョブ・注文番号、処理時間、結果を構造化し、文章だけのログにはしません。
認証ヘッダー、Cookie、パスワード、トークン、API キーは除去されます。未加工のリクエスト本文、署名付き URL、アカウントの出力内容は記録しません。respError が内部情報を記録して翻訳済みの error_code を返し、ブラウザーには error.message を出しません。
稼働準備、cron、再試行回数の枯渇、対応が必要な Webhook、遅延、5xx を監視し、Slack の警告を ID でログに関連付けます。Slack はログの保管場所ではありません。人へ通知する条件と内容は、Slack 運用通知で決めてください。