1. 程式人生 > >python-logging模組的簡單使用:如何同時輸出到控制檯和本地日誌檔案

python-logging模組的簡單使用:如何同時輸出到控制檯和本地日誌檔案

本文簡單記錄logging模組使用方法。參考部落格
提供兩種記錄日誌的方式:

  • 使用logging提供的模組級別的函式
  • 使用logging模組的四大元件

一、簡單使用——函式

下面是常用函式

logging.debug()
logging.info()
logging.warning()
logging.error()
logging.critical() #輸出函式,級別從低到高逐漸遞增
logging.log(logging.debug, msg)#與上面的函式等價
logging.basicConfig()#配置函式

1.配置函式說明

通過設定配置函式(basicConfig)然後,呼叫log列印函式就可以滿足簡單的使用了,下面對配置函式接收引數進行簡單的說明。

引數名稱 描述
filename 指定輸出檔名,如果指定後就不會輸出到控制檯。
format 指定日誌格式字串,詳細見下面。
datefmt 指定時間格式。只有在format包含%(asctime)才有效
level 指定日誌級別
stream 指定日誌輸出目標stream,比如sys.stdout等(預設是sys.stderr)。
handlers python 3.3新新增的,該項如果被指定,應該是一個建立了多個Handler的可迭代物件,這些handler將會被新增到root logger。注意filename、stream和handlers只能有一個存在,否則會引發ValueError異常

2.格式字串——format

使用格式 描述
%(asctime)s 日誌事件發生的時間——人類可讀時間,可以通過datefmt修改格式
%(created)f 日誌事件發生的時間——時間戳
%(levelname)s 日誌級別
%(name)s 日誌器名稱,預設是‘root’
%(message)s 日誌記錄的文字內容
%(pathname)s 呼叫日誌記錄函式的原始碼檔案的全路徑
%(filename)s pathname的檔名部分,包含字尾
%(lineno)s 呼叫日誌記錄函式的原始碼所在行號
%(fucName)s 呼叫日誌函式名

3.樣例

程式

LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"

logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)

logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")

檔案輸出內容

08/26/2018 15:37:14 PM - DEBUG - This is a debug log.
08/26/2018 15:37:14 PM - INFO - This is a info log.
08/26/2018 15:37:14 PM - WARNING - This is a warning log.
08/26/2018 15:37:14 PM - ERROR - This is a error log.
08/26/2018 15:37:14 PM - CRITICAL - This is a critical log.

4.注意事項

  • logging.basicConfig()函式是一個一次性簡單配置工具,只會在第一次呼叫時生效,後續再次呼叫將不會產生任何效果。
  • 日誌器(Logger)是有層級關係的,上面呼叫的logging模組級別的函式所使用的日誌器是RootLogger類的例項,名稱為’root’,它處於日誌器層級關係最頂層的日誌器,以單例模式存在。

二、高階使用——四大元件

元件名稱 對應類名 功能描述
日誌器 Logger 提供了應用程式使用的結構的介面
處理器 Handler 將logger建立的日誌記錄傳送發合適的目的輸出
過濾器 Filter 提供了更細粒度的控制工具來決定輸出哪條日誌記錄,丟棄哪條日誌記錄
格式器 Formatter 決定日誌記錄的最終輸出格式

整個處理流程相對而言還是很複雜,建議去看前文提到的連結
常見方法

名稱 描述
Logger.setLevel() 設定日誌器處理級別
Logger.addHandler()、Logger.removeHandler() 為該logger物件新增和移除一個handler物件
Logger.addFilter()、Logger.removeFilter() 為該logger物件新增和移除一個filter物件
Handler.setLevel() 設定handler將會處理的日誌級別
Handler.setFormatter() 為handler設定一個格式器物件
Handler.addFilter()、Handler.removeFilter() 為handler新增和刪除一個過濾物件
logging.StreamHandler 將日誌訊息傳送到輸出到Stream,如std.out,std.err
logging.FileHandler 將日誌訊息傳送到磁碟檔案,預設檔案大小會無限增長
logging.hanlders.TimeRotatingFileHandler 將日誌訊息傳送到磁碟檔案,並支援日誌檔案按時間切割

一條日誌訊息想被最終輸出,需要經過以下幾次過濾:

  • 日誌器等級過濾
  • 日誌器的過濾器過濾
  • 日誌器的處理器等級過濾
  • 日誌器的處理器的過濾器過濾

簡單例項

在該樣例中,實現了既將日誌資訊列印到控制檯,又將日誌資訊儲存到磁碟。注意以最高等級過濾為準。

import logging
import datetime
import sys

logger = logging.getLogger('mylogger')
logger.setLevel(logging.INFO)
rf_handler = logging.StreamHandler(sys.stderr)#預設是sys.stderr
rf_handler.setLevel(logging.DEBUG) 
#rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(message)s"))

f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))

logger.addHandler(rf_handler)
logger.addHandler(f_handler)

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