कई मॉड्यूल में लॉगिंग का उपयोग करना


257

मेरे पास एक छोटा अजगर प्रोजेक्ट है जिसमें निम्नलिखित संरचना है -

Project 
 -- pkg01
   -- test01.py
 -- pkg02
   -- test02.py
 -- logging.conf

मैं संदेश को stdout और एक लॉग फ़ाइल को प्रिंट करने के लिए डिफ़ॉल्ट लॉगिंग मॉड्यूल का उपयोग करने की योजना बना रहा हूं। लॉगिंग मॉड्यूल का उपयोग करने के लिए, कुछ आरंभीकरण आवश्यक है -

import logging.config

logging.config.fileConfig('logging.conf')
logger = logging.getLogger('pyApp')

logger.info('testing')

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


3
मेरे जवाब पर आपकी टिप्पणी के जवाब में: आपको fileConfigहर मॉड्यूल में कॉल करने की ज़रूरत नहीं है जो लॉगिंग करता है, जब तक कि आपके पास if __name__ == '__main__'उन सभी में तर्क नहीं है। यदि पैकेज एक लाइब्रेरी है, तो प्रॉपर्टी का जवाब अच्छा अभ्यास नहीं है, हालांकि यह आपके लिए काम कर सकता है - किसी को जोड़ने के अलावा, लाइब्रेरी पैकेज में लॉगिंग कॉन्फ़िगर नहीं करना चाहिए NullHandler
विनय साजिप

1
प्रॉपर्टी का अर्थ है कि हमें हर मॉड्यूल में आयात और लकड़हारा stmts को कॉल करने की आवश्यकता है, और केवल मुख्य मॉड्यूल में fileconfig stmt को कॉल करें। कि आप क्या कह रहे हैं के समान नहीं है?
क्वेस्ट मोंगर

6
प्रॉपर्टी कह रही है कि आपको लॉगिंग कॉन्फिगर कोड डालना चाहिए package/__init__.py। यह आमतौर पर आपके द्वारा if __name__ == '__main__'कोड डालने की जगह नहीं है । इसके अलावा, प्रॉपर्टी का उदाहरण ऐसा लगता है कि यह आयात पर बिना शर्त कॉन्फिगर कोड कहेगा, जो मुझे सही नहीं लगता। आम तौर पर, लॉगिन कोड एक ही स्थान पर किया जाना चाहिए और आयात के साइड-इफेक्ट के रूप में नहीं होना चाहिए, जब आप __main__ आयात कर रहे हों।
विनय साजिप

आप सही हैं, मैंने अपने कोड नमूने में लाइन '# पैकेज / __ init__.py' को पूरी तरह से याद किया। बिंदु के लिए धन्यवाद कि बाहर और आपके धैर्य।
क्वेस्ट मोंगर

1
यदि आपके पास कई हैं तो क्या होता है if __name__ == '__main__'? (यदि यह मामला है तो यह स्पष्ट रूप से उल्लेखित नहीं है)
kon psych

जवाबों:


293

सबसे अच्छा अभ्यास, प्रत्येक मॉड्यूल में, एक लकड़हारा को इस तरह परिभाषित करना है:

import logging
logger = logging.getLogger(__name__)

मॉड्यूल के शीर्ष के पास, और फिर मॉड्यूल में अन्य कोड में जैसे

logger.debug('My message with %s', 'variable data')

यदि आपको किसी मॉड्यूल के अंदर लॉगिंग गतिविधि को कम करने की आवश्यकता है, उदाहरण के लिए उपयोग करें

loggerA = logging.getLogger(__name__ + '.A')
loggerB = logging.getLogger(__name__ + '.B')

और उपयुक्त के रूप में लॉग इन करें loggerAऔर loggerB

अपने मुख्य कार्यक्रम या कार्यक्रमों में, जैसे:

def main():
    "your program code"

if __name__ == '__main__':
    import logging.config
    logging.config.fileConfig('/path/to/logging.conf')
    main()

या

def main():
    import logging.config
    logging.config.fileConfig('/path/to/logging.conf')
    # your program code

if __name__ == '__main__':
    main()

देखें यहाँ कई मॉड्यूल से प्रवेश करने के लिए, और यहाँ जो अन्य कोड से एक पुस्तकालय मॉड्यूल के रूप में इस्तेमाल किया जाएगा कोड के लिए लॉगिंग विन्यास के लिए।

अद्यतन: जब fileConfig()आप कॉल disable_existing_loggers=Falseकर रहे हैं, तो आप निर्दिष्ट कर सकते हैं कि आप पाइथन 2.6 या बाद का उपयोग कर रहे हैं ( अधिक जानकारी के लिए डॉक्स देखें)। डिफ़ॉल्ट मान Trueपिछड़ी संगतता के लिए है, जो सभी मौजूदा लॉगर को fileConfig()तब तक अक्षम कर देता है जब तक कि उन्हें या उनके पूर्वजों को स्पष्ट रूप से कॉन्फ़िगरेशन में नाम नहीं दिया जाता है। के लिए निर्धारित मान के साथ False, मौजूदा लॉगर अकेले छोड़ दिए जाते हैं। यदि Python 2.7 / Python 3.2 या बाद के संस्करण का उपयोग कर रहे हैं, तो आप dictConfig()API पर विचार करना पसंद कर सकते हैं जो बेहतर है fileConfig()क्योंकि यह कॉन्फ़िगरेशन पर अधिक नियंत्रण देता है।


21
यदि आप मेरे उदाहरण को देखते हैं, तो मैं पहले से ही वही कर रहा हूं जो आप ऊपर सुझाते हैं। मेरा सवाल यह था कि मैं इस लॉगिंग इनिशियलाइज़ेशन को केंद्रीकृत कैसे करूँ कि मुझे उन 3 कथनों को दोहराना न पड़े। इसके अलावा, आपके उदाहरण में आप 'logging.config.fileConfig (' logging.conf ')' stmt 'से चूक गए। यह stmt वास्तव में मेरी चिंता का मूल कारण है। आप देखें, अगर मैंने हर मॉड्यूल में लकड़हारा शुरू किया है, तो मुझे हर मॉड्यूल में इस stmt को लिखना होगा। इसका मतलब होगा कि प्रत्येक मॉड्यूल में conf फ़ाइल का मार्ग ट्रैक करना, जो मुझे एक सर्वोत्तम अभ्यास की तरह नहीं दिखता है (मॉड्यूल / पैकेज स्थानों को बदलते समय कहर की कल्पना करें)।
क्वेस्ट मोंगर

4
यदि आप लकड़हारा बनाने के बाद fileConfig को कॉल करते हैं, चाहे वह समान या किसी अन्य मॉड्यूल में (जैसे जब आप फ़ाइल के शीर्ष पर लकड़हारा बनाते हैं) काम नहीं करता है। लॉगिंग कॉन्फ़िगरेशन केवल उसके बाद बनाए गए लॉगर्स पर लागू होता है। तो यह दृष्टिकोण काम नहीं करता है या कई मॉड्यूल के लिए एक व्यवहार्य विकल्प नहीं है। @ क्वेश्च मोंगर: आप हमेशा एक और फाइल बना सकते हैं जो कॉन्फिगर फाइल की लोकेशन रखती है ..;)
विंसेंट केटेलार्स

2
@Oxidator: ज़रूरी नहीं है - उस disable_existing_loggersध्वज को देखें जो Trueडिफ़ॉल्ट रूप से है लेकिन इसे सेट किया जा सकता है False
विनय साजिप

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

1
अगर मैं चाहता हूं कि मेरे सभी मॉड्यूल विशिष्ट लॉगर्स के पास डिफ़ॉल्ट चेतावनी से भिन्न स्तर है, तो क्या मुझे प्रत्येक मॉड्यूल पर उस सेटिंग को बनाना होगा? कहो, मैं अपने सभी मॉड्यूल को INFO में लॉग इन करना चाहता हूं।
राज

127

वास्तव में हर लकड़हारा माता-पिता के पैकेज लकड़हारे का बच्चा होता है (यानी package.subpackage.moduleकॉन्फ़िगरेशन से इनहेरिट करता है package.subpackage), इसलिए आपको बस इतना करना होगा कि रूट लॉगर को कॉन्फ़िगर करना होगा। यह प्राप्त किया जा सकता है logging.config.fileConfig( लकड़हारा के लिए आपका अपना कॉन्फ़िगरेशन) या logging.basicConfig(रूट लकड़हारा सेट करता है) अपने प्रवेश मॉड्यूल में सेटअप लॉगिंग ( __main__.pyया आप जो भी चलाना चाहते हैं, उदाहरण के लिए main_script.py__init__.pyसाथ ही साथ काम करता है)

BasicConfig का उपयोग करना:

# package/__main__.py
import logging
import sys

logging.basicConfig(stream=sys.stdout, level=logging.INFO)

FileConfig का उपयोग कर:

# package/__main__.py
import logging
import logging.config

logging.config.fileConfig('logging.conf')

और फिर प्रत्येक लकड़हारा का उपयोग कर बनाएँ:

# package/submodule.py
# or
# package/subpackage/submodule.py
import logging
log = logging.getLogger(__name__)

log.info("Hello logging!")

अधिक जानकारी के लिए उन्नत लॉगिंग ट्यूटोरियल देखें ।


15
यह अब तक समस्या का सबसे सरल समाधान है, इसका उल्लेख नहीं करने के लिए मॉड्यूल के बीच माता-पिता के बच्चे के संबंध को उजागर करता है और लाभ उठाता है, कुछ ऐसा जो मैं एक noob के रूप में अनजान था। danke।
क्वेस्ट मोंगर

तुम सही हो। और जब तक विनय ने अपनी पोस्ट में बताया, आपका समाधान तब तक सही है, जब तक कि यह init .py मॉड्यूल में न हो। जब मैंने इसे मुख्य मॉड्यूल (प्रविष्टि के बिंदु) पर लागू किया तो आपके समाधान ने काम किया।
क्वेस्ट मोंगर

2
प्रश्न वास्तव में बहुत अधिक प्रासंगिक उत्तर है क्योंकि प्रश्न अलग-अलग मॉड्यूल से संबंधित है।
जनवरी सिला

1
गूंगा सवाल शायद: अगर कोई लकड़हारा नहीं है __main__.py(जैसे अगर मैं किसी स्क्रिप्ट में मॉड्यूल का उपयोग करना चाहता हूं जिसमें कोई लकड़हारा नहीं है) तब logging.getLogger(__name__)भी मॉड्यूल में किसी प्रकार का लॉगिंग करेगा या यह अपवाद को बढ़ाएगा?
बिल

1
आखिरकार। मेरे पास एक कार्यशील लकड़हारा था, लेकिन यह जॉबलिब के साथ समानांतर रन के लिए विंडोज में विफल रहा। मुझे लगता है कि यह सिस्टम के लिए एक मैनुअल ट्विक है - समानांतर के साथ कुछ और गलत है। लेकिन, यह निश्चित रूप से काम करता है! धन्यवाद
बी फर्टाडो

17

मैं हमेशा इसे नीचे की तरह करता हूं।

मेरे लॉग को सिंगलटन पैटर्न के रूप में कॉन्फ़िगर करने के लिए एक एकल अजगर फ़ाइल का उपयोग करें जिसका नाम ' log_conf.py'

#-*-coding:utf-8-*-

import logging.config

def singleton(cls):
    instances = {}
    def get_instance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return get_instance()

@singleton
class Logger():
    def __init__(self):
        logging.config.fileConfig('logging.conf')
        self.logr = logging.getLogger('root')

एक अन्य मॉड्यूल में, बस कॉन्फ़िगरेशन आयात करें।

from log_conf import Logger

Logger.logr.info("Hello World")

यह केवल और कुशलता से लॉग इन करने के लिए एक सिंगलटन पैटर्न है।


1
सिंगलटन पैटर्न का विवरण देने के लिए धन्यवाद। मैं इसे लागू करने की योजना बना रहा था, लेकिन तब @prost समाधान अधिक सरल है और मेरी आवश्यकताओं पर पूरी तरह से खरा उतरता है। लेकिन मैं देखता हूं कि आपका समाधान उपयोगी है बड़ी परियोजनाएं जिनमें प्रवेश के कई बिंदु हैं (मुख्य के अलावा)। danke।
क्वेस्ट मोंगर

46
यह बेकार है। रूट लॉगर पहले से ही एक सिंगलटन है। केवल Logger.logr.info के बजाय logging.info का उपयोग करें।
पॉड

9

इनमें से कई उत्तर आपको एक मॉड्यूल के शीर्ष पर सुझाव देते हैं जो आप करते हैं

import logging
logger = logging.getLogger(__name__)

यह मेरी समझ है कि यह बहुत बुरा अभ्यास माना जाता है । कारण यह है कि फ़ाइल कॉन्फ़िगरेशन डिफ़ॉल्ट रूप से सभी मौजूदा लॉगर को अक्षम कर देगा। उदाहरण के लिए

#my_module
import logging

logger = logging.getLogger(__name__)

def foo():
    logger.info('Hi, foo')

class Bar(object):
    def bar(self):
        logger.info('Hi, bar')

और आपके मुख्य मॉड्यूल में:

#main
import logging

# load my module - this now configures the logger
import my_module

# This will now disable the logger in my module by default, [see the docs][1] 
logging.config.fileConfig('logging.ini')

my_module.foo()
bar = my_module.Bar()
bar.bar()

अब logging.ini में निर्दिष्ट लॉग खाली होगा, क्योंकि मौजूदा लॉगगर को fileconfig कॉल द्वारा अक्षम कर दिया गया था।

हालांकि, इसके चारों ओर प्राप्त करना निश्चित रूप से संभव है (disable_existing_Loggers = False), वास्तविक रूप से आपकी लाइब्रेरी के कई क्लाइंट इस व्यवहार के बारे में नहीं जानते होंगे, और आपके लॉग प्राप्त नहीं करेंगे। हमेशा स्थानीय स्तर पर लॉगिंग.गेटलॉगर को कॉल करके अपने ग्राहकों के लिए इसे आसान बनाएं। हैट टिप: मैंने इस व्यवहार के बारे में सीखा विक्टर लिन की वेबसाइट

इसके बजाय अच्छा अभ्यास हमेशा स्थानीय रूप से लॉगिंग.गेटलॉगर को कॉल करने के बजाय है। उदाहरण के लिए

#my_module
import logging

logger = logging.getLogger(__name__)

def foo():
    logging.getLogger(__name__).info('Hi, foo')

class Bar(object):
    def bar(self):
        logging.getLogger(__name__).info('Hi, bar')    

इसके अलावा, यदि आप अपने मुख्य में fileconfig का उपयोग करते हैं, तो निष्क्रिय करें_सेस्टिंग_लॉगर्स = गलत पर सेट करें, ठीक वैसे ही जब आपके लाइब्रेरी डिजाइनर मॉड्यूल स्तर लकड़हारा इंस्टेंसेस का उपयोग करते हैं।


क्या आप logging.config.fileConfig('logging.ini')पहले नहीं दौड़ सकते import my_module? जैसा कि इस उत्तर में दिया गया है
ल्यूसिड_ड्रीमर

यकीन नहीं है - लेकिन यह निश्चित रूप से आयात और निष्पादन योग्य कोड को उस तरह से मिश्रण करने के लिए बुरा व्यवहार माना जाएगा। आप यह भी नहीं चाहते हैं कि आपके ग्राहकों को यह जाँचने की ज़रूरत है कि क्या उन्हें आयात करने से पहले लॉगिंग को कॉन्फ़िगर करने की आवश्यकता है, खासकर जब एक तुच्छ विकल्प है! सोचिए अगर अनुरोधों की तरह एक व्यापक रूप से इस्तेमाल की जाने वाली लाइब्रेरी ने ऐसा किया होता तो ....!
phil_20686

"निश्चित नहीं - लेकिन यह निश्चित रूप से इस तरह से आयात और निष्पादन योग्य कोड को मिलाने के लिए बुरा व्यवहार माना जाएगा।" - क्यों?
ल्यूसिड_ड्रीमर

मैं बहुत स्पष्ट नहीं हूं कि यह बुरा क्यों है। और मैं पूरी तरह से आपके उदाहरण को नहीं समझता। क्या आप इस उदाहरण के लिए अपना कॉन्फ़िगर पोस्ट कर सकते हैं और कुछ उपयोग दिखा सकते हैं?
ल्यूसिड_ड्रीमर

1
आप आधिकारिक डॉक्स का खंडन करते प्रतीत होते हैं : 'लॉगिंग नामकरण का उपयोग करने के लिए एक अच्छा सम्मेलन एक मॉड्यूल-स्तरीय लॉगर का उपयोग करना है, प्रत्येक मॉड्यूल में जो लॉगिंग का उपयोग करता है, जिसका नाम इस प्रकार है: logger = logging.getLogger(__name__)'
iron9

8

मेरे लिए एक से अधिक मॉड्यूल में लॉगिंग लाइब्रेरी के एक उदाहरण का उपयोग करने का एक सरल तरीका निम्नलिखित था:

base_logger.py

import logging

logger = logging
logger.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)

अन्य फ़ाइलें

from base_logger import logger

if __name__ == '__main__':
    logger.info("This is an info message")

7

दूसरे उपाय में फेंकना।

मेरे मॉड्यूल के init में .py मेरे पास कुछ इस तरह है:

# mymodule/__init__.py
import logging

def get_module_logger(mod_name):
  logger = logging.getLogger(mod_name)
  handler = logging.StreamHandler()
  formatter = logging.Formatter(
        '%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
  handler.setFormatter(formatter)
  logger.addHandler(handler)
  logger.setLevel(logging.DEBUG)
  return logger

फिर प्रत्येक मॉड्यूल में मुझे एक लकड़हारा चाहिए, मैं करता हूं:

# mymodule/foo.py
from [modname] import get_module_logger
logger = get_module_logger(__name__)

जब लॉग याद किए जाते हैं, तो आप उनके स्रोत को उनके द्वारा आए मॉड्यूल से अंतर कर सकते हैं।


"मेरे मॉड्यूल का मुख्य init" क्या मतलब है? और "फिर प्रत्येक कक्षा में मुझे लकड़हारा चाहिए, मैं करता हूं:"? क्या आप मॉड्यूल caller_module.py से आयात के रूप में इसका नमूना__मॉड्यूलहोम और इसके उपयोग का एक उदाहरण प्रदान कर सकते हैं? मैं जिस प्रारूप के बारे में पूछ रहा हूं, उसकी प्रेरणा के लिए यह उत्तर देखें । संरक्षण देने की कोशिश नहीं की जा रही है। मैं आपके उत्तर को समझने की कोशिश कर रहा हूं और मुझे पता है कि क्या आप इसे इस तरह से लिखेंगे।
ल्यूसिड_ड्रीमर

1
@lucid_dreamer मैंने स्पष्ट किया।
टॉमी

4

आप भी कुछ इस तरह से आ सकते हैं!

def get_logger(name=None):
    default = "__app__"
    formatter = logging.Formatter('%(levelname)s: %(asctime)s %(funcName)s(%(lineno)d) -- %(message)s',
                              datefmt='%Y-%m-%d %H:%M:%S')
    log_map = {"__app__": "app.log", "__basic_log__": "file1.log", "__advance_log__": "file2.log"}
    if name:
        logger = logging.getLogger(name)
    else:
        logger = logging.getLogger(default)
    fh = logging.FileHandler(log_map[name])
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    logger.setLevel(logging.DEBUG)
    return logger

अब आप एक ही मॉड्यूल में और पूरे प्रोजेक्ट में कई लॉगर का उपयोग कर सकते हैं यदि ऊपर एक अलग मॉड्यूल में परिभाषित किया गया है और अन्य मॉड्यूल में आयातित लॉगिंग की आवश्यकता थी।

a=get_logger("__app___")
b=get_logger("__basic_log__")
a.info("Starting logging!")
b.debug("Debug Mode")

4

@ यार्की का समाधान बेहतर लग रहा था। मैं इसमें कुछ जोड़ना चाहूंगा -

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances.keys():
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class LoggerManager(object):
    __metaclass__ = Singleton

    _loggers = {}

    def __init__(self, *args, **kwargs):
        pass

    @staticmethod
    def getLogger(name=None):
        if not name:
            logging.basicConfig()
            return logging.getLogger()
        elif name not in LoggerManager._loggers.keys():
            logging.basicConfig()
            LoggerManager._loggers[name] = logging.getLogger(str(name))
        return LoggerManager._loggers[name]    


log=LoggerManager().getLogger("Hello")
log.setLevel(level=logging.DEBUG)

तो LoggerManager पूरे अनुप्रयोग के लिए एक प्लग करने योग्य हो सकता है। आशा है कि यह समझ और मूल्य बनाता है।


11
लॉगिंग मॉड्यूल पहले से ही एकल के साथ काम करता है। logging.getLogger ("हैलो") को आपके सभी मॉड्यूल में समान लकड़हारा मिलेगा।
पॉड

2

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

from flask import Flask
import logging
from logging.handlers import RotatingFileHandler

app = Flask(__name__)

# make default logger output everything to the console
logging.basicConfig(level=logging.DEBUG)

rotating_file_handler = RotatingFileHandler(filename="logs.log")
rotating_file_handler.setLevel(logging.INFO)

app.logger.addHandler(rotating_file_handler)

logger.py नाम का एक अच्छा उपयोग फ़ाइल बनाया:

import logging

def get_logger(name):
    return logging.getLogger("flask.app." + name)

फ्लास्क.कैप फ्लास्क में एक हार्डकोड मूल्य है। अनुप्रयोग लकड़हारा हमेशा अपने मॉड्यूल के नाम के रूप में फ्लास्क.एप से शुरू होता है।

अब, प्रत्येक मॉड्यूल में, मैं इसे निम्न मोड में उपयोग करने में सक्षम हूं:

from logger import get_logger
logger = get_logger(__name__)

logger.info("new log")

यह न्यूनतम प्रयास के साथ "app.flask.MODULE_NAME" के लिए एक नया लॉग बनाएगा।


2

सबसे अच्छा अभ्यास अलग से एक मॉड्यूल बनाना होगा जिसमें केवल एक ही विधि हो जिसका कार्य हम कॉलिंग विधि के लिए एक लकड़हारा हैंडलर देना है। इस फ़ाइल को m_logger.py के रूप में सहेजें

import logger, logging

def getlogger():
    # logger
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    # create console handler and set level to debug
    #ch = logging.StreamHandler()
    ch = logging.FileHandler(r'log.txt')
    ch.setLevel(logging.DEBUG)
    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    # add formatter to ch
    ch.setFormatter(formatter)
    # add ch to logger
    logger.addHandler(ch)
    return logger

जब भी लकड़हारा हैंडलर की जरूरत हो, तो गेटलॉगर () विधि को कॉल करें।

from m_logger import getlogger
logger = getlogger()
logger.info('My mssg')

1
यदि आपके पास कोई अतिरिक्त पैरामीटर नहीं है तो यह अच्छा है। लेकिन अगर, मान लें, आपके पास --debugऐप में विकल्प है और आप इस पैरामीटर के आधार पर अपने ऐप में सभी लॉगर में लॉगिंग स्तर सेट करना चाहते हैं ...
गॉडफादर

@ द गॉडफादर इस पद्धति द्वारा इसे प्राप्त करना कठिन है। इस स्थिति में हम क्या कर सकते हैं कि एक ऐसी कक्षा बनाएं जिसके लिए ऑब्जेक्ट निर्माण के समय पैरामीटर के रूप में फॉर्मेटर ले जाएगा और लॉगर हैंडलर को वापस करने के लिए समान फ़ंक्शन होगा। इस पर आपके क्या विचार हैं?
मौसम सिंह

हां, मैंने इसी तरह का काम किया, get_logger(level=logging.INFO)किसी तरह के सिंगलटन को वापस करने के लिए, इसलिए जब पहली बार मुख्य ऐप से कॉल किया गया, तो यह लकड़हारे और हैंडलर को उचित स्तर के साथ आरंभ करता है और फिर उसी loggerऑब्जेक्ट को अन्य सभी तरीकों पर लौटाता है ।
द गॉडफादर

0

अजगर के लिए नया तो मुझे नहीं पता कि क्या यह उचित है, लेकिन यह बॉयलरप्लेट को दोबारा नहीं लिखने के लिए बहुत अच्छा काम करता है।

आपकी परियोजना में एक इन्टी .py होना चाहिए ताकि इसे एक मॉड्यूल के रूप में लोड किया जा सके

# Put this in your module's __init__.py
import logging.config
import sys

# I used this dictionary test, you would put:
# logging.config.fileConfig('logging.conf')
# The "" entry in loggers is the root logger, tutorials always 
# use "root" but I can't get that to work
logging.config.dictConfig({
    "version": 1,
    "formatters": {
        "default": {
            "format": "%(asctime)s %(levelname)s %(name)s %(message)s"
        },
    },
    "handlers": {
        "console": {
            "level": 'DEBUG',
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stdout"
        }
    },
    "loggers": {
        "": {
            "level": "DEBUG",
            "handlers": ["console"]
        }
    }
})

def logger():
    # Get the name from the caller of this function
    return logging.getLogger(sys._getframe(1).f_globals['__name__'])

sys._getframe(1)सुझाव यहाँ से आता है

फिर किसी अन्य फ़ाइल में अपने लकड़हारे का उपयोग करने के लिए:

from [your module name here] import logger

logger().debug("FOOOOOOOOO!!!")

चेतावनियां:

  1. आपको अपनी फ़ाइलों को मॉड्यूल के रूप में चलाना import [your module]होगा , अन्यथा काम नहीं करेगा:
    • python -m [your module name].[your filename without .py]
  2. आपके प्रोग्राम के प्रवेश बिंदु के लिए लकड़हारे का नाम होगा __main__, लेकिन किसी भी समाधान का उपयोग करने __name__पर उस समस्या होगी।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.