|
上面我曾提到過(guò),所有的對(duì)logging.getLogger(‘someLogger’)的調(diào)用都會(huì)返回同一個(gè)對(duì)象.這個(gè)規(guī)則不僅僅在同一個(gè)module有效,而且對(duì)在同一個(gè)Python的解釋器進(jìn)程里面的多個(gè)module也有效.而且,應(yīng)用代碼可以在一個(gè)module里面定義一個(gè)父logger,而在另一個(gè)module里面繼承這個(gè)logger,所有對(duì)這個(gè)子logger的調(diào)用都會(huì)轉(zhuǎn)到父logger里面去,如下所示:
下面這個(gè)是主模塊的代碼,
- import logging
- import auxiliary_module
- # create logger with "spam_application"
- logger = logging.getLogger("spam_application")
- logger.setLevel(logging.DEBUG)
- # create file handler which logs even debug messages
- fh = logging.FileHandler("spam.log")
- fh.setLevel(logging.DEBUG)
- # create console handler with a higher log level
- ch = logging.StreamHandler()
- ch.setLevel(logging.ERROR)
- # create formatter and add it to the handlers
- formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
- fh.setFormatter(formatter)
- ch.setFormatter(formatter)
- # add the handlers to the logger
- logger.addHandler(fh)
- logger.addHandler(ch)
- logger.info("creating an instance of auxiliary_module.Auxiliary")
- a = auxiliary_module.Auxiliary()
- logger.info("created an instance of auxiliary_module.Auxiliary")
- logger.info("calling auxiliary_module.Auxiliary.do_something")
- a.do_something()
- logger.info("finished auxiliary_module.Auxiliary.do_something")
- logger.info("calling auxiliary_module.some_function()")
- auxiliary_module.some_function()
- logger.info("done with auxiliary_module.some_function()")
這個(gè)是子模塊的代碼,
- import logging
- # create logger
- module_logger = logging.getLogger("spam_application.auxiliary")
- class Auxiliary:
- def __init__(self):
- self.logger = logging.getLogger("spam_application.auxiliary.Auxiliary")
- self.logger.info("creating an instance of Auxiliary")
- def do_something(self):
- self.logger.info("doing something")
- a = 1 + 1
- self.logger.info("done doing something")
- def some_function():
- module_logger.info("received a call to /"some_function/"")
可以看到, 我們?cè)谥髂K里面定義了一個(gè)logger 'spam_application', 并對(duì)他進(jìn)行了配置.
那么在這個(gè)解釋器進(jìn)程里面的任何地方去通過(guò)getLogger('spam_application')得到的對(duì)象都是一樣的, 不需要從新定義配置, 可以直接使用.
更方便的是, 你定義任意該logger的子logger, 都可以共享父logger的定義和配置
所謂的父子logger只是簡(jiǎn)單的通過(guò)命名來(lái)識(shí)別, 任意以'spam_application.'開(kāi)頭的logger都是他的子logger, 例如'spam_application.auxiliary'
這個(gè)在實(shí)際的開(kāi)發(fā)中, 還是很方便的, 對(duì)于一個(gè)application,
首先通過(guò)logging配置文件編寫(xiě)好這個(gè)application所對(duì)應(yīng)的log策略, 可以只生成一個(gè)根logger, 比如叫'Project'
然后在Main函數(shù)里面, 通過(guò)fileConfig加載logging的配置
接著在appliction的任意地方, 不同的模塊中, 可以使用Project的子logger, 如Project.UI, Project.Core, 來(lái)進(jìn)行l(wèi)og, 并且不需要反復(fù)的定義和配置各個(gè)logger.
|