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() 函数中解包测试时,一切正常。