2009-12-22 4 views
33

ऐसा प्रतीत होता है कि अगर आप logging.info() से पहले से पहले लॉगिंग करते हैं तो आप लॉगिंग करते हैं। BasicConfig, logging.basicConfig कॉल का कोई प्रभाव नहीं पड़ता है। वास्तव में, कोई लॉगिंग नहीं होती है।आपके द्वारा logging.basicConfig चलाने से पहले पायथन लॉगिंग?

इस व्यवहार को कहां रखा गया है? मैं वास्तव में समझ में नहीं आता।

उत्तर

37

आप डिफ़ॉल्ट हैंडलर को हटा दें और इस तरह प्रवेश करने पुनः कॉन्फ़िगर कर सकते "रूट" लॉगर - अगर आप लॉगिंग से पहले कॉल करते हैं, कहते हैं, logging.info() को कॉल करते हैं, तो इसका उपयोग किया जाता है। basicConfig (level = logging.DEBUG) - में चेतावनी का डिफ़ॉल्ट लॉगिंग स्तर है।

यही कारण है कि logging.info() और logging.debug() कुछ भी नहीं करते हैं: क्योंकि आपने उन्हें पर कॉन्फ़िगर नहीं किया है ... um ... उन्हें कॉन्फ़िगर नहीं कर रहा है।

संभावित रूप से संबंधित (यह मुझे थोड़ा सा): जब मूल कॉन्फिग को कॉल नहीं किया जाता है, तो मुझे अपने डीबग संदेश नहीं मिलते थे, भले ही मैंने अपने हैंडलर को DEBUG स्तर पर सेट किया हो। बालों को खींचने के बाद, मैंने पाया कि आपको कस्टम लॉगर का स्तर DEBUG होने के लिए भी सेट करना होगा। यदि आपका लॉगर चेतावनी पर सेट है, तो एक हैंडलर को DEBUG (स्वयं द्वारा) पर सेट करने से आपको logger.info() और logger.debug() पर कोई आउटपुट नहीं मिलेगा।

+1

वर्बैटिम का उपयोग करने के लिए। यदि आप मुझे पसंद करते हैं- इस तरह के तत्काल लॉगर का पुन: उपयोग करने का प्रयास किया गया: 'logger = logging.getLogger (__ name __) 'और' logger.handlers 'में लूप करने का प्रयास करें, यह काम नहीं करेगा। –

+1

"root rootanders:" क्या है? एक खाली अनुक्रम को बदलने से कोई प्रभाव नहीं पड़ता है। क्या यह संभव है कि root.handlers कुछ अन्य, गैर-अनुक्रम झूठा मान है? (यह मेरे सिस्टम पर नहीं है) – Sebastian

+0

AWS Lambdas के साथ लॉगिंग समस्या डीबग करने के लिए आसान है। ऐसा लगता है कि वे लैम्ब्डा बूटस्ट्रैपिंग के दौरान 'लैम्ब्डा लॉजिंग हैंडलर' नाम के साथ कुछ हैंडलर स्थापित करते हैं। स्थापित हैंडलर को हटाने से समस्या हल हो गई। –

9

हां।

आपने कुछ लॉग करने के लिए कहा है। लॉगिंग, इसलिए, एक डिफ़ॉल्ट विन्यास बनाना चाहिए। एक बार लॉगिंग कॉन्फ़िगर किया गया है ... अच्छा ... यह कॉन्फ़िगर किया गया है।

इसके अलावा, आप नकली प्रवेश को रोकने के लिए संचालकों बनाने के बारे में पढ़ सकते हैं:

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

इस पर एक चाल है।

  1. कोई मॉड्यूल वैश्विक स्तर पर logging.getlogger() अनुरोधों को छोड़कर कुछ भी कर सकता है।

  2. केवल if __name__ == "__main__": लॉगिंग कॉन्फ़िगरेशन कर सकता है।

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

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

# if someone tried to log something before basicConfig is called, Python creates a default handler that 
# goes to the console and will ignore further basicConfig calls. Remove the handler if there is one. 
root = logging.getLogger() 
if root.handlers: 
    for handler in root.handlers: 
     root.removeHandler(handler) 
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 
+1

नहीं, मैं गलत था - स्पष्ट रूप से यह डिज़ाइन द्वारा मूलभूत कॉन्फिग को .info et al से बुलाया जाता है ताकि यह सुनिश्चित किया जा सके कि लॉगर स्थापित है। यह अभी भी मेरे लिए अजीब व्यवहार की तरह लगता है। –

2

यहाँ पहेली है कि ऊपर जवाब का उल्लेख नहीं था ... में से एक टुकड़ा है और फिर:

7

कार्लोस ए इबरारा का यह जवाब सिद्धांत रूप में सही है, हालांकि कार्यान्वयन तोड़ सकता है क्योंकि आप एक सूची में पुनरावृत्ति कर रहे हैं जिसे हटाकर हैडलर() को कॉल करके बदला जा सकता है। यह असुरक्षित है। दो विकल्प हैं:

while len(logging.root.handlers) > 0: 
    logging.root.removeHandler(logging.root.handlers[-1]) 
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 

या:

logging.root.handlers = [] 
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG) 

जहां का उपयोग कर पाश है इन दोनों की पहली सबसे सुरक्षित (हैंडलर के लिए किसी भी विनाश कोड लॉगिंग ढांचे के अंदर स्पष्ट रूप से कहा जा सकता है के बाद से) । फिर भी, यह एक हैक है, क्योंकि हम एक सूची होने के लिए logging.root.handlers पर भरोसा करते हैं।

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