python之日誌模組
一、logging模組介紹
logging是Python中自帶的標準模組,是Python中用來操作日誌的模組。
1、控制檯輸出日誌
1 import logging 2 logging.basicConfig(level=logging.ERROR, # 列印的日誌級別 3 format= 4 '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' 5 # 日誌格式 6 ) 7 logging.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') 8 logging.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') 9 logging.warning('waring級別,一般用來列印警資訊') 10 logging.error('error級別,一般用來列印一些錯誤資訊') 11 logging.critical('critical級別,一般用來列印一些致命的錯誤資訊')
日誌級別 debug < info < warning < error < critical
設定了日誌級別之後,會列印該級別以及比該級別高的所有日誌,舉個例子,如果日誌級別是warning,那麼就會列印warning、error、critical,這三個級別的日誌,不會列印debug和info級別的,如果是debug,最低級別的日誌,那麼所有的日誌都會列印。
上面的只是在控制檯列印日誌,並沒有把日誌寫在檔案裡面,一般我們都會把日誌寫在日誌檔案裡面,也很簡單,只需要加個引數指定檔名就行了。
2、把日誌存入日誌檔案
要把日誌存入日誌檔案,需要加上filename引數(即日誌檔名)以及filemode引數(寫日誌模式w為覆蓋,a為追加),沒有加filename引數時,控制檯會輸出日誌資訊,加了filename引數後,控制檯不會再輸出日誌資訊。
1 import logging 2 # 沒有加filename引數時,控制檯有輸出日誌資訊,加了filename引數時,控制檯不會再輸出日誌資訊 3 logging.basicConfig(level=logging.ERROR, # 列印的日誌級別 4 filename='my.log', # 日誌檔名 5 filemode='a', # w清空,a追加寫入,不會清空 6 format= 7 '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' 8 # 日誌格式 9 ) 10 logging.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') 11 logging.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') 12 logging.warning('waring級別,一般用來列印警資訊') 13 logging.error('error級別,一般用來列印一些錯誤資訊') 14 logging.critical('critical級別,一般用來列印一些致命的錯誤資訊')
執行後發現能夠生成日誌檔案,但日誌檔案裡面的中文顯示為亂碼,且控制檯不再列印日誌資訊。
1 # 可以指定日誌的輸出格式format,這個引數可以輸出很多有用的資訊,如下面的幾種格式: 2 # % (levelno)s: # 列印日誌級別的數值 3 # % (levelname)s: # 列印日誌級別名稱 4 # % (pathname)s: # 列印當前執行程式的路徑,其實就是sys.argv[0] 5 # % (filename)s: # 列印當前執行程式名 6 # % (funcName)s: # 列印日誌的當前函式 7 # % (lineno)d: # 列印日誌的當前行號 8 # % (asctime)s: # 列印日誌的時間 9 # % (thread)d: # 列印執行緒ID 10 # % (threadName)s: # 列印執行緒名稱 11 # % (process)d: # 列印程序ID 12 # % (message)s: # 列印日誌資訊 13 # 常用格式: 14 # format = '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' 15 # 這個格式可以輸出日誌的列印時間,是哪個檔案第幾行輸出的,輸出的日誌級別是什麼,以及輸入的日誌內容。
3、同時實現控制檯輸出日誌、寫入日誌檔案
logging模組中主要有4個類,分別負責不同的工作:
(1)Logger記錄器:暴露了應用程式程式碼能直接使用的介面。簡單點說就是一個建立一個辦公室,讓人在裡頭工作
(2)Handler 處理器:將(記錄器產生的)日誌記錄傳送至合適的目的地。這個簡單點說就是辦事的人,你可以指定是讓在控制輸出日誌,還是在檔案裡面打 印日誌,常用的有4種:
後面兩種需要匯入handlers,from logging import handlers
a、StreamHandler 控制檯輸出
b、FileHandler 檔案輸出
c、TimedRotatingFileHandler 按照時間自動分割日誌檔案
d、RotatingFileHandler 按照大小自動分割日誌檔案,一旦達到指定的大小重新生成檔案
(3)Filter過濾器:提供了更好的粒度控制,它可以決定輸出哪些日誌記錄。(不常用)
(4)Formatter格式化器:指明瞭最終輸出中日誌記錄的佈局。指定輸出日誌的格式
具體怎麼實現呢?得有個辦公室,裡面放兩個人,一個負責往控制檯輸出日誌,一個負責將日誌寫入日誌檔案。
1 import logging 2 from logging import handlers 3 logger = logging.getLogger() # 先例項化一個logger物件,先建立一個辦公室 4 logger.setLevel(logging.DEBUG) # 設定日誌的總級別 5 # 建立一個檔案處理器,也就是把日誌寫到檔案裡(fh的功能包含在th當中,所以fh可以刪除不寫) 6 fh = logging.FileHandler(filename='my.log',mode='a',encoding='utf-8') 7 fh.setLevel(logging.ERROR) # 設定檔案輸出的日誌級別 8 # 建立一個控制檯輸出的處理器 9 sh = logging.StreamHandler() 10 sh.setLevel(logging.INFO) # 設定控制檯輸出的日誌級別 11 # 建立一個指定間隔時間自動生成日誌檔案的處理器,這個相對於fh更好用 12 th = handlers.TimedRotatingFileHandler(filename='a.log',when='S',interval=1,backupCount=3,encoding='utf-8') 13 # interval是時間間隔,backupCount是備份檔案的個數,如果超過這個超過這個個數,就會自動刪除 14 # when是間隔的時間單位,單位有以下幾種: 15 # S 秒 16 # M 分 17 # H 小時 18 # D 天 19 # W 星期(interval==0時代表星期一) 20 # midnight 每天凌晨 21 th.setLevel(logging.INFO) # 設定自動生成日誌檔案的日誌級別 22 # 以上三個日誌級別都可以單獨設定,他們和總日誌級別logger的級別區別是如果logger設定的級別比裡面的handler級別設定的高,那麼就以logger的級別為準 23 # 指定日誌格式 24 formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') 25 fh.setFormatter(formater) # 設定檔案處理器輸出的日誌格式 26 sh.setFormatter(formater) # 設定控制檯輸出的日誌格式 27 th.setFormatter(formater) # 設定檔案裡面寫入的日誌格式 28 # 把三個handler加入容器裡頭,相當於把工作人員培訓完了,你們可以上班了 29 logger.addHandler(fh) # 把檔案處理器放到辦公室 30 logger.addHandler(sh) # 把控制檯輸出的處理器放到辦公室 31 logger.addHandler(th) # 把第二個檔案處理器放到辦公室 32 33 # 執行 34 logger.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') 35 logger.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') 36 logger.warning('waring級別,一般用來列印警資訊') 37 logger.error('error級別,一般用來列印一些錯誤資訊') 38 logger.critical('critical級別,一般用來列印一些致命的錯誤資訊')
二、封裝寫日誌的類
1 # 封裝寫日誌的類 2 import logging 3 from logging import handlers 4 class MyLogger(): 5 def __init__(self,file_name,level='info',backCount=5,when='D'): 6 logger = logging.getLogger() # 先例項化一個logger物件,先建立一個辦公室 7 logger.setLevel(self.get_level(level)) # 設定日誌級別 8 ch = logging.StreamHandler() # 負責往控制檯輸出日誌 9 bh = handlers.TimedRotatingFileHandler(filename=file_name,when=when,interval=1,backupCount=backCount,encoding='utf-8') 10 formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') 11 ch.setFormatter(formater) # 設定控制檯輸出的日誌格式 12 bh.setFormatter(formater) # 設定檔案裡面寫入的日誌格式 13 logger.addHandler(ch) # 把把用於控制檯輸出的例項放入logger 14 logger.addHandler(bh) # 把用於寫檔案的例項放入logger 15 self.logger = logger 16 def get_level(self,str): # 該函式把輸入的字串轉換成日誌級別(debug轉換成logging.DEBUG) 17 level = { 18 'debug':logging.DEBUG, 19 'info':logging.INFO, 20 'waring':logging.WARNING, 21 'error':logging.ERROR, 22 'critical':logging.CRITICAL 23 } 24 str = str.lower() 25 return level.get(str) 26 27 mylog = MyLogger('my.log','debug') 28 mylog.logger.warning('waring級別日誌')
三、第三方模組nnlog
直接pip install nnlog即可,使用例子如下面程式碼:
1 import nnlog 2 # 例項化 3 log = nnlog.Logger(file_name='my.log', level='debug', when='D', backCount=5, interval=1) 4 # file_name是日誌檔名 5 # level是日誌級別,如果不傳的話預設是debug級別 6 # when是日誌檔案多久生成一個,預設是按天,S 秒、M 分、 H 小時、 D 天、 W 每星期 7 # backCount是備份幾個日誌檔案,預設保留5天的 8 # interval是間隔多久生成一個日誌檔案,預設是1天 9 log.debug('預設日誌級別是debug') 10 log.info('info級別') 11 log.warning('waring級別') 12 log.error('error級別')