टास्कपायथन: सभी मॉड्यूल भर में कस्टम प्रवेश
मैं स्क्रिप्ट का एक संग्रह है और मैं चाहें तो उसे वास्तविक संदेश प्रवेश करने कर मॉड्यूल के लिए कम से कम परिवर्तन के साथ एकीकृत प्रवेश संदेशों के उत्पादन के लिए।
मैंने एक छोटा मॉड्यूल 'custom_logger' लिखा है जिसे मैं मुख्य एप्लिकेशन से एक बार कॉल करने की योजना बना रहा हूं, क्या यह एक लॉगर लौटाएगा, जिसे मैं तब जारी रखूंगा।
submodules मैं एप्लिकेशन में आयात होगी ही (या बल्कि मैं उन्हें करना चाहते हैं) चाहिए
- केवल "लॉग के रूप में आयात लॉगिंग" चाहिए - कि मेरी साइट के लिए विशिष्ट कुछ भी नहीं की आवश्यकता है बनाने के लिए तो अगर वे किसी और को उपयोगी पाते हैं तो वे सिर्फ दौड़ते हैं।
- को केवल log.info/error('message 'के साथ संदेशों को लॉग इन करना चाहिए, उन्हें साइट-विशिष्ट कुछ भी जोड़ने के बिना
- को पहले से कॉन्फ़िगर किए गए' रूट 'लॉगर का उपयोग अपने सभी स्वरूपण और हैंडरों के साथ करना चाहिए और रूट लॉगर को प्रभावित नहीं करना चाहिए विन्यास
* custom_logger.py *
import logging
import logging.handlers
import os
import sys
def getLogger(name='root', loglevel='INFO'):
logger = logging.getLogger(name)
# if logger 'name' already exists, return it to avoid logging duplicate
# messages by attaching multiple handlers of the same type
if logger.handlers:
return logger
# if logger 'name' does not already exist, create it and attach handlers
else:
# set logLevel to loglevel or to INFO if requested level is incorrect
loglevel = getattr(logging, loglevel.upper(), logging.INFO)
logger.setLevel(loglevel)
fmt = '%(asctime)s %(filename)-18s %(levelname)-8s: %(message)s'
fmt_date = '%Y-%m-%dT%T%Z'
formatter = logging.Formatter(fmt, fmt_date)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
if logger.name == 'root':
logger.warning('Running: %s %s',
os.path.basename(sys.argv[0]),
' '.join(sys.argv[1:]))
return logger
फिर submodule जो है और क्या नहीं क्या काम करता है के उदाहरण के साथ कुछ परीक्षण संदेश हैं आता है।
submodule.py
import sys
import custom_logger
import logging
class SubClass(object):
def __init__(self):
# NOK (no idea why since by default (no name parameter), it should return the root logger)
#log = logging.getLogger()
#log.info('message from SubClass/__init__')
# OK (works as expected)
#log = logging.getLogger('root')
#log.info('message from SubClass/__init__')
# OK (works as expected)
log = custom_logger.getLogger('root')
log.info('message from SubClass/__init__')
def SomeMethod(self):
# OK but I'd have to define `log` for every method, which is unacceptable
# Please see question below all code snippets
log = custom_logger.getLogger('root')
log.info('message from SubClass/SomeMethod')
और मुख्य अनुप्रयोग: app.py यहां कुछ भी विशेष:
#!/usr/bin/python
import custom_logger
import submodule
log = custom_logger.getLogger('root', loglevel='DEBUG')
log.debug('debug message')
log.info('info message')
log.warning('warning message')
log.error('error message')
a = submodule.SubClass() # this should produce a log message
a.SomeMethod() # so should this
आउटपुट है कि मैं के बाद और है कि मैं हो रही हूँ, बस एक बेहद बदसूरत तरीके से:
% ./app.py
2013-04-08T03:07:46BST custom_logger.py WARNING : Running: app.py
2013-04-08T03:07:46BST app.py DEBUG : debug message
2013-04-08T03:07:46BST app.py INFO : info message
2013-04-08T03:07:46BST app.py WARNING : warning message
2013-04-08T03:07:46BST app.py ERROR : error message
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/__init__
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/SomeMethod
मैं app.py में एक लॉगर को परिभाषित करने में सक्षम होना चाहता हूं और फिर submodules में app.py में पहले से कॉन्फ़िगर किए गए लॉगर का उपयोग करने के लिए केवल मानक पायथन लॉगिंग लाइब्रेरी का उपयोग करना चाहता हूं।
इसके अलावा, एक बदसूरत वैकल्पिक हल: अगर मैं submodule.py में आयात के बाद नीचे दिए गए कोड को जगह:
log = custom_logger.getLogger('root')
यह इससे पहले कि मेरे लकड़हारा app.py में कॉन्फ़िगर किया गया है, प्रभावी रूप से submodule बनाने निष्पादित किया जाएगा, मेरा ऐप लॉगिंग कॉन्फ़िगर नहीं करता है।
एक और वैकल्पिक हल मैं माना: उपवर्ग वर्ग के constuctor अंदर ही मैंने
self.log = custom_logger.getLogger('root')
को परिभाषित करने और उसके बाद self.log.error ('कुछ त्रुटि') इस्तेमाल कर सकते हैं। एक अच्छा तरीका होना चाहिए - अगर आप कुछ उपयोगी सुझाव दे सकते हैं या बता सकते हैं कि मैंने दस्तावेज़ को गलत समझा, तो मैं बहुत आभारी रहूंगा!
पीएस। मैंने पाइथन लॉगिंग को कितना पढ़ा है (मूल और उन्नत) और कुकबुक ताकि अगर मैंने वहां कुछ उपयोगी याद किया है, तो कृपया इसे इंगित करें।
धन्यवाद!
धन्यवाद मिहाई। मैंने सोचा कि मुझे इसमें देखने के लिए और अधिक समय लगेगा लेकिन मुझे सप्ताहांत के लिए इंतजार करना होगा। अब तक मैं अपनी कक्षा बनाने में सक्षम हूं जो सब कुछ करता है (फॉर्मेटर्स, हैंडलर और सेटिंग loglevel संलग्न) submodule.py में getLogger ऑब्जेक्ट के रूप में लॉग को परिभाषित करके काम करता है। मैं उम्मीद कर रहा था कि यह कक्षा परिभाषा के बाहर चीजों को डाले बिना किया जा सकता है। मेरा प्रश्न अधिक था "मेरे द्वारा किए गए कुछ दृष्टिकोण क्यों अपेक्षित काम नहीं करते थे क्योंकि मैं इसके पीछे कारण समझना चाहता हूं, क्योंकि मुझे एक कोड सौंपने के विरोध में, लेकिन मैं आपकी मदद की सराहना करता हूं:) –
मैंने अपना जवाब अपडेट किया। अन्यथा आप मॉड्यूल के कोड में देख सकते हैं। आप देख सकते हैं कि आयात के दौरान रूट लॉगर को तुरंत चालू किया जाता है। मुझे यह भी समझ में नहीं आता कि क्यों लॉगर ("रूट") एक ही काम नहीं करता है सभी परिस्थितियों में (आप app.py.py में getLogger() प्राप्त कर सकते हैं और submodule.py में getLogger ("root") प्राप्त कर सकते हैं और आपको जो चाहिए वह आपको मिलता है, लेकिन इसके विपरीत नहीं) – Mihai
यह फ़ाइल पर stdout रीडायरेक्ट के साथ कैसे काम करें उदाहरण के लिए python ./app.py >> file.log? –