mcpField
L
logging-best-practices

logging-best-practices

github.com/andrelandgraf開発23106 回インストール22 週間前に更新
リポジトリ

logging-best-practices について

アプリケーションで Pino による構造化ログを使うための開発スキルです。ログレベルや API ルートのコンテキストに加え、ワークフローからログを呼び出すラッパー方式を説明します。

主な機能

  1. 01Pino による構造化ログ
  2. 02コンテキストを先に渡す呼び出し
  3. 03ログレベルの選択と設定
  4. 04API ログへの時間とステータスの記録
  5. 05step ラッパー経由のワークフローログ

活用シーン

  1. 01API リクエストの結果と所要時間の記録
  2. 02運用イベントや障害に応じたログレベルの選択
  3. 03Node モジュールを読み込めないワークフローでのログ記録

インストール

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

$npx skills add https://github.com/andrelandgraf/fullstackrecipes --skill logging-best-practices

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

詳細

ロギングのベストプラクティス

アプリ全体で Pino を使用して、構造化ログを出力します。

前提条件

まず、次のセットアップ手順を完了してください。

  • Pino ロギングのセットアップ
ロギング

@/lib/logging/logger から logger をインポートします。最初にコンテキストオブジェクト、次にメッセージを渡します。エラーの場合は、コンテキストオブジェクトに err を含めます。

import { logger } from "@/lib/logging/logger";

logger.info({ port: 3000 }, "Server started");
logger.warn({ endpoint: "/api/chat" }, "Rate limit reached");
logger.debug({ key: "user:123" }, "Cache miss");
logger.error({ err, userId: "123", endpoint: "/api/chat" }, "Request failed");
レベル
レベル使用する場面
trace詳細なデバッグ(使用頻度は低い)
debug開発時のトラブルシューティング
info通常の操作、ビジネスイベント
warn復旧可能な問題、非推奨に関する警告
error対応が必要な障害
fatal致命的な障害、アプリを継続できない場合

有効なログレベルのしきい値は LOG_LEVEL で設定します(デフォルトは info)。本番環境では warn を使用してください。

LOG_LEVEL="debug"
API ルート内

終了時に、タイミングのコンテキストを付けてログを出力します。

import { logger } from "@/lib/logging/logger";

export async function POST(request: Request) {
  const start = Date.now();
  try {
    const result = await processRequest(request);
    logger.info(
      { duration: Date.now() - start, status: 200 },
      "Request completed",
    );
    return Response.json(result);
  } catch (err) {
    logger.error({ err, duration: Date.now() - start }, "Request failed");
    return Response.json({ error: "Internal error" }, { status: 500 });
  }
}
ワークフロー内

ワークフローのランタイムでは Node モジュールをインポートできないため、ロガーを直接呼び出すことはできません。"use step" 関数でラップしてください。

// src/workflows/chat/steps/logger.ts
import { logger } from "@/lib/logging/logger";

export async function log(
  level: "info" | "warn" | "error" | "debug",
  message: string,
  data?: Record<string, unknown>,
): Promise<void> {
  "use step";

  if (data) {
    logger[level](data, message);
  } else {
    logger[level](message);
  }
}
import { log } from "./steps/logger";

export async function chatWorkflow({ chatId }) {
  "use workflow";

  await log("info", "Workflow started", { chatId });
}

参考資料

コメント