解決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類中的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è)屬性為True,就會(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中內(nèi)置的日志模塊logging用法詳解
- python標(biāo)準(zhǔn)日志模塊logging的使用方法
- Python中使用logging模塊打印log日志詳解
- Python中使用logging模塊代替print(logging簡(jiǎn)明指南)
- Python logging模塊handlers用法詳解
- Python使用logging模塊實(shí)現(xiàn)打印log到指定文件的方法
- Python logging日志模塊 配置文件方式
- 詳解?python?logging日志模塊
- Python中的logging模塊實(shí)現(xiàn)日志打印
- Python中l(wèi)ogging模塊用法示例總結(jié)
相關(guān)文章
使用基于Python的Tornado框架的HTTP客戶端的教程
這篇文章主要介紹了制作一個(gè)基于Python的Tornado框架的HTTP客戶端的教程,Tornado的異步特性使其能夠獲得很好的性能,需要的朋友可以參考下2015-04-04
Windows系統(tǒng)下多版本pip的共存問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于在Windows系統(tǒng)下多版本pip的共存問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
安裝pyhttpx解決ImportError: DLL load failed錯(cuò)誤
這篇文章主要為大家介紹了安裝pyhttpx解決ImportError: DLL load failed錯(cuò)誤,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
基于Flask+websocket實(shí)現(xiàn)一個(gè)在線聊天室
在今天的互聯(lián)網(wǎng)時(shí)代,實(shí)時(shí)通信成為了許多應(yīng)用和服務(wù)的核心特色,在本文中,我們將介紹如何使用 Flask 和 Websockets 通過(guò) Flask-SocketIO 框架創(chuàng)建一個(gè)簡(jiǎn)單的在線聊天室,感興趣的可以跟隨小編一起了解下2023-09-09
Python基于matplotlib繪制棧式直方圖的方法示例
這篇文章主要介紹了Python基于matplotlib繪制棧式直方圖的方法,涉及Python使用matplotlib進(jìn)行圖形繪制的相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
python中使用you-get庫(kù)批量在線下載bilibili視頻的教程
這篇文章主要介紹了使用python中you-get庫(kù)批量在線下載bilibili視頻的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
Python實(shí)現(xiàn)將多個(gè)文件的名稱或后綴名由大寫改為小寫
這篇文章主要介紹了如何基于Python語(yǔ)言實(shí)現(xiàn)將多個(gè)文件的名稱或后綴名由大寫字母修改為小寫,文中的示例代碼講解詳細(xì),感興趣的可以了解下2023-09-09
Python實(shí)現(xiàn)簡(jiǎn)單求解給定整數(shù)的質(zhì)因數(shù)算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)簡(jiǎn)單求解給定整數(shù)的質(zhì)因數(shù)算法,結(jié)合實(shí)例形式分析了Python正整數(shù)分解質(zhì)因數(shù)的相關(guān)操作技巧,需要的朋友可以參考下2018-03-03
python開發(fā)之tkinter實(shí)現(xiàn)圖形隨鼠標(biāo)移動(dòng)的方法
這篇文章主要介紹了python開發(fā)之tkinter實(shí)現(xiàn)圖形隨鼠標(biāo)移動(dòng)的方法,涉及Python基于tkinter繪圖的相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11

