python程序调试logging_python-logging模块的简单使用
本人是新手程序員,寫文章是為了記錄學(xué)習(xí),文章中多有錯(cuò)誤,還望大家諒解,并指出問題。
本文用到的技術(shù)與工具:python,pycharm,logging等。
最近寫了一個(gè)程序demo,一天24小時(shí)掛著跑,有時(shí)候會(huì)報(bào)錯(cuò),雖然不會(huì)影響程序繼續(xù)跑,但是問題總是要解決的,又不能24小時(shí)守著,所有想寫個(gè)日志記錄錯(cuò)誤信息,日志當(dāng)然已經(jīng)搞定了啦,下面是正文。
日志是什么,日志的作用是什么,這里就不一一贅述了,這里使用python的logging模塊來進(jìn)行日志操作。
1、logging模塊的日志級(jí)別
logging模塊默認(rèn)定義了以下幾個(gè)日志等級(jí),它允許開發(fā)人員自定義其他日志級(jí)別,但是這是不被推薦的,尤其是在開發(fā)供別人使用的庫時(shí),因?yàn)檫@會(huì)導(dǎo)致日志級(jí)別的混亂。logging默認(rèn)日志等級(jí)
開發(fā)應(yīng)用程序或部署開發(fā)環(huán)境時(shí),可以使用DEBUG或INFO級(jí)別的日志獲取盡可能詳細(xì)的日志信息來進(jìn)行開發(fā)或部署調(diào)試;
應(yīng)用上線或部署生產(chǎn)環(huán)境時(shí),應(yīng)該使用WARNING或ERROR或CRITICAL級(jí)別的日志來降低機(jī)器的I/O壓力和提高獲取錯(cuò)誤日志信息的效率。日志級(jí)別的指定通常都是在應(yīng)用程序的配置文件中進(jìn)行指定的。
注意:
~上圖列表中的日志等級(jí)是從上到下依次升高的,即:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次減少的;
~當(dāng)為某個(gè)應(yīng)用程序指定一個(gè)日志級(jí)別后,應(yīng)用程序會(huì)記錄所有日志級(jí)別大于或等于指定日志級(jí)別的日志信息,而不是僅僅記錄指定級(jí)別的日志信息,只有級(jí)別大于或等于該指定日志級(jí)別的日志記錄才會(huì)被輸出,小于該等級(jí)的日志記錄將會(huì)被丟棄。
2、logging模塊的使用方式
logging模塊提供了兩種使用方式:一、使用logging提供的模塊級(jí)別的函數(shù);二、使用Logging日志系統(tǒng)的四大組件。logging所提供的模塊級(jí)別的日志記錄函數(shù)是對logging日志系統(tǒng)相關(guān)類的封裝
上述是我參考的資料中所說的,看了第一種方式的使用過程,我有點(diǎn)不太理解如何自如使用,既然說到是對第二種方式的封裝,那我大概理解成了我太菜了,還沒到那個(gè)等級(jí),所有本文就不介紹第一種方式了,直接第二種方式開擼!
3、使用Logging日志系統(tǒng)的四大組件,日志流的處理流程
首先給大家看一下logging模塊定義的模塊級(jí)別的常用函數(shù),如下圖:logging模塊定義的模塊級(jí)別的常用函數(shù)
關(guān)于logging.basicConfig()函數(shù),我百度了大量資料,在眾多資料中有些提到該函數(shù)的參數(shù)時(shí)包含了handlers,有些沒有,參數(shù)handlers的使用方法仍未找到,希望有大佬知道的可以教一下我,logging.basicConfig()函數(shù)的參數(shù)說明如下圖:logging.basicConfig()函數(shù)的參數(shù)說明
我們已經(jīng)知道logging的常用函數(shù),下面看看lgging模塊的四大組件:lgging模塊的四大組件
這些組件之間是什么樣的關(guān)系呢?日志器(logger)需要通過處理器(handler)將日志信息輸出到目標(biāo)位置,如:文件、sys.stdout、網(wǎng)絡(luò)等;
不同的處理器(handler)可以將日志輸出到不同的位置;
日志器(logger)可以設(shè)置多個(gè)處理器(handler)將同一條日志記錄輸出到不同的位置;
每個(gè)處理器(handler)都可以設(shè)置自己的過濾器(filter)實(shí)現(xiàn)日志過濾,從而只保留感興趣的日志;
每個(gè)處理器(handler)都可以設(shè)置自己的格式器(formatter)實(shí)現(xiàn)同一條日志以不同的格式輸出到不同的地方。
簡單點(diǎn)說就是:日志器(logger)是入口,真正干活兒的是處理器(handler),處理器(handler)還可以通過過濾器(filter)和格式器(formatter)對要輸出的日志內(nèi)容做過濾和格式化等處理操作。
3.1、logger類
logger對象有三個(gè)任務(wù)要做:1)向應(yīng)用程序代碼暴露幾個(gè)方法,使應(yīng)用程序可以在運(yùn)行時(shí)記錄日志消息;
2)基于日志嚴(yán)重等級(jí)(默認(rèn)的過濾設(shè)施)或filter對象來決定要對哪些日志進(jìn)行后續(xù)處理;
3)將日志消息傳送給所有感興趣的日志handlers。
Logger對象最常用的方法分為兩類:配置方法 和 消息發(fā)送方法
最常用配置方法如下:logger對象常用配置方法
logger對象配置完成后,可以使用下面的方法來創(chuàng)建日志記錄:創(chuàng)建日志記錄的方法
通常使用logging.getLogger()方法創(chuàng)建一個(gè)logger實(shí)例,logging.getLogger()方法有一個(gè)可選參數(shù)name,該參數(shù)表示將要返回的日志器的名稱標(biāo)識(shí),如果不提供該參數(shù),則其值為'root'。若以相同的name參數(shù)值多次調(diào)用getLogger()方法,將會(huì)返回指向同一個(gè)logger對象的引用。多次使用注意不能創(chuàng)建多個(gè)logger,否則會(huì)出現(xiàn)重復(fù)輸出日志現(xiàn)象。
3.2、handler類
Handler對象的作用是(基于日志消息的level)將消息分發(fā)到handler指定的位置(文件、網(wǎng)絡(luò)、郵件等)。Logger對象可以通過addHandler()方法為自己添加0個(gè)或者更多個(gè)handler對象。
需要說明的是,應(yīng)用程序代碼不應(yīng)該直接實(shí)例化和使用Handler實(shí)例。因?yàn)镠andler是一個(gè)基類,它只定義了素有handlers都應(yīng)該有的接口,同時(shí)提供了一些子類可以直接使用或覆蓋的默認(rèn)行為。下面是一些常用的Handler:常用Handler
3.3、formatter類
Formater對象用于配置日志信息的最終順序、結(jié)構(gòu)和內(nèi)容。
3.4、filter類
Filter可以被Handler和Logger用來做比level更細(xì)粒度的、更復(fù)雜的過濾功能。
日志流簡要處理流程(按照日志時(shí)間切割)
1、創(chuàng)建一個(gè)logger,如果參數(shù)為空則返回root logger
logger = logging.getLogger('')
2、設(shè)置下logger的日志的等級(jí)
logger.setLevel(logging.DEBUG)
3、創(chuàng)建合適的Handler(FileHandler要有路徑),我這里創(chuàng)建了一個(gè)根據(jù)時(shí)間切分的Handler
下方代碼中,'when='S''表示以秒切割文件;'interval=1'表示切割的標(biāo)準(zhǔn)為間隔為1秒;'backupCount=3'表示日志文件總數(shù)為3,也就是說日志文件數(shù)等于3時(shí),后面生成的日志文件會(huì)替換掉時(shí)間最早的日志文件;fh.suffix設(shè)置日志文件名時(shí)間后綴。
fh = logging.handlers.TimedRotatingFileHandler("test.log", when='S', interval=1, backupCount=3, encoding="utf-8")
fh.suffix = "%Y-%m-%d_%H-%M-%S.log"
ch = logging.StreamHandler()
4、創(chuàng)建日志的格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(message)s",
datefmt="%Y/%m/%d %X"
)
5、向Handler中添加上面創(chuàng)建的格式
fh.setFormatter(formatter)
ch.setFormatter(formatter)
6、將上面創(chuàng)建的Handler添加到logger中
logger.addHandler(fh)
logger.addHandler(ch)
7、打印輸出
logger.warning("警告")
logger.info("提示")
logger.error("錯(cuò)誤")
logger.debug("查錯(cuò)")
例子:
import logging
import logging.handlers #按時(shí)間切割一定要導(dǎo)入該模塊
def log():
logger = logging.getLogger("") ?#創(chuàng)建logger,如果參數(shù)為空則返回root logger
logger.setLevel(logging.DEBUG) ?#設(shè)置logger日志等級(jí)
#這里進(jìn)行判斷,如果logger.handlers列表為空,則添加,否則,直接去寫日志
if not logger.handlers:
#創(chuàng)建handler
#按照時(shí)間切分文件,interval指間隔時(shí)間數(shù)目,backupCount指保留的文件個(gè)數(shù)
fh = logging.handlers.TimedRotatingFileHandler("test.log", when='S', interval=1, backupCount=3, encoding="utf-8")
fh.suffix = "%Y-%m-%d_%H-%M-%S.log"
ch = logging.StreamHandler()
#設(shè)置輸出日志格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(message)s",
datefmt="%Y/%m/%d %X"
)
#為handler指定輸出格式
fh.setFormatter(formatter)
ch.setFormatter(formatter)
#為logger添加的日志處理器
logger.addHandler(fh)
logger.addHandler(ch)
return logger #直接返回logger
logger = log()
logger.warning("警告")
logger.info("提示")
logger.error("錯(cuò)誤")
logger.debug("查錯(cuò)")
上面的例子中標(biāo)紅部分"if not?logger.handlers:"是為了解決重復(fù)寫日志問題,當(dāng)然還有其他解決方案,比如在為logger添加日志處理器后removeHandler,具體用哪種方案看個(gè)人喜好吧。
例子運(yùn)行看看效果如何,控制臺(tái)
控制臺(tái)打印出了日志信息,運(yùn)行四次程序看看生成的日志文件,運(yùn)行四次程序生成的日志文件
第一次運(yùn)行生成了“test.log”文件,后面三次生成了按照時(shí)間切割后的文件,再運(yùn)行一次看看,運(yùn)行第五次程序后生成的日志文件
可以看到后綴為43的文件被替換成了后綴為49的文件,成功!
主要參考資料鏈接地址:https://www.cnblogs.com/yuanyongqiang/p/11913812.html
總結(jié)
以上是生活随笔為你收集整理的python程序调试logging_python-logging模块的简单使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cmv空调与志高区别
- 下一篇: pythonandroid自动化测试仪器