python的logging模組
部落格轉自:https://www.cnblogs.com/CJOKER/p/8295272.html
用Python寫程式碼的時候,在想看的地方寫個print xx 就能在控制檯上顯示列印資訊,這樣子就能知道它是什麼了,但是當我需要看大量的地方或者在一個檔案中檢視的時候,這時候print就不大方便了,所以Python引入了logging模組來記錄我想要的資訊。
print也可以輸入日誌,logging相對print來說更好控制輸出在哪個地方,怎麼輸出及控制訊息級別來過濾掉那些不需要的資訊。
1、日誌級別
import logging # 引入logging模組 # 將資訊列印到控制檯上 logging.debug(u"蒼井空") logging.info(u"麻生希") logging.warning(u"小澤瑪利亞") logging.error(u"桃谷繪里香") logging.critical(u"瀧澤蘿拉")
回顯:
上面可以看到只有後面三個能打印出來
預設生成的root logger的level是logging.WARNING,低於該級別的就不輸出了
級別排序:CRITICAL > ERROR > WARNING > INFO > DEBUG
debug : 列印全部的日誌,詳細的資訊,通常只出現在診斷問題上
info : 列印info,warning,error,critical級別的日誌,確認一切按預期執行
warning : 列印warning,error,critical級別的日誌,一個跡象表明,一些意想不到的事情發生了,或表明一些問題在不久的將來(例如。磁碟空間低”),這個軟體還能按預期工作
error : 列印error,critical級別的日誌,更嚴重的問題,軟體沒能執行一些功能
critical : 列印critical級別,一個嚴重的錯誤,這表明程式本身可能無法繼續執行
這時候,如果需要顯示低於WARNING級別的內容,可以引入NOTSET級別來顯示:
import logging # 引入logging模組 logging.basicConfig(level=logging.NOTSET) #設定日誌級別 logging.debug(u"如果設定了日誌級別為NOTSET,那麼這裡可以採取debug、info的級別的內容也可以顯示在控制檯上了")
回顯:
2、部分名詞解釋
Logging.Formatter:這個類配置了日誌的格式,在裡面自定義設定日期和時間,輸出日誌的時候將會按照設定的格式顯示內容。
Logging.Logger:Logger是Logging模組的主體,進行以下三項工作:
1.為程式提供記錄日誌的介面
2.判斷日誌所處級別,並判斷是否要過濾
3.根據其日誌級別將該條日誌分發給不同handler
常用函式有:
Logger.setLevel()設定日誌級別
Logger.addHandler()和 Logger.removeHandler()新增和刪除一個Handler
Logger.addFilter()新增一個Filter,過濾作用
Logging.Handler:Handler基於日誌級別對日誌進行分發,如設定為WARNING級別的Handler只會處理WARNING及以上級別的日誌。
常用函式有:
setLevel()設定級別
setFormatter()設定Formatter
3、日誌輸出-控制檯
import logging # 引入logging模組 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # logging.basicConfig函式對日誌的輸出格式及方式做相關配置 # 由於日誌基本配置中級別設定為DEBUG,所以一下列印資訊將會全部顯示在控制檯上 logging.info('this is a loggging info message') logging.debug('this is a loggging debug message') logging.warning('this is loggging a warning message') logging.error('this is an loggging error message') logging.critical('this is a loggging critical message')
上面程式碼通過logging.basicConfig函式進行配置了日誌級別和日誌內容輸出格式;因為級別為DEBUG,所以會將DEBUG級別以上的資訊都輸出顯示再控制檯上。
回顯:
4、日誌輸出-檔案
import logging # 引入logging模組 import os.path import time # 第一步,建立一個logger logger = logging.getLogger() logger.setLevel(logging.INFO) # Log等級總開關 # 第二步,建立一個handler,用於寫入日誌檔案 rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) log_path = os.path.dirname(os.getcwd()) + '/Logs/' log_name = log_path + rq + '.log' logfile = log_name fh = logging.FileHandler(logfile, mode='w') fh.setLevel(logging.DEBUG) # 輸出到file的log等級的開關 # 第三步,定義handler的輸出格式 formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s") fh.setFormatter(formatter) # 第四步,將logger新增到handler裡面 logger.addHandler(fh) # 日誌 logger.debug('this is a logger debug message') logger.info('this is a logger info message') logger.warning('this is a logger warning message') logger.error('this is a logger error message') logger.critical('this is a logger critical message')
回顯(開啟同一目錄下生成的檔案):
5、日誌輸出-控制檯和檔案
只要在輸入到日誌中的第二步和第三步插入一個handler輸出到控制檯: 建立一個handler,用於輸出到控制檯 ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 輸出到console的log等級的開關 第四步和第五步分別加入以下程式碼即可 ch.setFormatter(formatter) logger.addHandler(ch) 6、format常用格式說明 %(levelno)s: 列印日誌級別的數值 %(levelname)s: 列印日誌級別名稱 %(pathname)s: 列印當前執行程式的路徑,其實就是sys.argv[0] %(filename)s: 列印當前執行程式名 %(funcName)s: 列印日誌的當前函式 %(lineno)d: 列印日誌的當前行號 %(asctime)s: 列印日誌的時間 %(thread)d: 列印執行緒ID %(threadName)s: 列印執行緒名稱 %(process)d: 列印程序ID %(message)s: 列印日誌資訊
7、捕捉異常,用traceback記錄
import os.path import time import logging # 建立一個logger logger = logging.getLogger() logger.setLevel(logging.INFO) # Log等級總開關 # 建立一個handler,用於寫入日誌檔案 rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) log_path = os.path.dirname(os.getcwd()) + '/Logs/' log_name = log_path + rq + '.log' logfile = log_name fh = logging.FileHandler(logfile, mode='w') fh.setLevel(logging.DEBUG) # 輸出到file的log等級的開關 # 定義handler的輸出格式 formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s") fh.setFormatter(formatter) logger.addHandler(fh) # 使用logger.XX來記錄錯誤,這裡的"error"可以根據所需要的級別進行修改 try: open('/path/to/does/not/exist', 'rb') except (SystemExit, KeyboardInterrupt): raise except Exception, e: logger.error('Failed to open file', exc_info=True)
回顯(儲存在檔案中):
如果需要將日誌不上報錯誤,僅記錄,可以將exc_info=False,回顯如下: 8、多模組呼叫logging,日誌輸出順序
warning_output.py import logging def write_warning(): logging.warning(u"記錄檔案warning_output.py的日誌") error_output.py import logging def write_error(): logging.error(u"記錄檔案error_output.py的日誌")
main.py
import logging import warning_output import error_output def write_critical(): logging.critical(u"記錄檔案main.py的日誌") warning_output.write_warning() # 呼叫warning_output檔案中write_warning方法 write_critical() error_output.write_error() # 呼叫error_output檔案中write_error方法
回顯:
從上面來看,日誌的輸出順序和模組執行順序是一致的。
9、日誌滾動和過期刪除(按時間
# coding:utf-8 import logging import time import re from logging.handlers import TimedRotatingFileHandler from logging.handlers import RotatingFileHandler def backroll(): #日誌列印格式 log_fmt = '%(asctime)s\tFile \"%(filename)s\",line %(lineno)s\t%(levelname)s: %(message)s' formatter = logging.Formatter(log_fmt) #建立TimedRotatingFileHandler物件 log_file_handler = TimedRotatingFileHandler(filename="ds_update", when="M", interval=2, backupCount=2) #log_file_handler.suffix = "%Y-%m-%d_%H-%M.log" #log_file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}.log$") log_file_handler.setFormatter(formatter) logging.basicConfig(level=logging.INFO) log = logging.getLogger() log.addHandler(log_file_handler) #迴圈列印日誌 log_content = "test log" count = 0 while count < 30: log.error(log_content) time.sleep(20) count = count + 1 log.removeHandler(log_file_handler) if __name__ == "__main__": backroll()
filename:日誌檔名的prefix;
when:是一個字串,用於描述滾動週期的基本單位,字串的值及意義如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
interval: 滾動週期,單位有when指定,比如:when=’D’,interval=1,表示每天產生一個日誌檔案
backupCount: 表示日誌檔案的保留個數
1、日誌級別
import logging # 引入logging模組
# 將資訊列印到控制檯上
logging.debug(u"蒼井空")
logging.info(u"麻生希")
logging.warning(u"小澤瑪利亞")
logging.error(u"桃谷繪里香")
logging.critical(u"瀧澤蘿拉")