encore-logging について
Encore.ts アプリケーションで `encore.dev/log` を使い、構造化ログとトレース連携を行うスキルです。業務コンテキスト、一貫したフィールド、エラー処理、機密データ保護、ログ量の管理を扱います。
主な機能
- 01アプリケーションログが必要なイベントの選定
- 02安定したメッセージと構造化フィールドの出力
- 03レベル選択と元のエラーの保持
- 04`log.with()` による共通コンテキストの追加
- 05機密データと過剰なログの回避
活用シーン
- 01業務状態の変化や判断の記録
- 02再試行や外部システム連携の背景記録
- 03ログの情報漏えいや過剰出力の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ encoredev/ skills --skill encore-loggingインストール後、Claude Code で/encore-loggingを入力して読み込まれたか確認します。
詳細
Encore.ts の構造化ログ
構造化フィールドやトレース連携が必要なアプリケーションイベントには encore.dev/log を使用します。アプリケーションで確立されたフィールド名やイベントの慣習がこのガイドラインと整合している場合は、それらを維持してください。
記録する内容を決める
Encore がインフラストラクチャの操作から推測できない情報については、ログを追加します。
- ビジネス上の状態遷移
- 判断と、その判断の根拠となった入力
- リトライ、フォールバック、縮退運転
- リトライ、復旧、中止のいずれかを決める境界での失敗
- ドメインのコンテキストを必要とする外部システムとのやり取り
- セキュリティに関連する操作や管理操作
Encore はすでに API リクエスト、データベースクエリ、サービス呼び出し、キャッシュ操作、Pub/Sub アクティビティをトレースします。request started、querying database、request completed といったログでその実行を語らないでください。
集計の件数とレベルにはメトリクスを使用します。呼び出しの流れとタイミングにはトレースを使用します。個々のイベントを調査するために必要なコンテキストにはログを使用します。
構造化ログを出力する
メッセージは安定させ、可変データはフィールドに入れます。
import log from "encore.dev/log";
log.info("order rejected", {
event: "order.rejected",
orderId,
productId,
reason: "insufficient_inventory",
requestedQuantity,
availableQuantity,
});
メッセージに識別子を補間することは避けてください。安定したメッセージはグループ化でき、フィールドは検索可能なままです。
ダッシュボード、アラート、自動化で使用されるイベントには、安定した event フィールドを含めます。payment.authorized や subscription.cancelled のように <domain>.<past-tense-event> を推奨します。診断ログにはイベント名は必要ありません。
各フィールド名と型はイベント間で一貫させてください。整形された文章よりも、明示的な単位を持つ数値や列挙的な値を推奨します。
log.info("payment authorized", {
event: "payment.authorized",
amountMinorUnits: 14900,
currency: "SEK",
});
レベルを選ぶ
error: 予期しない失敗により操作を完了できなかったwarn: アプリケーションが復旧した、または縮退した状態で継続したinfo: 意味のある、比較的発生頻度の低いビジネスイベントdebug: 通常の運用には不要な診断の詳細trace: 発生頻度の高い内部状態
検証の失敗、リソースの欠如、ログインの拒否、支払いの拒否といった想定内の結果は error イベントではありません。ビジネス上の意味に基づいてレベルを選んでください。
デフォルトの最小レベルは trace です。頻繁に実行されるコードに debug や trace の呼び出しを追加する前に、encore.app で log_level を設定してください。
エラーは一度だけ記録する
error と warn は元のエラーを最初の引数として受け取ります。
try {
await chargeCustomer(customerId, amount);
} catch (err) {
log.error(err, "payment authorization failed", {
customerId,
amountMinorUnits: amount,
currency,
});
throw err;
}
元のエラーを渡すことで、その型、メッセージ、スタックトレース、原因が保持されます。文字列に変換すると、その情報は失われます。
伝播された失敗は、復旧の判断を担い、その影響を説明できるドメインのコンテキストを持つ層でログに記録します。下位の層は、エラーを処理または抑制する、リトライする、不変条件の違反を検出する、あるいは伝播によって失われるコンテキストを保持している場合にのみログを記録すべきです。
共有コンテキストを追加する
1 つのドメイン操作からの複数のイベントがフィールドを共有する場合は、log.with() を使用します。
const logger = log.with({ importId, tenantId });
logger.info("user import completed", { succeededCount, failedCount });
logger.warn("user import row rejected", { rowNumber, reason: "invalid_email" });
Encore はすでにサービス、エンドポイント、トレース ID、認証済みユーザー ID をリクエストログに付加します。重複したコピーを追加しないでください。
機密データを保護する
Encore はログフィールドをマスクしません。認証情報、トークン、セッション識別子、Cookie、認可ヘッダー、シークレット設定、支払いの詳細、リクエストとレスポンスの完全なオブジェクトを決してログに記録しないでください。
個人データよりも内部識別子を推奨します。保存すべきでない値を相関に使用する必要がある場合は、安定した非可逆なフィンガープリントを使用してください。
sensitive API オプションはトレースからリクエストとレスポンスのペイロードをマスクしますが、log に渡された値をマスクするわけではありません。
ログ量の制御
バッチ処理や長時間実行される操作は、結果・件数・所要時間とともに要約して記録してください。各項目ごとに 1 件のログを出力することは、それぞれの失敗を調査する必要がある場合を除いて避けてください。
大規模な値からは、プロバイダーの完全なレスポンス、レコード、設定オブジェクト、配列、ドキュメント本文ではなく、選択したメタデータのみをログに記録してください。プレビューのサイズを制限し、ログに記録する前に機密データが含まれていないか確認してください。
既存のアプリケーションをレビューする際は、まずループ、Pub/Sub サブスクライバー、ミドルウェア、頻繁に呼び出されるヘルパーを確認してください。こうした呼び出し箇所のごく一部が、ログ量の大部分を生み出していることがよくあります。
Encore.ts ロギングガイドと encore.dev/log API リファレンスを参照してください。