標籤:包含 ica zha 控制台 filter alt 並且 eve print
logging模組:
很多程式都有記錄日誌的需求,並且日誌中包含的資訊既有正常的程式訪問日誌,還可能有錯誤、警告等資訊輸出。Python的logging模組提供了標準的日誌介面,你可以通過它儲存各種格式的日誌。logging的日誌可以分為debug()、info()、warning()、error() and critical()5個層級(按順序,層級越來越高)。
最簡單的用法:
import logginglogging.warning(‘User [neo] attempted wrong password more than 3 times‘)logging.critical(‘server is down‘)# 運行結果: # 跟print沒啥區別# WARNING:root:User [neo] attempted wrong password more than 3 times# CRITICAL:root:server is down
記錄層級:
把日誌寫到檔案裡:
import logginglogging.basicConfig(filename=‘logging_test.log‘,level=logging.INFO) # Do basic configuration for the logging system. # level=logging.INFO的意思是:只有日誌是INFO或者比INFO層級更高的日誌才會被記錄在檔案裡 # 記錄日誌時,只會接著以前的日誌繼續記錄,不會把以前的記錄覆蓋掉。logging.debug(‘debug test‘)logging.info(‘INFO info‘)logging.warning(‘Warning!‘)# 運行結果: 把logging.info和logging.warning記錄在了 ‘logging_test.log’(.log的尾碼名)這個檔案裡。 # 這種情況下螢幕上沒列印,即 沒有輸出到螢幕# 如下所示:# INFO:root:INFO info# WARNING:root:Warning!
把時間加到日誌裡面:
import logginglogging.basicConfig(filename=‘logging_with_time.log‘, level=logging.INFO, format=‘%(asctime)s %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S‘) # 注意裡面的參數‘format’和‘datefmt’logging.debug(‘debug test‘)logging.info(‘INFO info‘)logging.warning(‘Warning!‘)# 運行結果: INFO及其以上層級寫入了‘logging_with_time.log’檔案裡面# 如下所示:# 2018-02-09 11:37:11 INFO info# 2018-02-09 11:37:11 Warning!
除了加時間,還可以自訂其他的格式,下表就是所有支援的格式:
logging進階:日誌同時輸出到螢幕和檔案:
Python使用logging模組記錄日誌涉及四個主要的類:
- logger提供了應用程式可以直接使用的介面
- handler將(logger建立的)日誌記錄發送到合適的目的輸出
- filter提供了細度裝置來決定輸出哪條日誌記錄
- formatter決定日誌記錄的最終輸出格式
它們之間的關係如下:
logger:
每個程式在輸出資訊之前都要先獲得一個logger,如:
import logging# 產生 logger 對象logger = logging.getLogger(‘web‘) # logger通常對應了程式的模組名# 對logger對象設定Level層級,如設定成INFO層級 logger.setLevel(logging.INFO) # 利用logger.setLevel()對產生的logger對象順位, logging.INFO是把層級具體設定成INFO,如果你不設定,系統會預設把Level設定成WARNING。 # 對logger對象設定level的作用: logger。setLevel()相當於一個全域變數,所需要輸出的日誌需要先經過logging.getLogger產生logger對象,所以產生logger對象之前,會先檢測所輸出的記錄層級是否符合logger.setLevel的層級,如果符合則產生logger對象;如果不符合則直接忽略、不產生logger對象。 舉例說明: 有兩個需要輸出的日誌: logger.debug(‘test debug‘) 和 logger.info(‘test info‘) , 執行這兩句代碼的時候, 由於我已經給產生logger設定了level --- INFO:logger.setLevel(logging.INFO) ,debug的level低於INFO, 所以 logger.debug(‘test debug‘) 不會產生logger對象,但 logger.info(‘test info‘) 則會產生logger對象(相當於第一步產生logger對象時過濾了一部分資料)
handler:
handler負責發送相關的資訊到指定目的地。 Python日誌系統有多種handler可以使用。可以把資訊輸出到控制台(螢幕),也可以把資訊輸出到檔案,把資訊發送到網路上。自己也可以編寫自己的handler。
每個logger可以附加多個handler。常用的handler如下:
- logging.StreamHandler # 使用這個handler可以向類似於sys.stdout 或者 sys.stderr 的任何檔案對象(file object)輸出資訊(往螢幕上輸出)
- logging.FileHandler 和 StreamHandler類似, 用於向一個檔案輸出日誌資訊,不過FileHandler會幫你開啟這個檔案(往檔案中輸出)
- 還有兩種用法:一是根據檔案大小截斷;二是根據時間interval截斷。 詳情參考: https://www.luffycity.com/python-book/di-4-zhang-python-ji-chu-2014-chang-yong-mo-kuai/logging-mo-kuai.html
用法如下:
# 產生logger對象之後,再產生handler對象,然後把handler綁定到logger上# 產生handler對象ch = logging.StreamHandler() # 負責往螢幕發送的handler(發送到螢幕,所以括弧裡面為空白)fh = logging.FileHandler(‘web.log‘) # 負責往檔案“web.log”發送的handler # 記錄檔的尾碼名: .log# 把產生的handler對象綁定到logger對象logger.addHandler(ch) # 把ch這個handler對象綁定到logger上logger.addHandler(fh) # 把fh這個handler對象綁定到logger上# 設定handler的levelch.setLevel(logging.INFO) # 把ch這個handler對象的level設定成INFOfh.setLevel(logging.WARNING) # 把fh這個handler對象的level設定成WARNING# 關於設定handler的level,道理跟logger的level設定類似,即: 如果你不設定, 程式會預設level是WARNING;通過這一步設定的level能夠再次“過濾”資料# 關於logger設定的level和handler設定的level,按照哪個level呢? 效果上可以這麼理解: 所需要輸出的日誌(如: logger.warning(xx)), 先經過logger設定的level“過濾”,然後在產生handler對象這一步, 再次經過這一步的level“過濾”:level符合,則產生相應的handler;level不符合則忽略、不產生handler對象。
formatter組件:
日誌的formatter是個獨立的組件,可以跟handler組合, 用於設定所要發送的資訊以什麼樣的格式發送到目的地。
用法:
# 產生handler對象之後,再產生formatter對象,然後將formatter對象和handler綁定# 產生formatter對象console_fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s‘) # 利用上面的logger名字表file_fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)# 把formatter對象綁定到handlerch.setFormatter(console_fmt)fh.setFormatter(file_fmt)
下面把上述的代碼拼接到一起看效果:
import logging# 產生logger對象logger = logging.getLogger(‘web‘)logger.setLevel(logging.INFO)# 產生handler對象ch = logging.StreamHandler()fh = logging.FileHandler(‘web.log‘)# 設定levelch.setLevel(logging.DEBUG)fh.setLevel(logging.WARNING)# 把handler綁定在logger上logger.addHandler(ch)logger.addHandler(fh)# 產生formatter對象console_fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s‘)file_fmt = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) # %(name)s 這個name就是產生logger時括弧裡面的‘web’# 把formatter綁定到handlerch.setFormatter(console_fmt)fh.setFormatter(file_fmt)logger.debug(‘debug test‘)logger.info(‘info test‘)logger.warning(‘warning test‘)logger.error(‘error test‘)logger.critical(‘critical test‘) # 輸出的日誌
filter的用法參考: https://www.luffycity.com/python-book/di-4-zhang-python-ji-chu-2014-chang-yong-mo-kuai/logging-mo-kuai.html
Python模組:logging、