2012-09-25 17 views
7

मैं express.js का उपयोग कर रहा हूं। जब भी कोई संदेश लॉग करने का प्रयास करता है तो मुझे कुछ अनुरोध डेटा लॉग इन करने में सक्षम होने की आवश्यकता होती है। इसके लिए मैंक्या वर्तमान अनुरोध प्राप्त करना संभव है जिसे node.js द्वारा परोसा जा रहा है?

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

पर एक सहायक विधि बनाना चाहता हूं, तो मैं इस तरह की विधि का उपयोग करूंगा।

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

ध्यान दें कि मैं log_message फ़ंक्शन पर req ऑब्जेक्ट नहीं दे रहा हूं। मैं चाहता हूं कि पारदर्शी रूप से किया जाए ताकि log_message API उपयोगकर्ता को लॉग किए जा रहे सामान्य डेटा से अवगत होने की आवश्यकता न हो।

क्या express.js/node.js के साथ इसे प्राप्त करने का कोई तरीका है। अनुरोध वस्तु किसी प्रकार के वैश्विक चर से उपलब्ध है?

उत्तर

1

निम्नलिखित समाधान मुझे स्वीकार्य है।

यहां मेरे पास एक मिडलवेयर है जो अनुरोध वस्तु पर log_message विधि जोड़ता है। उसके बाद मैं संदेश लॉग करने के लिए बस req.log_message पर कॉल करता हूं। हालांकि यह प्रत्येक लॉगिंग कॉल पर रिक ऑब्जेक्ट को पास करने के समान ही है, यह थोड़ा सा क्लीनर है।

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

कॉलर (मॉड्यूल, आदि) के संपर्क में log_message और मार्ग से पहले पाइपलाइन पर आपके नियंत्रण पर कैसा है?

आप इस मार्ग के मंगलाचरण पूर्ववर्ती मिडलवेयर लागू करते हैं और समारोह log_message को बंद करने के भीतर से आते हो सकता था, या आप req EventEmitter सुविधा का लाभ उठाने और कॉल लपेट req.end के लिए कोई हैंडलर के अंदर winston.log सकता है और अनुरोध के दौरान किए गए सभी संदेशों को बस लॉग करें। यह आपके log_message को लॉग संदेशों (शायद एक ऐरे में) के संचयक के रूप में प्रभावी ढंग से बदल देगा और अनुरोध के अंत में बस उन्हें लॉग इन करेगा।

यह सब इस बात पर निर्भर करता है कि आप इस सामान को कैसे उजागर कर रहे हैं।

कई बिल्लियों यहाँ चमड़ी दिया है :)

10

एक दिलचस्प यह करने के लिए किया जाएगा नया डोमेन सुविधा रास्ता। 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(); 
}); 

लॉग फ़ंक्शन में, अब आप वर्तमान डोमेन प्राप्त कर सकते हैं और अनुरोध ऑब्जेक्ट निकाल सकते हैं।

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

    // TODO: log message 
}; 

डोमेन अभी भी प्रयोगात्मक हैं, लेकिन ऐसा लगता है कि अब और 1.0 रिलीज़ के बीच बहुत कुछ नहीं बदलेगा।

+0

एक डोमेन स्वचालित रूप से उस डोमेन के लिए process.domain निर्धारित नहीं करता है बनाना। तो log_message प्रक्रिया में। डोमेन वास्तव में अनिर्धारित है। –

+0

@MoizRaja तो वास्तव में उस प्रक्रिया में डोमेन कैसे जोड़ता है जो बाद में उपलब्ध है? –

+0

@ क्रिस्टोफरविल: 'process.domain = reqd;' मिडलवेयर में मेरे लिए काम किया। दुख की बात है कि व्यवहार का वर्णन करने के लिए दस्तावेज़ीकरण नहीं मिल सका: -/ – Timm

4

डोमेन जवाब की तरह, यह अब इस का उपयोग करते हुए निरंतरता-स्थानीय भंडारण करने के लिए एक बहुत आसान है: https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

DataHero हम सभी लॉग के साथ एक सौदे आईडी, उपयोगकर्ता आईडी, और सत्र id को बचाने संदेश।आपको अनुरोध ऑब्जेक्ट को सभी तरह से पास करने की आवश्यकता नहीं है, इसलिए यह आपके मॉडल/व्यावसायिक परत को भी साफ रखने में मदद करता है।

+1

वह डेटाहेरो साइट बहुत स्वरूपित है। – Thomas

3

एक midleware बनाएँ:

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'); 
संबंधित मुद्दे