1. 程式人生 > >python logging模組講解

python logging模組講解


日誌欄位資訊與日誌格式

一條日誌資訊對應的是一個事件的發生,而一個事件通常需要包括以下幾個內容:

  • 事件發生時間

  • 事件發生位置

  • 事件的嚴重程度--日誌級別

  • 事件內容

上面這些都是一條日誌記錄中可能包含的欄位資訊,當然還可以包括一些其他資訊,如程序ID、程序名稱、執行緒ID、執行緒名稱等。日誌格式就是用來定義一條日誌記錄中包含那些欄位的,且日誌格式通常都是可以自定義的。
 

日誌功能的實現

幾乎所有開發語言都會內建日誌相關功能,或者會有比較優秀的第三方庫來提供日誌操作功能,比如:log4j,log4php等。它們功能強大、使用簡單。Python自身也提供了一個用於記錄日誌的標準庫模組--logging。

logging模組是Python內建的標準模組,主要用於輸出執行日誌,可以設定輸出日誌的等級、日誌儲存路徑、日誌檔案回滾等;相比print,具備如下優點:

  • 可以通過設定不同的日誌等級,在release版本中只輸出重要資訊,而不必顯示大量的除錯資訊;

  • print將所有資訊都輸出到標準輸出中,嚴重影響開發者從標準輸出中檢視其它資料;logging則可以由開發者決定將資訊輸出到什麼地方,以及怎麼輸出。
     

    1、 logging模組的日誌級別

    logging模組預設定義了以下幾個日誌等級,它允許開發人員自定義其他日誌級別,但是這是不被推薦的,尤其是在開發供別人使用的庫時,因為這會導致日誌級別的混亂。

    日誌等級(level) 描述
    DEBUG 最詳細的日誌資訊,典型應用場景是 問題診斷
    INFO 資訊詳細程度僅次於DEBUG,通常只記錄關鍵節點資訊,用於確認一切都是按照我們預期的那樣進行工作
    WARNING 當某些不期望的事情發生時記錄的資訊(如,磁碟可用空間較低),但是此時應用程式還是正常執行的
    ERROR 由於一個更嚴重的問題導致某些功能不能正常執行時記錄的資訊
    CRITICAL 當發生嚴重錯誤,導致應用程式不能繼續執行時記錄的資訊

應用上線或部署生產環境時,應該使用WARNING或ERROR或CRITICAL級別的日誌來降低機器的I/O壓力和提高獲取錯誤日誌資訊的效率。日誌級別的指定通常都是在應用程式的配置檔案中進行指定的。

  • 上面列表中的日誌等級是從上到下依次升高的,即:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日誌的資訊量是依次減少的;

  • 當為某個應用程式指定一個日誌級別後,應用程式會記錄所有日誌級別大於或等於指定日誌級別的日誌資訊,而不是僅僅記錄指定級別的日誌資訊,nginx、php等應用程式以及這裡的python的logging模組都是這樣的。同樣,logging模組也可以指定日誌記錄器的日誌級別,只有級別大於或等於該指定日誌級別的日誌記錄才會被輸出,小於該等級的日誌記錄將會被丟棄。

  • logging模組定義的模組級別的常用函式

    函式 說明
    logging.debug(msg, *args, **kwargs) 建立一條嚴重級別為DEBUG的日誌記錄
    logging.info(msg, *args, **kwargs) 建立一條嚴重級別為INFO的日誌記錄
    logging.warning(msg, *args, **kwargs) 建立一條嚴重級別為WARNING的日誌記錄
    logging.error(msg, *args, **kwargs) 建立一條嚴重級別為ERROR的日誌記錄
    logging.critical(msg, *args, **kwargs) 建立一條嚴重級別為CRITICAL的日誌記錄
    logging.log(level, *args, **kwargs) 建立一條嚴重級別為level的日誌記錄
    logging.basicConfig(**kwargs) 對root logger進行一次性配置

    其中logging.basicConfig(**kwargs)函式用於指定“要記錄的日誌級別”、“日誌格式”、“日誌輸出位置”、“日誌檔案的開啟模式”等資訊,其他幾個都是用於記錄各個級別日誌的函式。
    預設情況下Python的logging模組將日誌列印到了標準輸出中,且只顯示了大於等於WARNING級別的日誌,這說明預設的日誌級別設定為WARNING(日誌級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG)

    #首先設定日誌的名稱,並指定日誌的級別
    #指定記錄日誌的路徑,並設定記錄日誌的級別
    #指定輸出在cmd視窗的物件,並設定顯示級別
    #設定記錄日誌和顯示視窗日誌的格式
    #將記錄日誌和顯示視窗日誌的格式分別加入相應的物件
    #開始列印日誌

    #視窗顯示日誌與顏色的混用,配合ctypes使用,在linux中,不存在windll模組,c相關的不清楚,歡迎留言解決

    import logging,ctypes
    class Logger():
        def __init__(self,path,clevel=logging.DEBUG,flevel=logging.DEBUG):
            self.logger=logging.getLogger(path)
            self.logger.setLevel(logging.DEBUG)
            fmt=logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s','%Y-%m-%d %H:%M:%S')
            #設定cmd日誌
            sh=logging.StreamHandler()
            sh.setFormatter(fmt)
            sh.setLevel(clevel)
            #設定檔案日誌
            fh=logging.FileHandler(path)
            fh.setFormatter(fmt)
            fh.setLevel(flevel)
            #將設定好的加入logger物件
            self.logger.addHandler(sh)
            self.logger.addHandler(fh)
            #設定視窗顯示的錯誤級別的顏色
            self.show_white=0x0007
            self.show_blue=0x01
            self.show_green=0x02
            self.show_red=0x04
            self.show_yellow=self.show_red|self.show_green
            self.std_output_handles=-11
            self.std_output_handle=ctypes.windll.kernel32.GetStdHandle(self.std_output_handles)
        def debug(self,message):
            self.logger.debug(message)
        def info(self,message):
            self.logger.info(message)
        def war(self,message):
            color=self.show_yellow
            self.set_color(color)
            self.logger.warning(message)
        def error(self,message):
            color=self.show_red
            self.set_color(color)
            self.logger.error(message)
        def cri(self,message):
            self.logger.critical(message)
        def set_color(self,color):
            handle=self.std_output_handle
            bool=ctypes.windll.kernel32.SetConsoleTextAttribute(handle,color)
            return bool
    if __name__=='__main__':
        logyyx=Logger('/root/python_test/logs/alllog.log',logging.ERROR,logging.DEBUG)
        logyyx.debug('一個debug資訊')
        logyyx.info('一個info資訊')
        logyyx.war('一個warning資訊')
        logyyx.error('一個error資訊')
        logyyx.cri('一個致命的critical資訊')