You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整Pino日志参数处理逻辑,支持message在前的对象/错误传参?

Fastify + Pino:适配message, data参数顺序的错误日志打印问题

问题描述

使用Fastify搭配pino-pretty工具时遇到日志传参问题:

  • 调用pino.info('Error doing that', Error)时,Error对象会被打印为{}
  • 调用pino.info(Error, 'Error doing that')时,Error能完整输出所有信息

但个人习惯使用message, data的参数顺序编写日志,希望调整Pino的参数处理逻辑,允许在第二个参数位置传入对象或错误并正确打印。

解决方案

1. 封装自定义日志方法(推荐)

自己封装一层日志函数,自动判断参数类型并调整顺序,既保留习惯的message, data写法,又适配Pino的底层逻辑:

// 基于现有Pino实例封装
const customLogger = {
  info(message, data) {
    if (data instanceof Error || (typeof data === 'object' && data !== null)) {
      return pino.info(data, message);
    }
    return pino.info(message, data);
  },
  // 按需封装warn、error等其他日志级别
  error(message, data) {
    if (data instanceof Error || (typeof data === 'object' && data !== null)) {
      return pino.error(data, message);
    }
    return pino.error(message, data);
  }
};

// 使用示例
customLogger.info('Error doing that', new Error('test error'));

2. 自定义Pino序列化器

通过配置serializers强制处理第二个参数中的Error对象,无需修改调用方式:

const pino = require('pino')({
  serializers: {
    // 保留默认的错误序列化
    err: pino.stdSerializers.err,
    // 自定义处理第二个参数(Pino会将其识别为占位符参数,存放在`args`字段)
    args: (values) => {
      if (Array.isArray(values) && values[0] instanceof Error) {
        return pino.stdSerializers.err(values[0]);
      }
      return values;
    }
  },
  transport: {
    target: 'pino-pretty'
  }
});

// 调用示例
pino.info('Error doing that', new Error('test error'));

注意:这种方式下,错误信息会出现在日志的args字段中,需要结合pino-pretty的配置调整显示效果。

3. 了解Pino的参数逻辑(底层原因)

Pino日志方法的参数规则是:

  • 若第一个参数是对象/Error,则作为日志上下文数据,第二个参数作为消息文本
  • 若第一个参数是字符串,第二个参数会被当作消息的占位符参数(如pino.info('Hello %s', 'World')),此时传入Error会被错误解析为占位符参数,最终打印为空对象{}

所以封装自定义方法是最灵活的方案,既能统一代码风格,又能避免Pino的参数规则限制。

内容的提问来源于stack exchange,提问作者Titan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 07:26:17