【问题标题】:Winston logger setting the timestamp of the log to 12/31/1969 instead of current timeWinston 记录器将日志的时间戳设置为 1969 年 12 月 31 日而不是当前时间
【发布时间】:2019-11-23 21:33:00
【问题描述】:

我正在使用 winston 设置登录应用程序,有时在我运行测试时会创建一个日期为 1969 年 12 月 31 日的单独文件。是否需要在创建传输时明确说明一些内容,以便它知道当前日期是什么?

非常有趣的是,这似乎是一个系统范围的异常,如 _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 };

我目前只在路由流经的 Promise 处理程序中对其进行测试:

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,日期是 1969 年 12 月 31 日。那么两者之间可能会发生什么?这条路线上是否有我无意中设置的东西?

【问题讨论】:

  • 那是 ECMAScript 纪元 1970-01-01 的前一天,所以也许您正在创建一个时间值为 0 的日期,例如 new Date(0) 您的系统设置为时区具有负偏移量(例如 -04:00)。如果您执行new Date('1970-01-01') 之类的操作,然后使用本地值打印时间戳,就会发生这种情况。
  • @RobG 我没有在任何地方设置日期,这让我很困惑。

标签: javascript node.js date logging winston


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2018-04-11
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多