1. 程式人生 > 其它 >Python-日誌收集處理

Python-日誌收集處理

目錄:

一、logging四大元件

1. 日誌器Logger

2. 處理器Handler

3. 過濾器Filter

4. 格式器Formatter

二、Logging的工作流程:

三、設定日誌級別

四、輸出日誌記錄

五、日誌記錄配置

六、其它實用的方法

一、logging四大元件:

  • 記錄器(Logger): 提供應用程式程式碼直接使用的介面
  • 處理器(Handler): 將日誌記錄(由記錄器建立)傳送適當的目的地,即決定日誌在不同端輸出-->控制檯、日誌檔案
  • 篩選器(Filter):提供了更細粒度的功能,用於確定要輸出的日誌記錄
  • 格式器(Formatter):程式在最終輸出日誌記錄的內容格式
  1. 日誌器Logger

    1. 1建立日誌器,若沒有指定日誌器名稱,則預設root

logger = logging.getLogger()
print(logger)      

輸出結果:#<RootLogger root (WARNING)>

1.2 當有多個具有相同名稱的日誌器,呼叫任一日誌器時將返回對同一記錄物件的引用

注:這種情況下的handler是相互疊加的,由於logging每次輸出日誌記錄數量 = handler數量,如有多個handler,實際結果也會列印多條日誌記錄

import logging

logger = logging.getLogger()
print(logger)       #<RootLogger root (WARNING)>

logger1 = logging.getLogger()
print(logger1)     #<<RootLogger root (WARNING)>

#設定兩個處理器handler
console_handler = logging.StreamHandler()
console_handler1 = logging.StreamHandler()

#給兩個相同名稱的logger新增上處理器
logger.addHandler(console_handler)
logger1.addHandler(console_handler1)

#設定一下格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
console_handler1.setFormatter(formatter)

#輸出日誌記錄
logger1.warning("=============this is a warning=================")


輸出結果:

<RootLogger root (WARNING)>      
<RootLogger root (WARNING)>      #兩個日誌器名稱相同,則對應的有幾個handler就輸出幾條日誌記錄
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================

1.3. 通常建議使用__name__來命名日誌器,或者自定義名稱

import logging

logger = logging.getLogger(__name__)
print(logger)       #<Logger __main__ (WARNING)>

logger1 = logging.getLogger("DIY")
print(logger1)     #<Logger DIY (WARNING)>

#設定兩個處理器handler
console_handler = logging.StreamHandler()
console_handler1 = logging.StreamHandler()

#給兩個相同名稱的logger新增上處理器
logger.addHandler(console_handler)
logger1.addHandler(console_handler1)

#設定一下格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
console_handler1.setFormatter(formatter)

#輸出日誌記錄
logger1.warning("=============this is a warning=================")


輸出結果:

2021-08-11 21:43:45,628 - DIY - WARNING - =============this is a warning=================

2. 處理器Handler

處理器負責將日誌訊息傳送到不同目標,例如:控制檯,日誌檔案,電子郵件等目標

logging模組提供很多個型別的處理器,其中NullHandler、StreamHandler、FileHandler類在核心日誌包中定義,直接用,其它處理器在logging.handler中(還有另一個子模組logging.config,用於配置功能)

  • SteamHandler: 日誌記錄傳送到控制檯,stream:預設為None,日誌輸出到sys.stder;指定stream的話,日誌則輸出到指定stream
logging.StreamHandler(stream=None)
  • FileHandler: 日誌記錄傳送到磁碟檔案中
logging.FileHandler(filename='log.txt',mode='a',encoding=None,delay=False)

引數:

filename: 只填寫檔名,則預設新增檔案到當前工作目錄;填寫工作路徑+檔名稱,則新增到對應工作目錄

mode: 預設a模式,可自定義

encoding: 預設為None,可自定義

delay: 預設為False, 如果為True時,將檔案開啟延遲到第一次呼叫時進行emit()

  • NullHandler: 不做任何事情的處理器,防止sys.stderr在沒有日誌記錄配置的情況下將庫的記錄事件輸出
logging.NullHandler()
  • WatchedFileHandler : 該處理器在linux / unix 下使用,它監視檔案以檢視自上一次發出以來是否已更改。(如果檔案的裝置或索引節點已更改,則認為改檔案已更改),如果檔案已更改,則關閉舊檔案流,並開啟該檔案以獲取新的流,不適合在window下使用
import logging.handlers

logging.handlers.WatchedFileHandler(filename='log.txt',mode='a',encoding='UTF-8',delay=False)
  • RotatingFileHandler:日誌記錄到檔案中,當檔案到達指定大小時,開啟一個新的檔案接著記錄,並重命名並增加其後綴為(例如:原檔名.1,原檔名.2)

引數:

maxBytes: 日誌檔案大小,單位為位元組

backupcCount: 備份檔案數量

logging.handlers.RotatingFileHandler(filename='log.txt',mode='a',maxBytes=200,backupCount=1)

輸出:

  • TimeRotatingFileHandler: 日誌記錄到檔案中,支援按時間間隔來更新日誌

引數 :

when: 不同值對應不同時間型別,以字串填入,不區分大小寫

3.過濾器Filter

Filters可以由級別使用,輸出感興趣的日誌,過濾不感興趣的日誌

4.格式器Formatter

引數:

fmt: 日誌格式引數,預設為None,如果不特別指定fmt,則使用'%(message)s'格式

datafmt: 時間格式引數,預設為None,如果不特別指定datafmt,則使用formatTime()文件中描述的格式

style: 風格引數,預設為'%',也支援'$','{' 格式

logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt=None,style='%')

二、Logging的工作流程:

  1. 一個Logger可以包含多個Handler
  2. 每個Handler可以設定自己的Filter和Formatter

三、設定日誌級別

使用setLevel()方法設定日誌級別,注意:若沒有設定日誌級別,日誌器的日誌級別預設為WARNING

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

四、輸出日誌記錄

logging模組提供5個日誌級別的輸出方法

兩種方法呼叫,分別是logging直接呼叫,或者日誌器呼叫,我們常用的都是建立日誌器物件來呼叫

#logger1為日誌器
logger1.warning("=============this is a warning=================")
logger1.info("=================this is a info===================")
logger1.error("=================this is a error==================")
logger1.debug("=================this is a debug==================")

五、日誌記錄配置

logging模組提供一個配置方法,以字典為容器,設定日誌器,處理器,格式器等引數,使用logging.conf.dictConfig(配置字典)方法生成對應的元器件

import logging.handlers
import logging.config

config = {
    'version': 1,  # 必填項,值只能為1
    'disable_existing_loggers': True,  # 選填,預設為True,將以向後相容的方式啟用舊行為,此行為是禁用任何現有的非根日誌記錄器,除非它們或它們的祖先在日誌配置中顯式命名。如果指定為False,則在進行此呼叫時存在的記錄器將保持啟用狀態
    'incremental': False,  # 選填,預設為False,作用,為True時,logging完全忽略任何formatters和filters,僅處理handlers的level

    'formatters':  # 格式器配置專用key,在這裡配置formatter,可配置複數formatter
        {
            'myformatter1': {
                'class': 'logging.Formatter',  # 必填,格式器對應的類
                'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',  # fmt格式
                'datefmt': '%Y-%m-%d %H:%M:%S'  # 日期時間格式
            }
        },

    'handlers':  # 處理器配置專用key,在這裡配置handler,可配置複數handler
        {
            'console_handler': {
                'class': 'logging.StreamHandler',  # 必填,處理器對應的類
                'level': logging.DEBUG,  # 選填,處理器的日誌級別,可填字串'info',或者logging.INFO
                'formatter': 'myformatter1',  # 選填,這裡要填寫formatters字典中的鍵
            },
            'file_handler': {
                'class': 'logging.handlers.RotatingFileHandler',  # 必填,處理器對應的類
                'level': logging.INFO,  # 選填,處理器的日誌級別,可填字串'info',或者logging.INFO
                'formatter': 'myformatter1',  # 選填,這裡要填寫formatters字典中的鍵
                'filename': './mylog.log',  # filehandler特有引數,檔名
                'maxBytes': 1024*1024,  # 檔案大小
                'backupCount': 3,  # 備份數量
                'encoding': 'UTF-8',  # 編碼格式
            }
        },

    'loggers':  # 記錄器配置專用key,在這裡配置logger,可配置複數logger
        {
            'logger1': {
                'handlers': ['console_handler', 'file_handler'],  # 列表形式,元素填handlers字典中的handler
                'level': logging.DEBUG,  # 選填,記錄器的日誌級別,不填則預設Warning級別
                'propagate': False,  # 選填,為False時,禁止將日誌訊息傳遞給父級記錄器
            }
        },

    'root':  # 根記錄器專用key
        {
            'handlers': ['console_handler', 'file_handler'],  # 列表形式,元素填handlers字典中的handler
            'level': logging.DEBUG,  # 選填,記錄器的日誌級別,不填則預設Warning級別
        }
}
# 根據配置字典,配置對應元器件
logging.config.dictConfig(config)

if __name__ == '__main__':
    logger = logging.getLogger('logger1')  # 獲取配置中的logger物件
    # 輸出logger日誌記錄
    logger.debug("====================【debug】====================")
    logger.info("====================【info】====================")
    logger.warning("====================【warning】====================")
    logger.error("====================【error】====================")
    logger.critical("====================【critical】====================")

六、其它實用的方法

logging.basicConfig(**kwargs): 該方法可設定多項引數,來建立StreamHandler或者FileHandler,並新增到根記錄器中,從程式碼上看,更方便更簡潔

三十六般武藝,七十二般變化,修練出個人品牌併發出光芒