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

Winston中结合format.printf时如何输出完整错误堆栈信息?

问题

我希望使用Winston(当前版本3.15.0)创建一个日志记录器,其error方法接收错误消息(字符串)和Error对象作为参数,输出带时间戳、级别、非JSON格式的错误日志,同时显示完整的错误堆栈。

我的代码如下:

const winston = require('winston');

const format = winston.format.combine(
    winston.format.errors({ stack: true }),
    winston.format.timestamp(),
    winston.format.printf(i => `${i.timestamp} [${i.level}] ${i.message}`)
)
// 注意:若将winston.format.printf([...])替换为winston.format.json(),则会包含完整堆栈

const logger = winston.createLogger({
    levels: {error: 1},
    format: format,
    transports: [new winston.transports.Console({level: 'error'})]
});

try {
    throw new Error('la la la');
} catch(e) {
    logger.error('oh no!!!', e);
}

process.exit(0);

当前输出:

2024-11-06T16:30:32.203Z [error] oh no!!! la la la

期望输出:

2024-11-06T16:31:14.535Z [error] oh no!!!
Error: la la la
    at Object.<anonymous> (/Users/foo/bar.js:19:11)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
    at node:internal/main/run_main_module:28:49

请问是否允许将printf与errors结合使用?若不允许,如何使用Winston输出格式化日志的同时显示错误堆栈?

解答

完全可以将winston.format.printf和winston.format.errors结合使用,你的问题出在自定义的printf格式化函数里没有处理错误堆栈的输出。

当你启用winston.format.errors({ stack: true })时,Winston会把Error对象的堆栈信息添加到日志对象的stack属性中,但你的原printf函数只输出了message字段,没有处理stack内容。

修改后的格式化逻辑如下:

const format = winston.format.combine(
    winston.format.errors({ stack: true }),
    winston.format.timestamp(),
    winston.format.printf(info => {
        let logContent = `${info.timestamp} [${info.level}] ${info.message}`;
        // 若存在堆栈信息,追加到日志内容后
        if (info.stack) {
            logContent += `\n${info.stack}`;
        }
        return logContent;
    })
)

另外,调用logger.error时,建议将错误对象作为第二个参数的error属性传入,这样Winston能更精准地识别并处理错误:

try {
    throw new Error('la la la');
} catch(e) {
    logger.error('oh no!!!', { error: e });
}

这样调整后,就能得到你期望的输出:包含时间戳、级别、自定义错误消息,同时完整显示错误堆栈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:45:09