mcpField
L
logging-best-practices

logging-best-practices

github.com/andrelandgraf开发23106 次安装22 周前更新
代码仓库

关于 logging-best-practices

这是一项指导应用使用 Pino 输出结构化日志的开发技能,涵盖日志级别、API 路由上下文,以及在工作流中调用日志的封装方式。

主要功能

  1. 01使用 Pino 输出结构化日志
  2. 02先传上下文再传消息
  3. 03日志级别选择与配置
  4. 04记录 API 耗时和状态
  5. 05通过 step 封装在工作流中记录日志

适用场景

  1. 01记录 API 请求结果和耗时
  2. 02为运行事件或故障选择日志级别
  3. 03在无法导入 Node 模块的工作流中记录日志

安装

复制下面的命令,在终端中运行。

$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 模块,因此不能直接调用 logger。请将其封装在一个 "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 });
}

参考资料

评论

支持 Markdown