我正在使用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)
如何获取winston
来记录包括堆栈跟踪在内的类似内容?
非常感谢!
编辑:如果我将logger.error(err)行更改为logger.error(err.message),至少我得到了:
{“ message”:“无法读取以下文件的属性'filename' 未定义”,“级别”:“错误”}
距离我追求的目标还很远。
答案 0 :(得分:1)
一种快速而肮脏的方法是登录err.stack
:
logger.error(err.stack);
一种更精细的方法是专门为Error
实例实现custom format。有关如何在this Github issue中实现该功能的示例代码。
答案 1 :(得分:1)
使用格式。
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" }),
],
});
答案 2 :(得分:0)
我认为您缺少的是format.errors({ stack: true })
中的winston.createLogger
。
const logger = winston.createLogger({
level: 'debug',
format: format.combine(
format.errors({ stack: true }),
print,
),
transports: [new transports.Console()],
});
有关更多信息,请参见this GitHub thread。
之所以会这样,是因为有趣的Error
对象属性(如.stack
)是不可枚举的。某些函数检查其参数是否为Error
实例(例如console.error
),而其他函数则忽略所有不可枚举的属性,例如winston.<log-level>
和JSON.stringify
。
> console.error(new Error('foo'))
Error: foo
at repl:1:15
at Script.runInThisContext (vm.js:124:20)
...(abbr)
> JSON.stringify(new Error('foo'))
'{}'
所有这些,使错误记录器本质上忽略错误是可怕的可用性……我为此花了太多时间。
答案 3 :(得分:0)
我之前也遇到过同样的问题,我知道有一点,但是对于仍在寻找解决方案的人们来说,可以使用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