1. 程式人生 > >Python–logging模組知多少

Python–logging模組知多少

  我們在寫程式的時候經常會打一些日誌來幫助我們查詢問題,這次學習一下logging模組,在python裡面如何操作日誌。
介紹一下logging模組,logging模組就是python裡面用來操作日誌的模組,logging模組中主要有4個類,分別負責不同的工作:

Logger 記錄器,暴露了應用程式程式碼能直接使用的介面;簡單點說就是一個建立一個辦公室,讓人在裡頭工作 

Handler 處理器,將(記錄器產生的)日誌記錄傳送至合適的目的地;這個簡單點說就是辦事的人,你可以指定是讓在控制輸出日誌,還是在檔案裡面列印日誌,常用的有4種: 

                StreamHandler 控制檯輸出 

                FileHandler 檔案輸出

                下面兩種需要匯入

                        handlers
                        from logging import handlers 

                        TimedRotatingFileHandler 按照時間自動分割日誌檔案 

                        RotatingFileHandler 按照大小自動分割日誌檔案,一旦達到指定的大小重新生成檔案 

                Filter
過濾器,提供了更好的粒度控制,它可以決定輸出哪些日誌記錄。(不常用) 

                Formatter
格式化器,指明瞭最終輸出中日誌記錄的佈局。指定輸出日誌的格式

 

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 import logging from logging import handlers #只在控制檯列印日誌 logging.basicConfig(level=logging.ERROR,#控制檯列印的日誌級別                     format=                     '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'                     #日誌格式                     ) logging.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') logging.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') logging.warning('waring級別,一般用來列印警資訊') logging.error('error級別,一般用來列印一些錯誤資訊') logging.critical('critical級別,一般用來列印一些致命的錯誤資訊')

日誌級別 debug < info < warning < error < critical
設 置了日誌級別之後,會列印該級別以及比該級別高的所有日誌,舉個例子,如果日誌級別是warning,那麼就會列印warning、error、 critical,這三個級別的日誌,不會列印debug和info級別的,如果是debug,最低級別的日誌,那麼所有的日誌都會列印。
上面的只是在控制檯列印日誌,並沒有把日誌寫在檔案裡面,一般我們都會把日誌寫在日誌檔案裡面,也很簡單,只需要加個引數指定檔名就行了。

 

 

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 logging.basicConfig(level=logging.ERROR,#控制檯列印的日誌級別                     filename='log.txt',#檔名                     filemode='a',#模式,有w和a,w就是寫模式,每次都會重新寫日誌,覆蓋之前的日誌                     #a是追加模式,預設如果不寫的話,就是追加模式                     format=                     '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'                     #日誌格式                     ) logging.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') logging.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') logging.warning('waring級別,一般用來列印警資訊') logging.error('error級別,一般用來列印一些錯誤資訊') logging.critical('critical級別,一般用來列印一些致命的錯誤資訊')

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 可以指定日誌的輸出格式 format,這個引數可以輸出很多有用的資訊,如下面的幾種格式: %(levelno)s: 列印日誌級別的數值     %(levelname)s: 列印日誌級別名稱     %(pathname)s: 列印當前執行程式的路徑,其實就是sys.argv[0]     %(filename)s: 列印當前執行程式名     %(funcName)s: 列印日誌的當前函式     %(lineno)d: 列印日誌的當前行號     %(asctime)s: 列印日誌的時間     %(thread)d: 列印執行緒ID     %(threadName)s: 列印執行緒名稱     %(process)d: 列印程序ID     %(message)s: 列印日誌資訊     我在工作中給的常用格式在前面已經看到了。就是: format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' 這個格式可以輸出日誌的列印時間,是哪個檔案第幾行輸出的,輸出的日誌級別是什麼,以及輸入的日誌內容。

加上檔名之後就會發現控制檯不會輸出日誌了,日誌檔案也產生了,那麼如何既在控制檯輸出日誌,也在檔案中寫入呢?

 

 

怎麼實現呢,就得有個辦公室,裡面塞倆人,一個給負責往控制檯輸出日誌,一個負責寫檔案,你把他倆往辦公室一塞,他倆就能幹活了。

 

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import logging from logging import handlers logger = logging.getLogger('my_log') #先建立一個logger物件,相當於這個辦公室,也就是上面說的Logger logger.setLevel(logging.INFO)#設定日誌的總級別 fh = logging.FileHandler('test.log',mode='a',encoding='utf-8')#建立一個檔案處理器,也就是把日誌寫到檔案裡頭 fh.setLevel(logging.INFO)#設定檔案輸出的級別 sh = logging.StreamHandler()#建立一個控制檯輸出的處理器,這兩個就是上面說的Handler sh.setLevel(logging.INFO) #設定控制檯輸出的日誌級別,這兩個級別都可以單獨設定,他們倆和logger的級別區別是如果logger設定的級別比裡面的handler級別設定的高,那麼就以logger的級別為準 th = handlers.TimedRotatingFileHandler('time',when='S',interval=1,backupCount=2) #指定間隔時間自動生成檔案的處理器 #interval是時間間隔,backupCount是備份檔案的個數,如果超過這個超過這個個數,就會自動刪除,when是間隔的時間單位,單位有以下幾種:             # S 秒             # M 分             # H 小時、             # D 天、             # W 每星期(interval==0時代表星期一)             # midnight 每天凌晨 th.setLevel(logging.INFO) formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') #指定日誌格式,上面咱們寫了常用的格式,直接指定了就行了,這也就是咱們上面說的Formatter sh.setFormatter(formater) fh.setFormatter(formater) th.setFormatter(formater) #設定兩個處理器的日誌格式   logger.addHandler(sh) logger.addHandler(fh) logger.addHandler(th) #把兩個handler加入容器裡頭,相當於把工作人員培訓完了,你們可以上班了 logger.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊') logger.info('info級別,正常輸出資訊,一般用來列印一些正常的操作') logger.warning('waring級別,一般用來列印警資訊') logger.error('error級別,一般用來列印一些錯誤資訊') logger.critical('critical級別,一般用來列印一些致命的錯誤資訊')

這樣logger這個日誌辦公室已經搞好了,咱們就可以直接用了,執行完發現檔案也產生了,控制檯也有日誌。如果不設定日誌級別的話,預設級別是waring。
下面我們自己封裝一個類來使用logging模組,方便使用,預設加一些配置

 

 

 

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import logging from logging import handlers class Logger(object):     level_relations = {         'debug':logging.DEBUG,         'info':logging.INFO,         'warning':logging.WARN,         'error':logging.ERROR,         'crit':logging.CRITICAL     }#日誌級別關係對映     def __init__(self,fp,level='debug',when='midnight',interval=1,backCount=5,encoding='utf-8'):         '''           :param fp:日誌檔案路徑         :param level: 日誌級別 預設是debug         :param when: 分割日誌的單位 S 秒、M 分、 H 小時、 D 天、 W 每星期(interval==0時代表星期一)、midnight 每天凌晨         :param interval: 時間間隔 預設每天凌晨         :param backCount: 備份檔案個數 預設5個         :param encoding: 日誌檔案編碼         '''         self.level = self.level_relations.get(level)         self.logger = logging.getLogger(fp)         self.logger.setLevel(self.level)         fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')         sh = logging.StreamHandler()         sh.setFormatter(fmt)         sh.setLevel(self.level)         th = handlers.TimedRotatingFileHandler(fp,when=when,interval=interval,backupCount=backCount,encoding=encoding)         th.setFormatter(fmt)         th.setLevel(self.level)         self.logger.addHandler(th)         self.logger.addHandler(sh)     def debug(self,msg):         self.logger.debug(msg)     def info(self,msg):         self.logger.info