如何在Morgan中正确分割请求和响应之间的日志记录?

时间:2018-01-16 13:44:13

标签: javascript node.js express logging morgan

Morgan's documentation描述了可以分割请求和响应的日志记录:

  

拆分/双重记录

     

morgan中间件可根据需要多次使用,从而实现以下组合:

     
      
  • 请求日志条目和响应日志条目
  •   
  • 将所有请求记录到文件,但将错误记录到控制台
  •   

在他们唯一的相关示例中,有一些评论描述一个中间件会将错误响应记录到控制台,另一个请求记录:

// log only 4xx and 5xx responses to console
app.use(morgan('dev', {
  skip: function (req, res) { return res.statusCode < 400 }
}))

// log all requests to access.log
app.use(morgan('common', {
  stream: fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'})
}))

这似乎实现了将所有文件和错误请求记录到控制台的第二个示例,但不是第一个。

我有点迷失,我无法理解是什么告诉morgan仅记录请求或仅记录响应。我是否必须考虑将这些中间件正确放置在哪里?

目前,我有一个请求和响应的日志条目,我想:

morgan('[:date[clf]] :remote-addr :url :method HTTP/:http-version :status :remote-user :res[content-length] :referrer :user-agent :response-time ms', {
  stream: {
    write: (message) => {
      winston.silly(message.trim());
    }
  }
});

那么,如何在morgan中间件调用中正确记录请求,在另一个中间件中正确记录响应

1 个答案:

答案 0 :(得分:5)

我设法通过immediate选项将请求和回复之间的摩根记录分开:

  

即时

     

根据请求而不是响应写入日志行。这意味着即使服务器崩溃,也会记录请求,但无法记录来自响应的数据(如响应代码,内容长度等)。

所以,不要使用这种混合日志记录:

app.use(morgan(':remote-addr :url :method HTTP/:http-version :status :res[content-length] :user-agent :response-time ms', {
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

可以将它们分开,并以正确的顺序登录:

// Logs requests
app.use(morgan(':remote-addr :url :method HTTP/:http-version :user-agent', {
  // https://github.com/expressjs/morgan#immediate
  immediate: true,
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

// Logs responses
app.use(morgan(':remote-addr :url :method :status :res[content-length] :response-time ms', {
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

注意:自express just enhances Node's own request and response objects以来,我认为它内部为res.on('finish', req => { /* log stuff */ }),而未设置为immediate