Python – logging Filter

測試環境為 CentOS 8 x86_64 (虛擬機)

參考文章 – https://www.pynote.net/archives/2006

透過 print 函數可以把執行 python 的訊息顯示在文字命令列上, 如果要把資料導向到檔案或是同時 顯示在文字命令列 並儲存到檔案 這時候可以透過 logging 類別來完成.

使用 logging 類別,有以下 6 個物件.

Logger <- Handler <- Formatter
   |        |
   <<<<<<<<<<<<<< Filter 
  1. Logger (紀錄器) – 用來執行日誌紀錄,透過 logging.getLogger(name=None) 來生成 .
  2. Handler (處理器) – 選擇日誌的輸出地方,常用的 Handler ,生成後透過 logger.addHandler(hdlr) 把 Handler 加到 Logger .
    • StreamHandler – 透過 logging.StreamHandler(stream=None) 來生成, 將資料輸出到標準輸出 sys.stdout, sys.stderr 或是 file-like object .
    • FileHandler – 透過 logging.FileHandler(filename, mode=’a’, encoding=None, delay=False, errors=None) 來生成 ,將資料儲存成檔案.
  3. Formatter (格式器) – 顯示訊息的格式, 透過 logging.Formatter(fmt=None, datefmt=None, style=’%’, validate=True, *, defaults=None)來生成, 生成後透過 Handler.setFormatter(fmt) 把 Formatter 加到 Handler .
  4. Filter (過濾器) – 用來控制訊息的輸出內容,看是要加到 logger 或是 Handler ,當你要所有的 Handler 都使用相同的 Filter 時就在 logger 物件透過 logger.addFilter(filter) 來生成 ,想要在個別 Handler 使用時就在 Handler 物件透過 handler.addFilter(filter) 來生成 .
  5. LogRecord – 產生 Logger 時自動生成.
  6. LoggerAdapter – 沒使用過.

下面來看一下 Filter 的使用.

  1. 範例 :
    自行定義 levelFilter 類別,主要內容是會檢查錯誤訊息的級別是否高於 Warning (等級 : NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL) 才會顯示.

    [root@localhost ~]# vi filter1.py
    import sys
    import logging
    
    class levelFilter(logging.Filter):
        def filter(self, record):
            if record.levelno < logging.WARNING:
                return False
            return True
    
    log = logging.getLogger('test')
    log.setLevel(logging.INFO)
    stream_handler = logging.StreamHandler(sys.stdout)
    log.addHandler(stream_handler)
    
    log.addFilter(levelFilter())
    log.warning('this is warning-2')
    log.info('this is info-2')
    

    執行結果,可以看到 Filter 加上 levelFilter 類別之後只會顯示高於 Warning 的訊息.

    [root@localhost ~]# python3 filter1.py
    this is warning-2
    

    說明:
    其中的 levelno – Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL). 更多 logrecord attributes 請參考 – https://docs.python.org/3/library/logging.html#logrecord-attributes

    class levelFilter(logging.Filter):
        def filter(self, record):
            if record.levelno < logging.WARNING:
                return False
            return True
    
    log = logging.getLogger('test')
    log.setLevel(logging.INFO)
    stream_handler = logging.StreamHandler(sys.stdout)
    log.addHandler(stream_handler)
    

    執行結果也已看到只有 ‘this is warning-2’ 這行字串, ‘this is info-2’ 無顯示.

    log.addFilter(levelFilter())
    log.warning('this is warning-2')
    log.info('this is info-2')
    
  2. 範例 :
    自行定義 stringFilter 類別,主要內容是會檢查訊息是否包含 abc 字串,無才會顯示.

    [root@localhost ~]# vi filter2.py
    import sys
    import logging
    
    class stringFilter(logging.Filter):
        def filter(self, record):
            if record.msg.find('abc') == -1:
                return True
            return False
    
    log = logging.getLogger('test')
    log.setLevel(logging.INFO)
    stream_handler = logging.StreamHandler(sys.stdout)
    log.addHandler(stream_handler)
    
    stream_handler.addFilter(stringFilter())
    log.warning('this is warning-3')
    log.info('this is info-3')
    log.warning('this is warning-abc')
    

    執行結果,可以看到 Filter 加上 stringFilter 類別之後只會顯示不包含 abc 的訊息(不會看到 ‘this is warning-abc’).

    [root@localhost ~]# python3 filter2.py
    this is warning-3
    this is info-3
    

    說明:
    自行定義的 stringFilter class 裡面使用到 字串物件的 find method,沒找到符合的字串時回傳 -1 .
    The find() method returns the index of first occurrence of the substring (if found). If not found, it returns -1.

    class stringFilter(logging.Filter):
        def filter(self, record):
            if record.msg.find('abc') == -1:
                return True
            return False
    
    log = logging.getLogger('test')
    log.setLevel(logging.INFO)
    stream_handler = logging.StreamHandler(sys.stdout)
    log.addHandler(stream_handler)
    
沒有解決問題,試試搜尋本站其他內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料