3

我正在尝试使用 morgan 记录对我的 api 服务器的请求。像这样配置我的路线;

  app.use logger('dev')

  app.use '/api/collab/dataobjects/:do',  if config.disable_auth then authMid.noAuthCheck else authMid.authCheck
  app.use '/api/collab/dataobjects/:do', queryRouter(config.testing)
  app.use '/api/collab/dataobjects/:do', queryRouter()

  app.use (req, res, next) ->
    console.warn "Test"
    err = new Error('Not Found')
    err.status = 404
    next err

  app.use (err, req, res, next) ->
    res.status(err.status || 500)
    console.warn err
    res.send {
      message: err.message
      error: err
    }

摩根大体上按预期工作,但在少数路线上给出了一些无意义的输出;

POST /api/collab/dataobjects/1/update - - ms - -

在检查了一些时间之后,很明显,摩根在这些回复实际返回之前就记录了它们。为了解决这个问题,我app.use logger('dev')在 api 路由之后移动了该行,但在错误捕获路由之前。放在那里,Morgan 将显示长请求的状态代码和大小,与以前不同,但现在在所有请求上它都不会显示所花费的时间;

获取 /api/collab/dataobjects/1 200 - 毫秒 - 4119

为什么 Morgan 没有显示响应时间,我该如何解决?

4

1 回答 1

3

我刚刚注意到这个问题已经有 2 年以上的历史了,但我已经完成了跑腿工作,所以无论如何我都会发布我的回复。

我自己也看到过类似的问题,所以我花了一点时间四处挖掘以试图解决这个问题。我不确定我能否完全回答您的问题(还没有?),但我可以解释您所看到的一些事情:

启动定时器:

当调用中间件处理程序方法(带有签名的方法)时, Morgan启动它的计时器,所以在这种情况下:(req, res, next)

app.use logger('dev')
app.use '/api/foo/:bar', handler

报告的时间应包括处理时间/api/foo/:bar,但这种情况:

app.use '/api/foo/:bar', handler
app.use logger('dev')

它不应该包括处理时间,/api/foo/:bar因为计时器在handler方法运行后启动。

停止定时器:

在格式化要写入的日志行之前,Morgan 不会停止计时器。

除非另有配置(例如,使用immediate选项),否则 Morgan 在响应完全处理之前不会将行写入日志,使用on-finished模块在快速请求处理完成时进行回调。

报告-而不是响应时间

我认为有几种情况会导致 Morgan 写-而不是响应时间:

  1. 根据源代码-,当 Morgan在“启动计时器”时找不到它设置的临时变量时,它看起来会写入日志,因此写入-以指示该值或多或少是“null”。

  2. 如果请求“从未”完成处理, Morgan 也会写入-日志——即,如果请求超时而没有完成有效响应。(在这种情况下,我猜-或多或少表示“无穷大”)。

  3. 当值实际上是 0 时,Morgan也可能会写,这可以解释为什么一旦您将代码移到实际路线下方,您就会开始看到。或者,由于响应可能在 Morgan在您的第二个场景中调用时已经处理完毕,因此可能在写入临时开始时间变量之前立即触发 on-finished 回调,从而导致 #1。--app.use(logger)onFinished

那么,为什么摩根有时会-在您的原始设置中写入内容?

我认为最有可能的情况是您的“长期运行”请求根据您的基础架构的一部分或另一部分超时。例如,位于您的 expressjs 应用程序(如 nginx 之类的 Web 服务器或最终用户的 Web 浏览器)前面的服务最终将放弃等待响应关闭连接。

我需要深入研究完成的代码库(或者让有人向我解释这个:))以了解摩根在这种情况下将从完成中得到什么,以及它将如何处理这些信息,但我认为响应超时与您共享的信息一致。

于 2019-01-24T23:22:37.813 回答