Winston 记录器将日志的时间戳设置为 12/31/1969 而不是当前时间
Winston logger setting the timestamp of the log to 12/31/1969 instead of current time
我正在使用 winston 设置登录一个应用程序,偶尔当我 运行 测试时会创建一个单独的文件,日期为 12/31/1969。在创建 t运行sport 时我需要明确说明什么以便它知道当前日期是什么吗?
非常有趣的是,这似乎是一个系统范围的异常,因为 _log
方法不使用 new Date()
语法,但 moment.js 库也会导致日志文件中的 12-31-1969:
我的记录器:
class Logger{
constructor(configs){
if (!configs) configs = {};
this.logDirectory = configs.directory ? path.join(__dirname, configs.directory) : path.join(__dirname, '../logs') ;
this.initialize();
this.date = moment().format("YYYY-MM-DD HH:mm:ss");
}
initialize() {
this._createTransportObj();
this._createLoggerObj();
}
_createTransportObj() {
const DailyRotateFile = winston.transports.DailyRotateFile;
this._transport = new DailyRotateFile({
filename: path.join(this.logDirectory, '/log-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'info'
});
}
_createLoggerObj() {
this._logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [this._transport],
exitOnError: true
});
if (nodeEnv !== 'production') {
this._logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
}
_log(type, msg, options) {
const logMsg = {};
const timestamp = moment().format("YYYY-MM-DD HH:mm:ss");
logMsg.level = type || 'info';
logMsg.time = timestamp;
logMsg.msg = msg || '';
logMsg.desc = options.description || '';
// get the user that made the request if available
if (options.user) logMsg.user = options.user;
// get the url endpoint that was hit if available
if (options.url) logMsg.url = options.url;
// if an error is sent through, get the stack
// and remove it from msg for readability
if (msg.stack) {
logMsg.stack = msg.stack;
msg = msg.message ? msg.message : msg;
}
// get the ip address of the caller if available
if (options.ip) logMsg.ip = options.ip;
// get the body of the request if available
if (options.body) logMsg.body = options.body;
// get the query string of the request if available
if (options.query) logMsg.query = options.query;
// get the params string of the request if available
if (options.params) logMsg.params = options.params;
const jsonString = JSON.stringify(logMsg);
this._logger.log(type, logMsg);
}
info(msg, options) {
return this._log('info', msg, options);
}
error(msg, options) {
return this._log('error', msg, options);
}
warn(msg, options) {
return this._log('warn', msg, options);
}
verbose(msg, options) {
return this._log('verbose', msg, options);
}
debug(msg, options) {
return this._log('debug', msg, options);
}
silly(msg, options) {
return this._log('silly', msg, options);
}
}
module.exports = { Logger };
我目前只在我的路由流经的承诺处理程序中测试它:
const asyncHandler = fn => (req, res, next) => {
const logger = new Logger();
Promise.resolve(fn(req, res, next))
.then(result => {
if (req.body.password) delete req.body.password;
logger.info(result,
{ user: req.user.username,
url: req.originalUrl,
body: req.body,
description: '200:OK Response sent back successfully'
});
return res.status(200).json({ result })
})
.catch(e => {
console.log(e);
return res.status(400).json({ error: e.message })
});
};
module.exports = asyncHandler;
更新*
好的,所以它似乎不是记录器本身。我 运行 进行了一批测试,发现触发日期更改的路径始终相同。奇怪的是我似乎无法弄清楚发生了什么。
路线是:
和app.use()
语句如下:
最后 admin_access 中间件足够简单了:
我已经知道如果我在 app.js
文件到达 admin_access
之前打破了端点,那么日期是正确的。但是,如果我进入 admin_access
,则日期为 12-31-1969。那么两者之间会发生什么呢?这条路线上有没有我可能无意中设置的东西?
想通了。原来包 sinon-test 正在更改系统时间。
我的测试设置是这样的:
const sinon = require('sinon');
const sinonTest = require('sinon-test');
const test = sinonTest(sinon);
describe('Test suite for route: /video/admin/create', ()=>{
let agent;
beforeEach(async function() {
// create temporary admin
admin.permissionId = 1;
await new NewUser().createUser(admin);
//login as admin
agent = chai.request.agent(server);
await agent
.post('/auth')
.send({ username: admin.username, password: admin.password });
});
afterEach(async function() {
// destroy temp admin
await new UserManager(admin).hardRemove();
});
it('should fail to create a video for not including video info', test(async function(){
const newVideo = { title: 'Test Video' };
const response = await agent.post('/video/admin/create')
.send(newVideo);
expect(response.status).to.equal(400);
}));
it('should create a video', test(async function(){
const newVideo = {
title: 'Test Video',
description: 'This is a description',
embed: 'https://youtu.be/SKbHjjZXdmc',
source: 'youtube',
type: 'lecture',
category: 'physics'
};
const response = await agent.post('/video/admin/create')
.send(newVideo);
// validations
expect(response.status).to.equal(200);
const { result } = response.body;
expect(result.title).to.equal(newVideo.title);
expect(result.description).to.equal(newVideo.description);
expect(result.embed).to.equal(newVideo.embed);
}));
});
当我从 test()
函数中解包测试时,一切正常。
我正在使用 winston 设置登录一个应用程序,偶尔当我 运行 测试时会创建一个单独的文件,日期为 12/31/1969。在创建 t运行sport 时我需要明确说明什么以便它知道当前日期是什么吗?
非常有趣的是,这似乎是一个系统范围的异常,因为 _log
方法不使用 new Date()
语法,但 moment.js 库也会导致日志文件中的 12-31-1969:
我的记录器:
class Logger{
constructor(configs){
if (!configs) configs = {};
this.logDirectory = configs.directory ? path.join(__dirname, configs.directory) : path.join(__dirname, '../logs') ;
this.initialize();
this.date = moment().format("YYYY-MM-DD HH:mm:ss");
}
initialize() {
this._createTransportObj();
this._createLoggerObj();
}
_createTransportObj() {
const DailyRotateFile = winston.transports.DailyRotateFile;
this._transport = new DailyRotateFile({
filename: path.join(this.logDirectory, '/log-%DATE%.log'),
datePattern: 'YYYY-MM-DD',
level: 'info'
});
}
_createLoggerObj() {
this._logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [this._transport],
exitOnError: true
});
if (nodeEnv !== 'production') {
this._logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
}
_log(type, msg, options) {
const logMsg = {};
const timestamp = moment().format("YYYY-MM-DD HH:mm:ss");
logMsg.level = type || 'info';
logMsg.time = timestamp;
logMsg.msg = msg || '';
logMsg.desc = options.description || '';
// get the user that made the request if available
if (options.user) logMsg.user = options.user;
// get the url endpoint that was hit if available
if (options.url) logMsg.url = options.url;
// if an error is sent through, get the stack
// and remove it from msg for readability
if (msg.stack) {
logMsg.stack = msg.stack;
msg = msg.message ? msg.message : msg;
}
// get the ip address of the caller if available
if (options.ip) logMsg.ip = options.ip;
// get the body of the request if available
if (options.body) logMsg.body = options.body;
// get the query string of the request if available
if (options.query) logMsg.query = options.query;
// get the params string of the request if available
if (options.params) logMsg.params = options.params;
const jsonString = JSON.stringify(logMsg);
this._logger.log(type, logMsg);
}
info(msg, options) {
return this._log('info', msg, options);
}
error(msg, options) {
return this._log('error', msg, options);
}
warn(msg, options) {
return this._log('warn', msg, options);
}
verbose(msg, options) {
return this._log('verbose', msg, options);
}
debug(msg, options) {
return this._log('debug', msg, options);
}
silly(msg, options) {
return this._log('silly', msg, options);
}
}
module.exports = { Logger };
我目前只在我的路由流经的承诺处理程序中测试它:
const asyncHandler = fn => (req, res, next) => {
const logger = new Logger();
Promise.resolve(fn(req, res, next))
.then(result => {
if (req.body.password) delete req.body.password;
logger.info(result,
{ user: req.user.username,
url: req.originalUrl,
body: req.body,
description: '200:OK Response sent back successfully'
});
return res.status(200).json({ result })
})
.catch(e => {
console.log(e);
return res.status(400).json({ error: e.message })
});
};
module.exports = asyncHandler;
更新* 好的,所以它似乎不是记录器本身。我 运行 进行了一批测试,发现触发日期更改的路径始终相同。奇怪的是我似乎无法弄清楚发生了什么。
路线是:
和app.use()
语句如下:
最后 admin_access 中间件足够简单了:
我已经知道如果我在 app.js
文件到达 admin_access
之前打破了端点,那么日期是正确的。但是,如果我进入 admin_access
,则日期为 12-31-1969。那么两者之间会发生什么呢?这条路线上有没有我可能无意中设置的东西?
想通了。原来包 sinon-test 正在更改系统时间。
我的测试设置是这样的:
const sinon = require('sinon');
const sinonTest = require('sinon-test');
const test = sinonTest(sinon);
describe('Test suite for route: /video/admin/create', ()=>{
let agent;
beforeEach(async function() {
// create temporary admin
admin.permissionId = 1;
await new NewUser().createUser(admin);
//login as admin
agent = chai.request.agent(server);
await agent
.post('/auth')
.send({ username: admin.username, password: admin.password });
});
afterEach(async function() {
// destroy temp admin
await new UserManager(admin).hardRemove();
});
it('should fail to create a video for not including video info', test(async function(){
const newVideo = { title: 'Test Video' };
const response = await agent.post('/video/admin/create')
.send(newVideo);
expect(response.status).to.equal(400);
}));
it('should create a video', test(async function(){
const newVideo = {
title: 'Test Video',
description: 'This is a description',
embed: 'https://youtu.be/SKbHjjZXdmc',
source: 'youtube',
type: 'lecture',
category: 'physics'
};
const response = await agent.post('/video/admin/create')
.send(newVideo);
// validations
expect(response.status).to.equal(200);
const { result } = response.body;
expect(result.title).to.equal(newVideo.title);
expect(result.description).to.equal(newVideo.description);
expect(result.embed).to.equal(newVideo.embed);
}));
});
当我从 test()
函数中解包测试时,一切正常。