1. 程式人生 > 其它 >python之日誌模組

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級別')