Node.js Winston未显示错误详细信息

Node.js Winston未显示错误详细信息,node.js,express,logging,winston,Node.js,Express,Logging,Winston,我正在使用winston进行日志记录,大多数情况下它运行良好,但当出现异常时,它不会打印任何详细信息 这是我配置winston的代码: // Create logger const logger = winston.createLogger() // Create timestamp format const tsFormat = () => (new Date()).toLocaleTimeString() // Attach transports based on app mode

我正在使用
winston
进行日志记录,大多数情况下它运行良好,但当出现异常时,它不会打印任何详细信息

这是我配置winston的代码:

// Create logger
const logger = winston.createLogger()

// Create timestamp format
const tsFormat = () => (new Date()).toLocaleTimeString()

// Attach transports based on app mode
if (process.env.APP_MODE === 'production') {
  // Log to file
  logger.add(new (winston.transports.DailyRotateFile)({
    filename: path.join(__dirname, '../logs/errors-%DATE%.log'),
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    format: winston.format.json(),
    handleExceptions: true
  }))
} else {
  // Log to the console
  logger.add(new (winston.transports.Console)({
    timestamp: tsFormat,
    colorize: true,
    handleExceptions: true
  }))
}

module.exports = logger
我还使用了
Express
,在我的错误处理中间件中,我有以下代码:

const logger = require('../config/winston')
function (err, req, res, next) {
    console.log(err)
    logger.error(err)
    res.status(500).send({ error: 'Please try again later.' })
}
问题是,当发生错误时,所有
winston
日志都是:

{“级别”:“错误”}

而良好的旧
console.log()
显示:

TypeError: Cannot read property 'filename' of undefined
    at router.post (/Users/balazsvincze/Desktop/testapi/app/routes/upload.js:16:33)
    at Layer.handle [as handle_request] (/Users/de/Desktop/testapi/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/balazsvincze/Desktop/testapi/node_modules/express/lib/router/route.js:137:13)
    at Immediate.<anonymous> (/Users/balazsvincze/Desktop/testapi/node_modules/multer/lib/make-middleware.js:53:37)
    at runCallback (timers.js:814:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)
TypeError:无法读取未定义的属性“filename”
在router.post(/Users/balazsvincze/Desktop/testapi/app/routes/upload.js:16:33)
在Layer.handle[as handle_request](/Users/de/Desktop/testapi/node_modules/express/lib/router/Layer.js:95:5)
接下来(/Users/balazsvincze/Desktop/testapi/node_modules/express/lib/router/route.js:137:13)
马上。(/Users/balazsvincze/Desktop/testapi/node_modules/multer/lib/make middleware.js:53:37)
运行回调时(timers.js:814:20)
在tryOnImmediate(timers.js:768:5)
在processImmediate[as_immediateCallback](timers.js:745:5)
如何让
winston
记录这样的内容,包括堆栈跟踪

非常感谢

编辑:如果我将行记录器.error(err)更改为logger.error(err.message),至少我会得到以下信息:

{“message”:“无法读取的属性'filename'” 未定义的“级别”:“错误”}


离我想要的还很远

一种快速而肮脏的方法是记录
错误堆栈

logger.error(err.stack);
更详细的方法是专门为
错误
实例实现一个。这里有一些示例代码,说明如何在。

中使用format实现该功能

const { combine, timestamp, label, printf } = winston.format;
const myFormat = printf(info => {
    if(info instanceof Error) {
        return `${info.timestamp} [${info.label}] ${info.level}: ${info.message} ${info.stack}`;
    }
    return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
});
winston.createLogger({
    level: "info",
    format: combine(
        winston.format.splat(),
        label({ label: filename}),
        timestamp(),
        myFormat,
    ),
    transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log`
    // - Write all logs error (and below) to `error.log`.
    //
        new winston.transports.File({ filename: path.join(os.tmpdir(), "test", "test.log"), level: "info" }),
    ],
});

我认为您缺少的是
winston.createLogger
中的
格式错误({stack:true})

const logger=winston.createLogger({
级别:“调试”,
格式:format.combine(
错误({stack:true}),
印刷品,
),
transports:[新transports.Console()],
});
有关更多信息,请参阅

发生这种情况的原因是,有趣的
错误
对象属性,如
.stack
,是不可枚举的。一些函数检查其参数是否为
Error
实例,如
console.Error
,其他函数忽略所有不可枚举属性,如
winston.
JSON.stringify

控制台错误(新错误('foo')) 错误:foo 回复:1:15 位于Script.runInThisContext(vm.js:124:20) …(缩写) >stringify(新错误('foo')) '{}'
总而言之,让一个错误记录器基本上忽略错误是可怕的可用性。。。我在这方面浪费了太多的时间。

我之前也遇到过同样的问题,我知道这有一点,但对于仍在寻找解决方案的人来说,可以使用
utils deep clone
包。只是在Winston上面加了一层来处理错误对象

const winston = require('winston')
const { toJSON } = require('utils-deep-clone')

const winstonLogger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)()
  ]
})

const log = (message, payload) => {
  try {
    payload = toJSON(payload)
    return winstonLogger.log('info', message, payload)
  } catch(error) {
    console.error('some error occured while consoling')
  }
}

const testObj = {
  error: new Error('It should work')
}

log('Testing few bugs', testObj)
输出将是:

info: Testing few bugs message=It should work, stack=Error: It should work
    at Object.<anonymous> (/Users/atishay/Desktop/utils-error-deep-log/logger.js:20:10)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

info:Testing少量bug message=应该工作,stack=错误:应该工作
反对。(/Users/atishay/Desktop/utils error deep log/logger.js:20:10)
编译(Module.js:652:30)
在Object.Module.\u extensions..js(Module.js:663:10)
在Module.load(Module.js:565:32)
在tryModuleLoad时(module.js:505:12)
在Function.Module.\u加载(Module.js:497:3)
位于Function.Module.runMain(Module.js:693:10)
启动时(bootstrap_node.js:188:16)
在bootstrap_node.js:609:3

我真不敢相信这个问题还不流行。这是我在设置SERN应用程序时需要做的第一件事,我们使用Winston这样的记录器的主要原因是什么?尽可能详细地查看错误。遗憾的是,默认情况下,它不能作为
控制台.log
打印错误对象的全部细节。