Python LOGGING使用方法


Python LOGGING使用方法

1. 簡介

使用場景

場景 適合使用的方法
在終端輸出程序或腳本的使用方法 print
報告一個事件的發生(例如狀態的修改) logging.info()或logging.debug()
發生了一個特定的警告性的事件 logging.warn()
發生了一個特定的錯誤性的事件 raise
發生了一個特定的錯誤性的事件,但是又不想因為此錯誤導致程序退出(例如程序是一個守護進程) logging.error(),logging.exception(),logging.critical()

日志的嚴重程度

由高到低

Level
CRITICAL
ERROR
WARNING
INFO
DEBUG

logging默認的嚴重程度是WARNING,即在這個嚴重程度或以上的日志才會被記錄。

有兩種常用的記錄日志的方式:

  1. 輸出到終端
import logging
logging.error('hello1')
  1. 記錄到文件,也就是硬盤
import logging
logging.basicConfig(filename='./log.log',level=logging.DEBUG)
logging.error('hello1')

basicConfig方法用於快速設置日志,有下面的參數:

  • filename 包日志保存到哪個文件
  • filemode記錄日志的模式,a代表在文件中追加日志,w是刪除原有文件,創建新文件。
  • format 設置日志IDE輸出格式,
  • level 日志的嚴重程度,
  • datefmt 日期格式
  • stream 日志輸出到那里,如果有filename參數,忽略改參數

logging中包含了四個主要的類:

  • logger 提供應用程序直接使用的接口
  • handler將日志記錄到指定的輸出,例如文件或終端
  • filter提供了對日志進行過濾的功能
  • formatter決定日志記錄的最終輸出格式。

2. logger

  1. 命名空間 
    每個logger都會有一個名字。名字中使用點號來進行等級管理。例如scanscan.htmlscan.pdf的上級 
    logging中建議使用logger = logging.getLogger(__name__)來獲取logger,因為__name__代表當前模塊的路徑

  2. 日志流 
    當應用程序執行一個寫日志操作時,例如logging.info(),日志流程圖: 
    ![enter image description here] (http://7xpt1q.com1.z0.glb.clouddn.com/img/doc/logging_flow.png)

  • 如果logger有父類,日志流會同時發送給logger和logger的父類的handler。

    ```python
    allot_logger('scan', './scan.log')
    allot_logger('scan.pdf', './scan.pdf.log')
    scan_log = logging.getLogger('scan')
    scan_pdf_log = logging.getLogger('scan.pdf')
    scan_log.info('scan_log')  # 日志只會輸出到./scan.log文件
    scan_pdf_log.info('scan_pdf_log')  # 日志會輸出到./scan.log和./scan.pdf.log兩個文件
    ```
    
  1. 方法

    • Logger.setLevel() 設置logger的日志嚴重程度
    • logger.addHandler() ,Logger.remoteHandler()添加或刪除Handler
    • Logger.addFilter,Logger.remoteFilter()添加或刪除Filter
    • Logger.debug(), Logger.info(), Logger.warning(), Logger.error(), and Logger.critical()記錄日志,其中debug是日志等級。支持字符串格式化,例如logging.debug('error_msg:%s',error_msg)
    • Logger.log(level,msg) 。logging.log(logging.WARN,'msg')等於logging.warn(msg)
  2. 屬性

  • Logger.handlers 該logger已添加的Handlers
  • Logger.filters 該logger已添加的Filters
  1. 獲取Logger實例 
    通過getLogger() 來獲取logger。

3. Handler

一個logger可以設置0個或以上的Handler。logger執行記錄日志的方法后,會把日志交給Handler來處理。

1. 方法

  • Handler.setLevel() 設置logger的日志嚴重程度
  • Handler.addFilter,Handler.remoteFilter()添加或刪除Filter
  • setFormatter() 設置日志輸出的格式

2. Handler類

  1. logging.StreamHandler 
    輸出日志到一個文件對象,可以是open打開的文件,也可以是系統終端,例如sys.stdout或sys.stderr 
    。它的構造函數是: 
    StreamHandler([strm])
  • 其中strm是一個文件對象。默認是sys.stderr.
  • demo:
f=open('./test1.log','w')
handler3=logging.StreamHandler(f)
import sys
handler4=logging.StreamHandler(sys.stdout)
  1. logging.FileHandler 
    向一個文件中輸出日志內容。如果文件根路徑不存在,會報錯。如果文件根路徑存在,但是文件不存在,會自動創建文件。 
    。它的構造函數是: 
    FileHandler(filename[,mode])
  • filename是日志文件路徑。
  • mode是寫文件的方法,例如’a’,’w’,參考open里面的mode
  1. logging.handlers.RotatingFileHandler 
    類似FileHandler,不同的是這個可以管理文件的大小,如果日志文件大於某個值,就會把舊的日志重命名,並創建新的日志文件。如果有三個日志文件chat.log,chat.log.1,chat.log.2 ,時間大小:chat.log>chat.log.1>chat.log.2

    它的構造函數是: 
    RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])

  • 其中filename和mode兩個參數和FileHandler一樣。
  • maxBytes 最大文件大小,單位字節,0代表無限大。
  • backupCount 保留的備份個數。
  • demo:
handler = RotatingFileHandler('./test.log', maxBytes=10, backupCount=5)
  1. logging.handlers.TimedRotatingFileHandler 
    這個Handler和RotatingFileHandler類似,不同的是這個Handler通過時間來切分日志文件: 
    TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 
    其中filename參數和backupCount參數和RotatingFileHandler具有相同的意義
    • interval是時間間隔。
    • when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有以下取值: 
      S 秒 
      M 分 
      H 小時 
      D 天 
      W 每星期(interval==0時代表星期一) 
      midnight 每天凌晨
  2. logging.handlers.SocketHandler
  3. logging.handlers.DatagramHandler 
    以上兩個Handler類似,都是將日志信息發送到網絡。不同的是前者使用TCP協議,后者使用UDP協議。它們的構造函數是: 
    Handler(host, port) 
    其中host是主機名,port是端口名
  4. logging.handlers.SysLogHandler
  5. logging.handlers.NTEventLogHandler
  6. logging.handlers.SMTPHandler
  7. logging.handlers.MemoryHandler
  8. logging.handlers.HTTPHandler

4. Formatter

logging.Formatter('%(asctime)s %(levelname)s %(module)s.%(funcName)s Line:%(lineno)d %(message)s')

常用格式:

%(name)s Logger的名字
%(levelno)s 數字形式的日志級別
%(levelname)s 文本形式的日志級別
%(pathname)s 調用日志輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日志輸出函數的模塊的文件名
%(module)s 調用日志輸出函數的模塊名
%(funcName)s 調用日志輸出函數的函數名
%(lineno)d 調用日志輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標准的表示時間的浮 點數表示
%(relativeCreated)d 輸出日志信息時的,自Logger創建以 來的毫秒數
%(asctime)s 字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號后面的是毫秒
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
%(message)s 用戶輸出的消息
 

5. 常用工具

1. 初始化一個logger

def allot_logger(name, filename, level=None, format=None):
'''
初始化一個logger
:param name: logger名稱
:param filename: 日志文件路徑
:param format: 日志格式
:param level: 日志的嚴重程度
:return:
'''
if level == None:
level = logging.DEBUG
if format == None:
format = '%(asctime)s %(levelname)s %(module)s.%(funcName)s Line:%(lineno)d %(message)s'
logger = logging.getLogger(name)
if not logger.handlers:
logger.setLevel(level)
handler = logging.FileHandler(filename)
handler.setFormatter(
logging.Formatter(format))
logger.handlers = [handler]
  • 如果logger有多個handler,這樣會輸出重復的日志,所以添加handler前,先判斷handler的數量,而且采用設置handlers屬性的方式而不是addHandler方法,解決多線程同步問題。

參考: 
python 日志模塊 logging 詳解 
PSL LOGGING模塊教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM