是否有可能获得由node.js服务的当前请求?
我正在使用express.js。 每当有人试图logging消息时,我都需要能够logging某些请求数据。 为此,我想创build一个像这样的帮助器方法
function log_message(level, message){ winston.log(level, req.path + "" + message); }
然后我会使用这样的方法。
exports.index = function(req, res){ log_message("info", "I'm here"); }
请注意,我没有将req对象传递给log_message函数。 我希望这样做是透明的,这样log_message API用户不需要知道正在被logging的公共数据。
有没有一种方法来实现这个express.js / node.js。 请求对象是否可以从某种全局variables中获得?
一个有趣的方法来做到这一点将是新的域function。 http://nodejs.org/api/domain.html
在提供出色错误恢复的同时,域可以用作“线程本地存储”types – 基本上存储每个请求的数据。
创build一些将每个请求/响应添加到域的中间件。
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(); });
在日志function中,您现在可以获取当前的域并取出请求对象。
function log_message(level, message) { // Pull the request from the current domain. var request = process.domain._req; // TODO: log message };
域名仍然是实验性的,但是从现在到1.0版本之间似乎并没有什么变化。
与域的答案类似,使用continuation-local-storage执行此操作现在更容易: https : //datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks /
在DataHero中,我们保存了一个包含所有日志消息的事务ID,用户ID和会话ID。 您不需要一直传递请求对象,所以它也有助于保持模型/业务层的清洁。
如何将log_message
暴露给调用者(一个模块等),以及对路由前面的pipe道有什么控制?
您可以应用此路由调用之前的中间件,并且可以在闭包中使用函数log_message
,或者可以利用req
EventEmitter工具并将调用包装到req.end处理程序中的winston.log中,并只logging所有消息在请求期间已经提出的。 这将有效地改变你的log_message
成为日志消息的累加器(也许在一个数组中),并且只是在请求的最后把它们全部logging下来。
这一切都取决于你如何揭露这些东西。
许多猫在这里被剥皮:)
创build一个中间件:
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(); }); });
并使用它:
var cls = require('continuation-local-storage'); var namespace = cls.getNamespace('com.storage'); namespace.get('ip');
下面的解决scheme是可以接受的。
在这里我有一个中间件,它将log_message方法添加到请求对象上。 之后,我只需调用req.log_message来logging消息。 虽然这与将req对象传递给每个日志logging调用非常相似,但它只是稍微更清晰。
function logging_middleware(req, res, next){ req.log_message = function(level, message){ winston.log(level, req.path + ":" + message); } next(); }