如何调整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
相关产品推荐
相关产品推荐

