創用 CC 授權條款
除非另有註明,本網站的著作Fygul Hether製作,以創用CC 姓名標示-非商業性-禁止改作 4.0 國際 授權條款釋出。

2017年11月26日 星期日

Python logging模組

在某些情況,在Python程式中要對程式的執行狀況做些記錄,比如排程在凌晨三點執行下載某種資料的程式,程式若只是把執行狀況的資訊顯示在螢幕上,若程式結束,這些資訊就不見了。像這時候較好的作法是把這些資訊存到記錄檔中。Python標準庫中的logging模組在這方面提供了相當方便的途徑,只需做個簡單設置,簡單幾行代碼就可以解決。

以下以簡單的例子說明logging模組的簡易用法。

簡單設置與使用


import logging

logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO)
logging.info('一般訊息。')
此例子中設置了一個名為my_app.log的記錄檔,指定記錄層級為INFO。檔案為write模式,即程式啟動時,會丟棄舊內容寫入新的。預設模式是'a'即附加(append)在原內容之後。

最後寫入一條INFO層級的訊息到記錄檔中。這裡所謂的level(層級),即所要記錄訊息所屬的層級種類,或是嚴重的程度,這由程式員自行決定。

logging的幾個標準層級level如下,越後面的層級越高:
  • DEBUG:最詳細的訊息,通常用在分析問題時。
  • INFO:一般正常的訊息。
  • WARNING:警告訊息。指示有某種問題發生,但程式仍如預期般正常運作。
  • ERROR:錯誤訊息。
  • CRITICAL:嚴重錯誤訊息。
預設層級是WARNING,即只對WARNING、ERROR、CRITICAL層級的訊息做記錄。

而logging用來記錄不同層級訊息的函式的命名就來自於這些層級,分別是:
  • debug()
  • info()
  • warning()
  • error()
  • critical()
上例中如果沒有basicCofig()那行,即不做設置時,訊息會寫到螢幕(console)上。但因預設層級是WARNING,所以logging.info()那行的訊息就不會顯示了。要WARNING或以上的層級才會顯示:

logging.warning('警告訊息!')
上例沒有設置訊息的格式,所看到的訊息會像: 
INFO:root:一般訊息。
這是預設的記錄格式,其格式是levelname:name:message。格式是可以修改的。

如果想改成levelname - message,那麼basicConfig()可改成:

logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO, format='{levelname} - {message}', style='{')
format參數中的格式字串,可以有三種型式,即Python用的三種格式字串的方式:%-style, str.format()與string.Template,預設是%-style。style參數則分別是'%', '{'與'$',預設是'%'。

這裡用str.format()的style來格式字串,故要再指定style參數。

格式字串中的levelname, message是LogRecord屬性的名稱,還有其他的屬性可用,像asctime是時間,預設格式是YYYY-MM-DD hh:mm:ss,sss。如果想用不同格式,可用datefmt參數指定,如:

logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO, format='{asctime} - {levelname} - {message}', style='{', datefmt='%Y/%m/%d %H:%M:%S')
datefmt參數所用字串格式的方式與time.strftime()相同。

最後提醒一下,在同一Python session裡,logging.basicConfig()只作用一次,重複做是無效的。同時,logging.warning()這類函式若不慎寫在loggin.bascConfig()之前也會讓後者沒有作用。試一下以下代碼並觀察一下結果就知道了:

import logging

logging.warning('未bascConfig()就warning()!')

logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO)
logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO, format='{levelname} - {message}', style='{')
logging.basicConfig(filename='my_app.log', filemode='w', level=logging.INFO, format='{asctime} - {levelname} - {message}', style='{', datefmt='%Y/%m/%d %H:%M:%S')
logging.info('一般訊息。')
logging.warning('警告訊息!')
這個代碼把前面的範例都集合在一起,再加了一行,純粹展示用,實際應用時別這麼做。也可註釋掉不要的行,並在不同的Python session中執行以觀察結果。

以上只是簡單使用,logging可以做到很複雜的事,詳細可見以下參考中的官方文件。

參考

  • https://docs.python.org/3/howto/logging.html 
  • https://docs.python.org/3/library/logging.html

沒有留言:

張貼留言