python3中的logging記錄日志實(shí)現(xiàn)過程及封裝成類的操作
作用:
主要記錄信息,便于定位查看問題。
python logging模塊官網(wǎng):
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects
三種定位問題方法:
debug調(diào)試:代碼寫好后,就不需要再進(jìn)行調(diào)試了,所以引入了logger
logging.debug() – 一般在測試環(huán)境中用
logger:當(dāng)生產(chǎn)環(huán)境中有問題時(shí),可以查看logger定位問題
步驟:
1.初始化日志 收集器
2.設(shè)置日志 收集器級別 -默認(rèn)是warning
3.初始化日志 處理器 - 可以理解為寫日志的筆
4.設(shè)置日志 處理器級別
5.添加handler
6.設(shè)置日志的格式
7.添加日志處理器
8.設(shè)置不同級別的logger
這里是引用
日志收集器級別
1.NOSET 0 等于沒寫,廢話
2.DEBUG 10 程序調(diào)試bug時(shí)使用
3.INFO 20 程序正常運(yùn)行時(shí)使用
4.WARNING 30 警告,程序未按預(yù)期運(yùn)行時(shí)使用
5.ERROE 40 程序出錯(cuò)
6.CRITICAL 50 嚴(yán)重問題
如何定義級別:自己定的 可以結(jié)合try: except: 記錄log
代碼實(shí)現(xiàn)過程如下:
```python import logging # 標(biāo)準(zhǔn)庫,直接導(dǎo)入。 logger = logging.getLogger("日志名字") # 初始化日志收集器 logger.setLevel("DEBUG") # 設(shè)置日志收集器級別 handler = logging.FileHandler("日志路徑") # 初始化日志處理器 - 文件輸出(指定位置使用絕對路徑,默認(rèn)當(dāng)前目錄下) handler.setLevel("warning") # 設(shè)置日志處理器級別 默認(rèn)warning console_handler = logging.StreamHandler() # 控制臺輸出 console_handler.setLevel("DEBUG") logger.addHandler(handler) # 添加handler logger.addHandler(console_handler) # 設(shè)置日志格式,中間間隔使用冒號也可以(模塊名字-報(bào)錯(cuò)行-收集器名字-級別-信息) fmt = logging.Formatter("%(filename)s-%(lineno)s-%(name)s-%(levelname)s-%(massage)s") handler.setFormat(fmt) # 日志輪轉(zhuǎn) - 添加日志處理器 # 設(shè)置不同級別的logger -- 選擇一個(gè)級別就可以 logging.info("") logging.debug("") logging.waring("") logging.error("") logging.critical("")
問題1:級別設(shè)置
如當(dāng)設(shè)成debug的時(shí)候,只有高于,等于該級別的才會打印
如當(dāng)你設(shè)成warning的時(shí)候,只有warning.error,critical才會打印
不用管(日志收集器)的級別是啥,這里設(shè)置就以(日志處理器)的級別
為準(zhǔn),兩者中選擇最高的如果(日志收集器)是warning,(日志處理器)
是debug,就以warning為準(zhǔn),兩個(gè)都設(shè)置,這樣可以添加多個(gè)handler
問題2:實(shí)例化
在模塊中直接實(shí)例化,如果在外部實(shí)例化,容易造成多個(gè)日志文件的生成
問題3:日志格式設(shè)置,python logging官網(wǎng),查找需要用到的。
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects
封裝為類
import logging class LoggerHandler(logging.Logger): def __init__(self, name="root", level="DEBUG", file=None, format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s" ): # 初始化日志收集器 logger = logging.getLogger(name) # 設(shè)置收集器級別 logger.setLevel(level) # 繼承了Logger 返回的實(shí)例就是自己 # 初始化format,設(shè)置格式 fmt = logging.Formatter(format) # 初始化處理器 # 如果file為空,就執(zhí)行stream_handler,如果有,兩個(gè)都執(zhí)行 if file: file_handler = logging.FileHandler(file) # 設(shè)置handler級別 file_handler.setLevel(level) # 添加handler logger.addHandler(file_handler) # 添加日志處理器 file_handler.setFormatter(fmt) stream_handler = logging.StreamHandler() stream_handler.setLevel(level) logger.addHandler(stream_handler) stream_handler.setFormatter(fmt) self.logger = logger def debug(self, msg): return self.logger.debug(msg) def info(self,msg): return self.logger.info(msg) def warning(self,msg): return self.logger.warning(msg) def error(self,msg): return self.logger.error(msg) def critical(self,msg): return self.logger.critical(msg) # 為了確保每次是同一個(gè)文件,調(diào)用同樣的logger對象(防止手誤寫錯(cuò)文件名字),所以在這里直接初始化logger這個(gè)對象比較好 # 可以將name,file參數(shù)寫入配置文件中(這里我是直接寫到了配置文件當(dāng)中,也可以直接傳) logger = LoggerHandler(config.logger_name,config.level,config.logger_file) # logger = LoggerHandler("python21",file="demo.txt") if __name__ == '__main__': logger = LoggerHandler() logger.debug("world") # 測試.py:40:root:DEBUG:world - 應(yīng)該是59行打印,因?yàn)樾畔⒃缇捅4娴絣ogger當(dāng)中了 -- 可以直接繼承l(wèi)ogging.Logger使用
重新封裝 - 繼承l(wèi)ogger后,發(fā)現(xiàn)可以直接定位到哪一行打印,可以查看源碼
import logging class LoggerHandler(logging.Logger): def __init__(self, name="root", level="DEBUG", file=None, format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s" ): # logger(name) 直接超繼承l(wèi)ogger當(dāng)中的name super().__init__(name) # 設(shè)置收集器級別 # logger.setLevel(level) self.setLevel(level) # 繼承了Logger 返回的實(shí)例就是自己 # 初始化format,設(shè)置格式 fmt = logging.Formatter(format) # 初始化處理器 # 如果file為空,就執(zhí)行stream_handler,如果有,兩個(gè)都執(zhí)行 if file: file_handler = logging.FileHandler(file) # 設(shè)置handler級別 file_handler.setLevel(level) # 添加handler self.addHandler(file_handler) # 添加日志處理器 file_handler.setFormatter(fmt) stream_handler = logging.StreamHandler() stream_handler.setLevel(level) self.addHandler(stream_handler) stream_handler.setFormatter(fmt) # 為了確保每次是同一個(gè)文件,調(diào)用同樣的logger對象(防止手誤寫錯(cuò)文件名字),所以在這里直接初始化logger這個(gè)對象比較好 # 可以將name,file參數(shù)寫入配置文件中(這里我是直接寫到了配置文件當(dāng)中,也可以直接傳) logger = LoggerHandler(config.logger_name,config.level,config.logger_file) # logger = LoggerHandler("python21",file="demo.txt") if __name__ == '__main__': logger = LoggerHandler() logger.debug("world") # 繼承后---測試.py:44:root:DEBUG:world
補(bǔ)充知識:python3使用logging包,把日志寫到系統(tǒng)的rsyslog中
最近要寫一個(gè)python程序?qū)懭罩镜絩syslog中,并通過配置rsyslog的文件來將他存到一個(gè)指定文件中。
首先,我想來看看logging提供的常用模塊:
logger:logger主要是用來配置和發(fā)送日志消息的??赏ㄟ^logging.getLogger(name)來返回一個(gè)logger對象。
不指定name就默認(rèn)為root。
這里可以取一個(gè)合適的名字。
相同的name會返回同一個(gè)logger對象。在Formatter方法中用%(name)s在日志中打印出這個(gè)name。例如:
log = logging.getLogger('mylog') log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') #打印結(jié)果示例: #Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message handler:將日志記錄發(fā)送到目的地,如文件,socket等。這里可以通過addHandler方法添加多個(gè)handler,可以實(shí)現(xiàn)日志的分級過濾。如果要把日志發(fā)送到rsyslog中,就可以采用SysLogHandler(),使用這個(gè)方法前需要導(dǎo)入他 from logging.handlers import SysLogHandler 這個(gè)方法有兩個(gè)參數(shù)、一個(gè)是rsyslog中的facility:指定的是發(fā)送的設(shè)備,如kernel,mail,system等等,他還有l(wèi)ocal0-local7預(yù)留。這里我采用local5。還有一個(gè)參數(shù)指定的是log程序的地址,在centos7上默認(rèn)是/dev/log。示例如下: log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log') 對應(yīng)的rsyslog設(shè)置文件(/etc/rsyslog.conf): local5.* /var/log/all.log #將local5的所有日志存入all.log文件中
如果想用handler對日志信息進(jìn)行過濾,可以這樣:
log_hdlr.setLevel(logging.ERROR) #這里就指定了接收error以及更高級別的日志 formatter:指定日志的輸出格式,包括消息格式和日期字符格式,例如: log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') #輸出示例 #Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message
formatter可調(diào)用參數(shù)有:
%(name)s Logger的名字
%(levelname)s 文本形式的日志級別
%(message)s 用戶輸出的消息
%(asctime)s 字符串形式的當(dāng)前時(shí)間。默認(rèn)格式是 “2003-07-08 16:49:45,896”。逗號后面的是毫秒
%(levelno)s 數(shù)字形式的日志級別
%(pathname)s 調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒有
%(filename)s 調(diào)用日志輸出函數(shù)的模塊的文件名
%(module)s 調(diào)用日志輸出函數(shù)的模塊名
%(funcName)s 調(diào)用日志輸出函數(shù)的函數(shù)名
%(lineno)d 調(diào)用日志輸出函數(shù)的語句所在的代碼行
%(created)f 當(dāng)前時(shí)間,用UNIX標(biāo)準(zhǔn)的表示時(shí)間的浮 點(diǎn)數(shù)表示
%(relativeCreated)d 輸出日志信息時(shí)的,自Logger創(chuàng)建以 來的毫秒數(shù)
%(thread)d 線程ID??赡軟]有
%(threadName)s 線程名。可能沒有
%(process)d 進(jìn)程ID??赡軟]有
由上面的這些模塊就可以實(shí)現(xiàn)我想要的功能啦
將日志寫入到all.log文件中-----源代碼:
import logging from logging.handlers import SysLogHandler log = logging.getLogger('mylog') log.setLevel(logging.DEBUG) log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log') log_format = logging.Formatter( 'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s') log_hdlr.setFormatter(log_format) log_hdlr.setLevel(logging.ERROR)#接受error及以上的日志信息 log.addHandler(log_hdlr) log.debug('debug message test')#指明級別為debug log.error('error message test')#指明級別為error #最后只保存error及更高優(yōu)先級的日志
可能有些地方說的不對,還望大家能夠指正!
以上這篇python3中的logging記錄日志實(shí)現(xiàn)過程及封裝成類的操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python 類屬性與實(shí)例屬性,類對象與實(shí)例對象用法分析
這篇文章主要介紹了Python 類屬性與實(shí)例屬性,類對象與實(shí)例對象用法,結(jié)合實(shí)例形式分析了java類相關(guān)的屬性、實(shí)例化、對象等相關(guān)概念與操作技巧,需要的朋友可以參考下2019-09-09python 實(shí)現(xiàn)的發(fā)送郵件模板【普通郵件、帶附件、帶圖片郵件】
這篇文章主要介紹了python 實(shí)現(xiàn)的發(fā)送郵件模板,包含Python發(fā)送普通郵件、帶附件及帶圖片郵件相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-07-07Python使用日志模塊快速調(diào)試代碼并記錄異常信息
本文詳細(xì)介紹了Python logging日志模塊的使用方法,包括如何在代碼中使用logging記錄調(diào)試信息、如何設(shè)置日志級別、如何記錄異常信息等。通過本文的指南,讀者可以快速學(xué)會如何使用logging模塊進(jìn)行調(diào)試,并保留有用的日志信息,便于后續(xù)排查問題和優(yōu)化代碼2023-04-04python selenium禁止加載某些請求的實(shí)現(xiàn)
本文主要介紹了python selenium禁止加載某些請求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01詳解在Python中創(chuàng)建條形圖追趕動(dòng)畫
動(dòng)畫是使可視化更具吸引力和用戶吸引力的好方法。它幫助我們以有意義的方式展示數(shù)據(jù)可視化。Matplotlib是一個(gè)非常流行的數(shù)據(jù)可視化庫,通常用于數(shù)據(jù)的圖形表示以及使用內(nèi)置函數(shù)的動(dòng)畫。本文將用Matplotlib繪制條形圖追趕動(dòng)畫,需要的可以參考一下2022-03-03python3.x實(shí)現(xiàn)base64加密和解密
這篇文章主要為大家詳細(xì)介紹了python3.x實(shí)現(xiàn)base64加密和解密,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03Matlab中如何實(shí)現(xiàn)將長字符串換行寫
這篇文章主要介紹了Matlab中如何實(shí)現(xiàn)將長字符串換行寫問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01