歡迎您光臨本站 註冊首頁

python3中的logging記錄日誌實現過程及封裝成類的操作

←手機掃碼閱讀     e36605 @ 2020-05-13 , reply:0

作用:
主要記錄信息,便於定位查看問題。
python logging模塊官網:
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects
三種定位問題方法:
print
debug調試:代碼寫好後,就不需要再進行調試了,所以引入了logger
logging.debug() �C 一般在測試環境中用
logger:當生產環境中有問題時,可以查看logger定位問題
步驟:
1.初始化日誌 收集器
2.設置日誌 收集器級別 -默認是warning
3.初始化日誌 處理器 - 可以理解為寫日誌的筆
4.設置日誌 處理器級別
5.添加handler
6.設置日誌的格式
7.添加日誌處理器
8.設置不同級別的logger
這裡是引用
日誌收集器級別
1.NOSET 0 等於沒寫,廢話
2.DEBUG 10 程序調試bug時使用
3.INFO 20 程序正常運行時使用
4.WARNING 30 警告,程序未按預期運行時使用
5.ERROE 40 程序出錯
6.CRITICAL 50 嚴重問題
如何定義級別:自己定的 可以結合try: except: 記錄log
代碼實現過程如下:
```python import logging # 標準庫,直接導入。 logger = logging.getLogger("日誌名字") # 初始化日誌收集器 logger.setLevel("DEBUG") # 設置日誌收集器級別 handler = logging.FileHandler("日誌路徑") # 初始化日誌處理器 - 文件輸出(指定位置使用絕對路徑,默認當前目錄下) handler.setLevel("warning") # 設置日誌處理器級別 默認warning console_handler = logging.StreamHandler() # 控制檯輸出 console_handler.setLevel("DEBUG") logger.addHandler(handler) # 添加handler logger.addHandler(console_handler) # 設置日誌格式,中間間隔使用冒號也可以(模塊名字-報錯行-收集器名字-級別-信息) fmt = logging.Formatter("%(filename)s-%(lineno)s-%(name)s-%(levelname)s-%(massage)s") handler.setFormat(fmt) # 日誌輪轉 - 添加日誌處理器 # 設置不同級別的logger -- 選擇一個級別就可以 logging.info("") logging.debug("") logging.waring("") logging.error("") logging.critical("")
問題1:級別設置
如當設成debug的時候,只有高於,等於該級別的才會打印
如當你設成warning的時候,只有warning.error,critical才會打印
不用管(日誌收集器)的級別是啥,這裡設置就以(日誌處理器)的級別
為準,兩者中選擇最高的如果(日誌收集器)是warning,(日誌處理器)
是debug,就以warning為準,兩個都設置,這樣可以添加多個handler
問題2:實例化
在模塊中直接實例化,如果在外部實例化,容易造成多個日誌文件的生成
問題3:日誌格式設置,python logging官網,查找需要用到的。
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) # 設置收集器級別 logger.setLevel(level) # 繼承了Logger 返回的實例就是自己 # 初始化format,設置格式 fmt = logging.Formatter(format) # 初始化處理器 # 如果file為空,就執行stream_handler,如果有,兩個都執行 if file: file_handler = logging.FileHandler(file) # 設置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) # 為了確保每次是同一個文件,調用同樣的logger對象(防止手誤寫錯文件名字),所以在這裡直接初始化logger這個對象比較好 # 可以將name,file參數寫入配置文件中(這裡我是直接寫到了配置文件當中,也可以直接傳) 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 - 應該是59行打印,因為信息早就保存到logger當中了 -- 可以直接繼承logging.Logger使用
重新封裝 - 繼承logger後,發現可以直接定位到哪一行打印,可以查看源碼
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) 直接超繼承logger當中的name super().__init__(name) # 設置收集器級別 # logger.setLevel(level) self.setLevel(level) # 繼承了Logger 返回的實例就是自己 # 初始化format,設置格式 fmt = logging.Formatter(format) # 初始化處理器 # 如果file為空,就執行stream_handler,如果有,兩個都執行 if file: file_handler = logging.FileHandler(file) # 設置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) # 為了確保每次是同一個文件,調用同樣的logger對象(防止手誤寫錯文件名字),所以在這裡直接初始化logger這個對象比較好 # 可以將name,file參數寫入配置文件中(這裡我是直接寫到了配置文件當中,也可以直接傳) 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
補充知識:python3使用logging包,把日誌寫到系統的rsyslog中
最近要寫一個python程序寫日誌到rsyslog中,並通過配置rsyslog的文件來將他存到一個指定文件中。
首先,我想來看看logging提供的常用模塊:
logger:logger主要是用來配置和發送日誌消息的。可通過logging.getLogger(name)來返回一個logger對象。
不指定name就默認為root。
這裡可以取一個合適的名字。
相同的name會返回同一個logger對象。在Formatter方法中用%(name)s在日誌中打印出這個name。例如:
log = logging.getLogger('mylog') 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 handler:將日誌記錄發送到目的地,如文件,socket等。這裡可以通過addHandler方法添加多個handler,可以實現日誌的分級過濾。如果要把日誌發送到rsyslog中,就可以採用SysLogHandler(),使用這個方法前需要導入他 from logging.handlers import SysLogHandler 這個方法有兩個參數、一個是rsyslog中的facility:指定的是發送的設備,如kernel,mail,system等等,他還有local0-local7預留。這裡我採用local5。還有一個參數指定的是log程序的地址,在centos7上默認是/dev/log。示例如下: log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log') 對應的rsyslog設置文件(/etc/rsyslog.conf): local5.* /var/log/all.log #將local5的所有日誌存入all.log文件中
如果想用handler對日誌信息進行過濾,可以這樣:
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可調用參數有:
%(name)s Logger的名字
%(levelname)s 文本形式的日誌級別
%(message)s 用戶輸出的消息
%(asctime)s 字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒
%(levelno)s 數字形式的日誌級別
%(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模塊的文件名
%(module)s 調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌信息時的,自Logger創建以 來的毫秒數
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
由上面的這些模塊就可以實現我想要的功能啦
將日誌寫入到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及更高優先級的日誌


[e36605 ] python3中的logging記錄日誌實現過程及封裝成類的操作已經有249次圍觀

http://coctec.com/docs/python/shhow-post-234293.html