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

如何配置Winston日志实现不同级别消息写入对应日志文件

问题诱因
  • Winston默认使用npm风格的日志级别规则,级别优先级和对应数值为:error(0) > warn(1) > info(2) > http(3) > verbose(4) > debug(5) > silly(6),数值越小代表日志优先级越高。
  • 你在transport中配置的level参数,作用是设置当前日志输出通道可接收的最低优先级阈值,而非“仅接收该级别日志”:所有优先级高于或等于该阈值的日志,都会被输出到对应通道。举个例子:你给info.log设置level: 'info',对应阈值数值为2,那么所有优先级数值≤2的日志(error、warn、info)都会被写入info.log,这就是error日志混入info.log、error日志混入warn.log的核心原因。
  • 你观察到的“仅初次执行npm start时error写入info.log、其余场景无异常”属于感知偏差:只要触发error级别日志,它就会满足info.log、warn.log、debug.log的阈值规则,被同步写入这几个文件,其余场景未出现只是因为你没有触发对应级别的日志,或是未注意到文件的追加写入内容。
  • debug.log同时写入error、debug级别日志也是相同规则导致:debug级别对应阈值数值为5,error优先级远高于该阈值,自然会被写入debug.log。warn.log中混入info日志,一般是级别阈值规则叠加日志追加写入的历史内容导致,添加精确过滤后即可解决。
正确配置方法

要实现单一级别日志单独写入对应文件的分流效果,不能仅依赖level参数配置,需要给每个文件输出通道添加单独的级别过滤规则,仅放行级别完全匹配的日志。Winston支持在format中返回false直接过滤掉不符合规则的日志,修正后的完整配置代码如下:

const { createLogger, transports, format } = require('winston');
const { combine, timestamp, printf } = format;

const customFormat = printf(({ level, message, timestamp }) => {
    if (!message.includes('&')) {       
        return `${timestamp} ${level}: ${message}`;
    } else {
        return `${timestamp} - ${message.split('&')[0]} - ${level}: ${message.split('&')[1]}`;
    }
});

// 生成对应级别的过滤format
const levelFilter = (targetLevel) => format((info) => {
    return info.level === targetLevel ? info : false;
})();

const logger = createLogger({
    format: combine(
        timestamp(),
        customFormat
    ),
    transports: [       
        new transports.File({
            filename: `${__dirname}/log/error.log`,
            level: 'error',
            format: combine(levelFilter('error'), timestamp(), customFormat)
        }),
        new transports.File({
            filename: `${__dirname}/log/info.log`,
            level: 'info',
            format: combine(levelFilter('info'), timestamp(), customFormat)
        }),
        new transports.File({
            filename: `${__dirname}/log/warn.log`,
            level: 'warn',
            format: combine(levelFilter('warn'), timestamp(), customFormat)
        }),
        new transports.File({
            filename: `${__dirname}/log/debug.log`,
            level: 'debug',
            format: combine(levelFilter('debug'), timestamp(), customFormat)
        }),
        // 控制台保留全量日志输出,不需要过滤
        new transports.Console({
            timestamp: true,
            format: combine(timestamp(), customFormat)
        }),
    ],
    exceptionHandlers: [
        new transports.Console({
            json: false,
            timestamp: true
        }),
        new transports.File({
            filename: `${__dirname}/log/exceptions.log`,
            json: false
        })
    ],
    exitOnError: false
});

module.exports = logger;

配置说明:

  • 封装了通用的levelFilter方法,传入目标级别即可生成对应的过滤规则,只有日志级别和目标级别完全一致时才会被放行
  • 每个文件传输通道单独引入对应级别的过滤器,同时保留定义的时间戳和自定义输出格式
  • 控制台通道不添加过滤,保留全级别日志输出方便开发调试
  • 配置完成后建议先清空原有log目录下的历史日志文件,再重新启动项目验证分流效果,避免旧日志内容干扰判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:33:20