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資訊')