添加钩子以全局记录node.js/express中的所有节点HTTP响应

添加钩子以全局记录node.js/express中的所有节点HTTP响应,node.js,express,Node.js,Express,我使用node.js和express来处理HTTP请求和响应。通过使用http.ServerRequest事件,我可以添加一个钩子并记录http请求。http.ServerResponse似乎没有类似的事件,我想知道如何用我的服务器发送的一段代码记录所有http响应?如果您对所有响应都使用express'res.send(),并且您不介意将代码插入express模块,那么可以插入 进入 …/node_modules/express/lib/response.js: 43 res.send = f

我使用node.js和express来处理HTTP请求和响应。通过使用
http.ServerRequest
事件,我可以添加一个钩子并记录http请求。
http.ServerResponse
似乎没有类似的事件,我想知道如何用我的服务器发送的一段代码记录所有http响应?

如果您对所有响应都使用express'res.send(),并且您不介意将代码插入express模块,那么可以插入 进入

…/node_modules/express/lib/response.js:

43 res.send = function(body, headers, status){
44   console.log("\n...your log text here..." + body);
45   // allow status as second arg
46   if ('number' == typeof headers) {
47     status = headers,
48     headers = null;
49   }

我认为您无法侦听非错误事件——“关闭”似乎不会在res.send()上触发;。我想这是因为send()总是在代码中的某个地方被调用。

出于类似的需要,我创建了一个包来完成这样的任务。退房

该程序的核心是这样的,它包含一些额外的代码,因此您可以拥有自己的键值映射数据,每个请求都会记录这些数据:

// Save the real end that we will wrap
var rEnd = res.end;

// To track response time
req._rlStartTime = new Date();

// Proxy the real end function
res.end = function(chunk, encoding) {
  // Do the work expected
  res.end = rEnd;
  res.end(chunk, encoding);

  // And do the work we want now (logging!)

  // Save a few more variables that we can only get at the end
  req.kvLog.status = res.statusCode;
  req.kvLog.response_time = (new Date() - req._rlStartTime);

  // Send the log off to winston
  var level = req.kvLog._rlLevel;
  delete req.kvLog._rlLevel;
  logger.log(level, '', req.kvLog);
};

上述代码在express中作为中间件运行。查看代码,如果您有进一步的问题,请通过here或github与我联系。

不再需要monkeypatch,只要node.js 0.8.12之后有finish事件发出即可

实际上,它最初发布为endin(同时签出),但后来被重命名为finish。

如果您只想记录(请求和/或响应),请签出。

,它甚至可以记录请求/响应主体

coffeescript中的示例:

expressWinston.requestWhitelist.push('body')
expressWinston.responseWhitelist.push('body')
app.use(expressWinston.logger({
      transports: [
        new winston.transports.Console({
          json: true,
          colorize: true
        })
      ],
      meta: true, // optional: control whether you want to log the meta data about the request (default to true)
      msg: "HTTP {{req.method}} {{req.url}}", // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}"
      expressFormat: true, // Use the default Express/morgan request formatting, with the same colors. Enabling this will override any msg and colorStatus if true. Will only output colors on transports with colorize set to true
      colorStatus: true, // Color the status code, using the Express/morgan color palette (default green, 3XX cyan, 4XX yellow, 5XX red). Will not be recognized if expressFormat is true
      ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response
    }));

没有办法做到这一点<代码>“请求”由express扩展的
HttpServer
发出。最简单的方法是使用精简日志代理覆盖
.send
.end
。谢谢,我最后用猴子修补了http.ServerResponse方法-效果很好。我检查了节点0.8.14和0.8.23,并发出
end
,而不是
finish
。您链接的提交包含在0.9/0.10分支中(从几周前开始,GH现在将其显示在提交消息下方)。是否可以在完成事件上获得响应消息?
end
似乎也适用于我,而
finish
则不适用。我糊涂了!这是个坏主意。相反,请参见其他答案。这是当今最现代、也许也是最正确的答案。在Node.js的当前版本中,
res
应生成一个
“finish”
事件,您可以使用该事件来代替代理end方法。