Node.js中如何用pino-pretty正确格式化多行日志
解决Pino + Pino-Pretty多行日志转义字符未解析为换行的问题
问题分析
你当前的日志输出中,\n转义字符被原样显示而非解析为换行,核心原因是日志消息被作为结构化字段传入(放在logger.error的第一个对象参数里),Pino-pretty会将其当作普通字符串输出,不会解析内部的转义字符。
解决方案1:调整日志消息传递方式
将日志消息作为logger方法的第二个参数(主消息位)传入,而非放在元数据对象中。修改你的LoggerService方法:
import pino from 'pino'; export class LoggerService { private readonly logger = pino({ formatters: { bindings: (bindings) => ({ pid: bindings.pid, hostname: bindings.hostname, }), }, transport: { target: 'pino-pretty', options: { colorize: true, }, }, timestamp: pino.stdTimeFunctions.isoTime, redact: ['user.email', 'user.password', 'user.hash'], }); async log(message: string, context?: string) { // 将context作为元数据,message作为主消息 this.logger.info(context ? { context } : {}, message); } async error(message: string, context?: string) { this.logger.error(context ? { context } : {}, message); } // Additional methods... }
修改后,你的示例调用this.logger.error(error.message,'UserService.findAllByFilter')会自动将error.message作为主日志消息,Pino-pretty会正确解析其中的\n为换行,输出格式会恢复整洁。
解决方案2:通过Pino-Pretty的transform函数处理转义字符
如果不想修改现有调用方式,可以在Pino-Pretty配置中添加transform函数,主动解析message字段中的转义换行符:
private readonly logger = pino({ formatters: { bindings: (bindings) => ({ pid: bindings.pid, hostname: bindings.hostname, }), }, transport: { target: 'pino-pretty', options: { colorize: true, // 自定义转换逻辑,替换转义换行符 transform: (log) => { if (typeof log.message === 'string') { log.message = log.message.replace(/\\n/g, '\n'); } return log; } }, }, timestamp: pino.stdTimeFunctions.isoTime, redact: ['user.email', 'user.password', 'user.hash'], });
该方法会在日志格式化前处理message字段,将所有\n转义字符替换为实际换行。
生产环境(推送至BetterStack)注意事项
生产环境无需使用Pino-pretty,直接保留Pino的默认JSON格式输出即可:
- JSON格式中的转义字符
\n在BetterStack的日志查看器中会被自动解析为换行,无需额外处理 - 结构化JSON日志更利于BetterStack的检索、分析和告警配置,直接通过Pino的传输配置将日志推送至BetterStack即可
内容的提问来源于stack exchange,提问作者Nazar Duma
相关产品推荐
相关产品推荐

