Is it possible to get the current request that is served by node.js?

I am using express.js. I need to be able to log certain request data when someone tries to register a message. For this, I would like to create a helper method similar to

function log_message(level, message){ winston.log(level, req.path + "" + message); } 

Then I would use such a method.

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

Note that I do not pass the req object to the log_message function. I want this to be transparently done so that the log_message API user does not need to know about the general data that is being logged.

Is there any way to achieve this using express.js / node.js. Is the request object accessible from a global variable?

+7
source share
5 answers

The following solution is acceptable to me.

Here I have middleware that adds the log_message method to the request object. After that, I just call req.log_message to register the message. Although this is very similar to passing a req object to every registration call, it is a little cleaner.

 function logging_middleware(req, res, next){ req.log_message = function(level, message){ winston.log(level, req.path + ":" + message); } next(); } 
+1
source

An interesting way to do this would be the new Domains feature. http://nodejs.org/api/domain.html

Domains, providing excellent error recovery, can be used as a type of "Local stream storage" - basically, storing data for each request.

Create some middleware that adds each request / response to the domain.

 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(); }); 

In the log function, you can now get the current domain and pull out the request object.

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

Domains are still experimental, but it doesn't seem like much will change between now and release 1.0.

+10
source

As with domain responses, now it’s much easier to do this using the continuation-local storage: https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

In DataHero, we store the transaction ID, user ID, and session ID with all log messages. You do not need to pass the request object completely, so it also helps to clean up your models / business layer.

+4
source

create an average program:

 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(); }); }); 

And use it:

 var cls = require('continuation-local-storage'); var namespace = cls.getNamespace('com.storage'); namespace.get('ip'); 
+3
source

How does log_message work for the caller (module, etc.) and what control do you have over the pipeline preceding the route?

You can use the middleware preceding this route call and enable the log_message function from the closure, or you can use the req EventEmitter tool and transfer the call to winston.log inside the handler for req.end and simply log all the messages that were made during the request . This would effectively change your log_message as a store of log messages (possibly in an array) and simply log them all at the end of the request.

It all depends on how you publish this material.

Many cats have been circumcised here :)

+2
source

All Articles