6

Morgan 的文档描述了可以拆分请求和响应的日志记录:

拆分/双重记录

中间件可以根据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

4

1 回答 1

11

我已经设法使用immediate选项在请求和响应之间拆分 Morgan 日志记录:

即时

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

因此,不要使用这种混合日志记录:

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 只是增强了 Node 自己的请求和响应对象,我相信它在内部会这样做res.on('finish', req => { /* log stuff */ }),当它没有设置为immediate.

于 2018-01-25T17:49:27.313 回答