解決Python logging模塊無(wú)法正常輸出日志的問(wèn)題
廢話少說(shuō),先上代碼
File:logger.conf [formatters] keys=default [formatter_default] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s class=logging.Formatter [handlers] keys=console, error_file [handler_console] class=logging.StreamHandler formatter=default args=tuple() [handler_error_file] class=logging.FileHandler level=INFO formatter=default args=("logger.log", "a") [loggers] keys=root [logger_root] level=DEBUG formatter=default handlers=console,error_file
File:logger.py #!/bin/env python import logging from logging.config import logging class Test(object): """docstring for Test""" def __init__(self): logging.config.fileConfig("logger.conf") self.logger = logging.getLogger(__name__) def test_func(self): self.logger.error('test_func function') class Worker(object): """docstring for Worker""" def __init__(self): logging.config.fileConfig("logger.conf") self.logger = logging.getLogger(__name__) data_logger = logging.getLogger('data') handler = logging.FileHandler('./data.log') fmt = logging.Formatter('%(asctime)s|%(message)s') handler.setFormatter(fmt) data_logger.addHandler(handler) data_logger.setLevel(logging.DEBUG) self.data_logger = data_logger def test_logger(self): self.data_logger.error("test_logger function") instance = Test() self.data_logger.error("test_logger output") instance.test_func() def main(): worker = Worker() worker.test_logger() if __name__ == '__main__': main()
問(wèn)題一:測(cè)試過(guò)程中,只能打印出test_logger function一條語(yǔ)句
問(wèn)題二:明明只在data_logger中打印出語(yǔ)句,但是logger的日志中也出現(xiàn)了相關(guān)的日志。
問(wèn)題一解決方案:
利用python -m pdb logger.py 語(yǔ)句對(duì)腳本進(jìn)行調(diào)試發(fā)現(xiàn),在執(zhí)行instance = Test()語(yǔ)句后,通過(guò)print '\n'.join(['%s:%s' % item for item in self.data_logger.__dict__.items()])調(diào)試語(yǔ)句看到data_logger的disable屬性值由0變成了True,此時(shí)logger的對(duì)應(yīng)屬性也發(fā)生了相同的變化。這種變化導(dǎo)致了logger對(duì)象停止記錄日志。
參考python logging模塊的相關(guān)手冊(cè)發(fā)現(xiàn)
“The fileConfig() function takes a default parameter, disable_existing_loggers, which defaults to True for reasons of backward compatibility. This may or may not be what you want, since it will cause any loggers existing before the fileConfig() call to be disabled unless they (or an ancestor) are explicitly named in the configuration.”
的說(shuō)明,即調(diào)用fileconfig()函數(shù)會(huì)將之前存在的所有l(wèi)ogger禁用。
在python 2.7版本該fileConfig()函數(shù)添加了一個(gè)參數(shù),logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True),可以顯式的將disable_existing_loggers設(shè)置為FALSE來(lái)避免將原有的logger禁用。
將上述代碼中的Test類(lèi)中的logging.config.fileConfig函數(shù)改成logging.config.fileConfig("./logger.conf", disable_existing_loggers=0)就可以解決問(wèn)題。
不過(guò)該代碼中由于位于同一程序內(nèi),可以直接用logging.getLogger(LOGGOR_NAME)函數(shù)引用同一個(gè)logger,不用再調(diào)用logging.config.fileConfig函數(shù)重新加載一遍了。
問(wèn)題二解決方案:
logger對(duì)象有個(gè)屬性propagate,如果這個(gè)屬性為T(mén)rue,就會(huì)將要輸出的信息推送給該logger的所有上級(jí)logger,這些上級(jí)logger所對(duì)應(yīng)的handlers就會(huì)把接收到的信息打印到關(guān)聯(lián)的日志中。logger.conf配置文件中配置了相關(guān)的root logger的屬性,這個(gè)root logger就是默認(rèn)的logger日志。
修改后的如下:
File:logger.conf [formatters] keys=default, data [formatter_default] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s class=logging.Formatter [formatter_data] format=%(asctime)s|%(message)s class=logging.Formatter [handlers] keys=console, error_file, data_file [handler_console] class=logging.StreamHandler formatter=default args=tuple() [handler_error_file] class=logging.FileHandler level=INFO formatter=default args=("logger.log", "a") [handler_data_file] class=logging.FileHandler level=INFO formatter=data args=("data_new.log", "a") [loggers] keys=root, data [logger_root] level=DEBUG handlers=console,error_file [logger_data] level=DEBUG handlers=data_file qualname=data propagate=0
File:logger.py #!/bin/env python import logging from logging.config import logging class Test(object): """docstring for Test""" def __init__(self): self.logger = logging.getLogger(__name__) def test_func(self): self.logger.error('test_func function') class Worker(object): """docstring for Worker""" def __init__(self): logging.config.fileConfig("logger.conf") self.logger = logging.getLogger(__name__) self.data_logger = logging.getLogger('data') def test_logger(self): self.data_logger.error("test_logger function") instance = Test() self.data_logger.error("test_logger output") instance.test_func() def main(): worker = Worker() worker.test_logger() if __name__ == '__main__': main()
以上這篇解決Python logging模塊無(wú)法正常輸出日志的問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Python logging日志模塊 配置文件方式
- Python logging模塊異步線程寫(xiě)日志實(shí)現(xiàn)過(guò)程解析
- Python日志處理模塊logging用法解析
- Python日志logging模塊功能與用法詳解
- python 日志 logging模塊詳細(xì)解析
- Python常用模塊logging——日志輸出功能(示例代碼)
- python logging模塊書(shū)寫(xiě)日志以及日志分割詳解
- Python中使用logging和traceback模塊記錄日志和跟蹤異常
- python logging日志模塊以及多進(jìn)程日志詳解
- python logging日志模塊的詳解
- python 日志模塊logging的使用場(chǎng)景及示例
相關(guān)文章
Python之list對(duì)應(yīng)元素求和的方法
今天小編就為大家分享一篇Python之list對(duì)應(yīng)元素求和的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python Selenium網(wǎng)頁(yè)自動(dòng)化利器使用詳解
這篇文章主要為大家介紹了使用Python Selenium實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Python標(biāo)準(zhǔn)庫(kù)re的使用舉例(正則化匹配)
正則表達(dá)式re是內(nèi)置函數(shù),通過(guò)一定的匹配規(guī)則獲取指定的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Python標(biāo)準(zhǔn)庫(kù)re的使用舉例,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10Python字典查找數(shù)據(jù)的5個(gè)基礎(chǔ)操作方法
Python字典是另一種可變?nèi)萜髂P?且可存儲(chǔ)任意類(lèi)型對(duì)象,如字符串、數(shù)字、元組等其他容器模型,下面這篇文章主要給大家介紹了關(guān)于Python字典查找數(shù)據(jù)的5個(gè)基礎(chǔ)操作方法,需要的朋友可以參考下2022-06-06Python工程師面試題 與Python基礎(chǔ)語(yǔ)法相關(guān)
這篇文章主要為大家分享了Python工程師面試題,面試題的內(nèi)容主要與Python基礎(chǔ)語(yǔ)法相關(guān),感興趣的小伙伴們可以參考一下2016-01-01python 通過(guò)類(lèi)中一個(gè)方法獲取另一個(gè)方法變量的實(shí)例
今天小編就為大家分享一篇python 通過(guò)類(lèi)中一個(gè)方法獲取另一個(gè)方法變量的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Python實(shí)現(xiàn)根據(jù)日期獲取當(dāng)天凌晨時(shí)間戳的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)根據(jù)日期獲取當(dāng)天凌晨時(shí)間戳的方法,涉及Python針對(duì)日期與時(shí)間戳的相關(guān)轉(zhuǎn)換、運(yùn)算等操作技巧,需要的朋友可以參考下2019-04-04Python利用matplotlib模塊數(shù)據(jù)可視化繪制3D圖
matplotlib是python最著名的繪圖庫(kù),它提供了一整套和matlab相似的命令A(yù)PI,十分適合交互式地行制圖,下面這篇文章主要給大家介紹了關(guān)于Python利用matplotlib模塊數(shù)據(jù)可視化實(shí)現(xiàn)3D圖的相關(guān)資料,需要的朋友可以參考下2022-02-02