如何用Winston Logger模拟NestJS彩色日志效果?
解决方案
问题根源
你的代码存在三个核心问题导致需求无法实现:
winston.format.json()会把日志对象转为JSON字符串,后续printf无法访问原始字段,同时破坏颜色格式winston.format.ms()放在printf之后,此时已生成最终日志字符串,无法插入耗时标识- 自定义
printf中未针对traceId、RoutesResolver这类特定内容添加颜色标记
修改后的实现代码
format: winston.format.combine( winston.format.timestamp({ format: 'DD-MM-YYYY, HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.ms(), // 先生成耗时字段,供后续printf调用 winston.format.printf(({ message, timestamp, ms, level }) => { // 给traceId添加黄色 const logTraceId = this.traceId ? `\x1b[33m[${this.traceId}]\x1b[0m` : ''; let logContext = ''; // 给包含RoutesResolver的context添加黄色 if (this.context) { logContext = this.context.includes('RoutesResolver') ? `\x1b[33m[${this.context}]\x1b[0m` : `[${this.context}]`; } // 给message中的RoutesResolver文本添加黄色 const coloredMessage = message.replace(/RoutesResolver/g, '\x1b[33m$&\x1b[0m'); // 给日志级别添加对应颜色(和NestJS默认风格匹配) const coloredLevel = winston.format.colorize().colorize(level, level); return `${timestamp} ${coloredLevel} - ${logContext}${logTraceId} ${coloredMessage} ${ms}`; }), ),
关键修改说明
- 移除
json()格式:保留原始日志字段,确保后续格式处理能正常访问message、ms等属性 - 调整
ms()位置:放在printf之前,让Winston自动计算日志耗时并生成ms字段 - 手动插入ANSI颜色码:
\x1b[33m是黄色的ANSI控制码,\x1b[0m用于重置颜色,避免后续内容持续变色- 分别对
traceId、含RoutesResolver的context、message中的RoutesResolver文本单独上色
- 保留级别颜色:通过
winston.format.colorize().colorize()方法给日志级别添加对应颜色,和NestJS默认日志风格对齐
额外优化建议
如果需要统一管理颜色,可定义常量避免硬编码:
const COLORS = { yellow: '\x1b[33m', reset: '\x1b[0m', };
之后在代码中用COLORS.yellow替代直接写ANSI码,更易维护。
内容的提问来源于stack exchange,提问作者napfernandes
相关产品推荐
相关产品推荐

