close

Python - 日誌 (logging) 模組

     0 留言
  1. 載入 logging 模組
  2. logging 等級
  3. 輸出 logging
  4. 紀錄堆疊追蹤資訊
  5. 自訂 logging 輸出格式
    1. 自訂輸出的時間格式
  6. 儲存 logging

開發 Python 時,很常使用 print() 來輸出變數以方便 debug,但要部署時,不需要這些訊息,需要自己手動去註解或刪除那些放在各處的 print()。而 Python 內建提供了 logging 模組可以用來取代 print()logging 除了可以輸出訊息,也可以將訊息儲存至日誌檔保存。下面紀錄如何使用 logging 模組。

載入 logging 模組

1
import logging

logging 等級

logging 模組預先定義了 6 種等級以及對應的 log 輸出函數 (除了 logging.NOTSET 沒有對應的輸出函數):

等級 等級數值 輸出函數 說明
NOTSET 0 無對應的輸出函數 未設定
DEBUG 10 logging.debug() 除錯
INFO 20 logging.info() 訊息
WARNING 30 logging.warning() 警告
ERROR 40 logging.error() 錯誤
CRITICAL 50 logging.critical() 嚴重錯誤

若要查詢各等級的數值,可直接呼叫該等級:

1
2
3
4
5
6
7
8
import logging

print(logging.NOTSET)   # 0
print(logging.DEBUG)    # 10
print(logging.INFO)     # 20
print(logging.WARNING)  # 30
print(logging.ERROR)    # 40
print(logging.CRITICAL) # 50

若要用等級數值來查詢是哪個等級的訊息,可使用 logging.getLevelName(level)

1
2
3
4
5
6
7
8
import logging

print(logging.getLevelName(0))    # NOTSET
print(logging.getLevelName(10))   # DEBUG
print(logging.getLevelName(20))   # INFO
print(logging.getLevelName(30))   # WARNING
print(logging.getLevelName(40))   # ERROR
print(logging.getLevelName(50))   # CRITICAL

輸出 logging

logging 模組預設等級為 WARNING,大於或等於 WARNING 等級的訊息才會被記錄:

1
2
3
4
5
6
7
import logging

logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

下面是輸出結果,可以看到比 WARNING 等級還要低的訊息有 DEBUG  INFO 就不會被輸出:

1
2
3
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

若將等級設為 DEBUG,就會將所有等級的訊息都輸出:

1
2
3
4
5
6
7
8
9
import logging

logging.basicConfig(level=logging.DEBUG)

logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

下面是輸出結果,預設的訊息輸出格式是 %(levelname)s:%(name)s:%(message)s (後面會介紹如何自訂輸出格式):

1
2
3
4
5
DEBUG:root:debug message
INFO:root:info message
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

紀錄堆疊追蹤資訊

logging 模組也提供可以紀錄完整的堆疊追蹤 (stack traces),若在 logging.error() 加上 exc_info 參數,並將該參數設為 True,就可以紀錄 Exception,如下:

1
2
3
4
5
6
import logging

try:
    x = 5 / 0
except:
    logging.error("Catch an exception.", exc_info=True)

下面是輸出結果:

1
2
3
4
5
ERROR:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero

若沒有加上 exc_info=True 則無法紀錄 Exception:

1
2
3
4
5
6
import logging

try:
    x = 5 / 0
except:
    logging.error("Catch an exception.")

下面是輸出結果:

1
ERROR:root:Catch an exception.

若要在 logging 內紀錄 exception 訊息,可使用 logging.exception(),它會將 exception 添加至訊息中,此方法的等級為 ERROR,也就是說 logging.exception() 就等同於 logging.error(exc_info=True)

1
2
3
4
5
6
import logging

try:
    x = 5 / 0
except:
    logging.exception('Catch an exception.')

輸出結果和 logging.error(exc_info=True) 相同:

1
2
3
4
5
ERROR:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero

若不想使用 ERROR 級別紀錄 exception 訊息,可使用 DEBUGINFOWARNINGCRITICAL 級別並加上參數 exc_info=True 的設定:

1
2
3
4
5
6
7
8
9
10
11
import logging

logging.basicConfig(level=logging.DEBUG)

try:
    x = 5 / 0
except:
    logging.debug('Catch an exception.', exc_info=True)
    logging.info('Catch an exception.', exc_info=True)
    logging.warning('Catch an exception.', exc_info=True)
    logging.critical('Catch an exception.', exc_info=True)

下面是輸出結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DEBUG:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero
INFO:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero
WARNING:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero
CRITICAL:root:Catch an exception.
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    x = 5 / 0
ZeroDivisionError: division by zero

自訂 logging 輸出格式

預設的訊息輸出格式只有 levelnamenamemessage,下面是其他相關的資訊:

arrow
arrow
    全站熱搜

    歐巴珊手繪設計 發表在 痞客邦 留言(0) 人氣()