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

如何用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}`;
  }),
),

关键修改说明

  1. 移除json()格式:保留原始日志字段,确保后续格式处理能正常访问message、ms等属性
  2. 调整ms()位置:放在printf之前,让Winston自动计算日志耗时并生成ms字段
  3. 手动插入ANSI颜色码:
    • \x1b[33m是黄色的ANSI控制码,\x1b[0m用于重置颜色,避免后续内容持续变色
    • 分别对traceId、含RoutesResolver的context、message中的RoutesResolver文本单独上色
  4. 保留级别颜色:通过winston.format.colorize().colorize()方法给日志级别添加对应颜色,和NestJS默认日志风格对齐

额外优化建议

如果需要统一管理颜色,可定义常量避免硬编码:

const COLORS = {
  yellow: '\x1b[33m',
  reset: '\x1b[0m',
};

之后在代码中用COLORS.yellow替代直接写ANSI码,更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:36:15