2013-04-25 10 views
19

चलें कहते हैं कि मैं इस स्वरूपण स्ट्रिंग की तरह प्रवेश करना चाहते हैं:django लॉगिंग प्रति अनुरोध वैश्विक स्तर पर संदर्भ सेट?

logging.error('Error fetching information', extra = { 'user_id': 22 })

इस के लिए संदेशों प्रवेश करने के लिए वर्तमान उपयोगकर्ता आईडी जोड़ देगा:

%(levelname)s %(asctime)s %(module)s %(funcName)s %(message)s %(user_id) 

यह प्रवेश करने कमांड के इस प्रकार का उपयोग किया जा सकता है वर्तमान अनुरोध

लेकिन अतिरिक्त dict हर प्रवेश कॉल में जोड़ा जाना चाहिए।

क्या इस संदर्भ को django (जैसे मिडलवेयर, या दृश्य के इंडेक्स फ़ंक्शन) में एक सामान्य फ़ंक्शन में जोड़ने का कोई अच्छा तरीका है, ताकि उपयोगकर्ता आईडी के साथ अतिरिक्त शब्दकोश सेट हो और वर्तमान में सभी लॉगिंग कॉल हो जाएं अनुरोध वर्तमान उपयोगकर्ता को भी लॉग इन करें।

+1

क्यों 'mawimawi' के जवाब स्वीकार्य नहीं है? क्या यह थ्रेड-स्थानीय उपयोग, या कुछ और वजह से है? –

+0

विनय साजिप, कुछ प्रतिनिधि अंक अकेले मर जाएंगे। इस तरह यह stackoverflow पर काम करता है। – mawimawi

+0

@VinaySajip, हाँ, धागे की स्थानीय और एक अतिरिक्त मिडलवेयर के उपयोग से बचने की कोशिश। यदि लॉगिंग क्लास को विस्तारित करने का कोई तरीका संभव है, तो यह बहुत अच्छा होगा। – DhruvPathak

उत्तर

8

जो हर जगह वर्तमान अनुरोध उपलब्ध बनाने में अपनी समस्या के साथ मदद करता है https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py पर एक ThreadLocal मिडलवेयर मौजूद है। , अपने views.py में, कहते हैं:

from django_tools.middlewares import ThreadLocal 
def log_something(levelname, module, funcname, message): 
    user = ThreadLocal.get_current_user() 
    # do your logging here. "user" is the user object and the user id is in user.pk 
2

यहाँ धागा स्थानीय लोगों या मध्यस्थ के बिना एक संभव तरीका है:

तो तुम क्या करने की जरूरत अपने MIDDLEWARE_CLASSES सेटिंग को मिडलवेयर जोड़ सकते हैं और एक समारोह बनाने कहीं इस तरह है

from threading import RLock 
shared_data_lock = RLock() 
request_map = {} 

def set_request(request): 
    with shared_data_lock: 
     request_map[threading.current_thread()] = request 

निम्नलिखित फ़िल्टर बनाएं और संचालकों जो उत्पादन अनुरोध विशिष्ट जानकारी की जरूरत के लिए देते हैं:

अनुरोध करने के लिए एक dict मानचित्रण धागे, और यह करने के लिए उपयोग करने के लिए serialise लॉक
import logging 
class RequestFilter(logging.Filter): 
    def filter(self, record): 
     with shared_data_lock: 
      request = request_map.get(threading.current_thread()) 
     if request: 
      # Set data from the request into the record, e.g. 
      record.user_id = request.user.id 
     return True 

फिर, प्रत्येक दृश्य के पहले बयान के रूप में, नक्शे में अनुरोध सेट:

def my_view(request, ...): 
    set_request(request) 
    # do your other view stuff here 

इस स्थापना के साथ, आप पाएँगे कि आपका लॉग उत्पादन प्रासंगिक अनुरोध विशेष जानकारी शामिल है।

1

मुझे लगता है कि आप एक custom log formatter के लिए देख रहे हैं। मादामावी के जवाब के साथ मिलकर थ्रेडलोकल जानकारी शामिल करने के लिए, आपकी प्रारूप विधि स्वचालित रूप से जानकारी ले सकती है और इसे प्रत्येक लॉग संदेश में जोड़ सकती है। सबसे पहले, threadlocal चर खतरनाक बदतर हो सकता है और,, जानकारी लीक, यदि आप एक तरह से एक ThreadPool का उपयोग करता है में तैनात:

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

संबंधित मुद्दे