是否有可能获得node.js服务的当前请求?

Moi*_*aja 9 javascript node.js express

我正在使用express.js.每当有人试图记录消息时,我都需要能够记录某些请求数据.为此我想创建一个这样的辅助方法

function log_message(level, message){
  winston.log(level, req.path + "" + message);
}
Run Code Online (Sandbox Code Playgroud)

然后我会使用这样的方法.

exports.index = function(req, res){
  log_message("info", "I'm here");
}
Run Code Online (Sandbox Code Playgroud)

请注意,我没有将req对象传递给log_message函数.我希望透明地完成它,以便log_message API用户不需要知道正在记录的公共数据.

有没有办法用express.js/node.js实现这一点.请求对象是否可以从某种全局变量中获得?

Bad*_*yon 11

一个有趣的方法是使用新的域名功能. http://nodejs.org/api/domain.html

域提供出色的错误恢复,可以用作"线程本地存储"类型 - 基本上存储每个请求的数据.

创建一些中间件,将每个请求/响应添加到域.

app.use(function(req, res, next) {
  var reqd = domain.create();
  reqd.add(req);
  reqd.add(res);
  reqd._req = req; // Add request object to custom property
  // TODO: hook error event on reqd (see docs)
  next();
});
Run Code Online (Sandbox Code Playgroud)

在日志功能中,您现在可以获取当前域并提取请求对象.

function log_message(level, message) {
  // Pull the request from the current domain.
  var request = process.domain._req;

  // TODO: log message
};
Run Code Online (Sandbox Code Playgroud)

域仍然是实验性的,但从现在到1.0版本之间听起来并没有多大变化.

  • 不要再使用它:"此模块正在等待弃用" (10认同)

iba*_*ash 5

与域名回答相似,现在使用continuation-local-storage更容易实现此目的:https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks /

在DataHero中,我们使用所有日志消息保存事务ID,用户ID和会话ID.您不需要一直传递请求对象,因此它也有助于保持模型/业务层的清洁.

  • 该DataHero网站的格式非常糟糕。 (3认同)
  • 请注意使用 CLS 时会遇到的问题:https://github.com/othiym23/node-continuation-local-storage/issues/59 (2认同)

Sha*_*ngh 5

创建一个中间件:

app.use(function(req, res, next) {
       var tid = uuid.v4();
     var cls = require('continuation-local-storage');
       var namespace = cls.createNamespace('com.storage');
      var pre_ip;
          if(get_ip(req))
          { ip_info= get_ip(req).clientIp;
              pre_ip=ip_info
          }
          namespace.bindEmitter(req);
          namespace.bindEmitter(res);
        namespace.run(function() {
               console.log(logobj);
              namespace.set('tid', tid);
              namespace.set('ip',ip_info);
           namespace.set('logobj',logobj);   
              next();
          });
      });
Run Code Online (Sandbox Code Playgroud)

并使用它:

var cls = require('continuation-local-storage');
 var namespace = cls.getNamespace('com.storage');
      namespace.get('ip');
Run Code Online (Sandbox Code Playgroud)


Moi*_*aja 2

以下解决方案是我可以接受的。

在这里,我有一个中间件,它将 log_message 方法添加到请求对象上。之后,我只需调用 req.log_message 来记录消息。虽然这与将 req 对象传递给每个日志记录调用非常相似,但它只是稍微干净一些。

function logging_middleware(req, res, next){
    req.log_message = function(level, message){
        winston.log(level, req.path + ":" + message);
    }
    next();
}
Run Code Online (Sandbox Code Playgroud)