logging模塊的特色及用法

logging模塊的特色及用法

1、概述

  不少程序都有記錄日誌的需求,而且日誌中包含的信息即有正常的程序訪問日誌,還可能有錯誤、警告等信息輸出,python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌,logging的日誌能夠分爲 debug()info()warning()error() and critical() 5個級別,其中他們級別大小關係python

debug() <info() <warning() <error() <critical()  級別越低打印的日記等級就越多網絡

下面咱們看一下他是怎樣的用法。app

2、用法

一、最簡單的用法函數

複製代碼
 1 import logging
 2  
 3 logging.debug("logging debug")
 4 logging.info("logging info")
 5 logging.warning("user [qianduoduo] attempted wrong password more than 3 times")
 6 logging.error("logging error")
 7 logging.critical("logging critical")
 8 
 9 #輸出
10 WARNING:root:user [qianduoduo] attempted wrong password more than 3 times
11 ERROR:root:logging error
12 CRITICAL:root:logging critical  #root  就是默認的用戶名
複製代碼

 

重點:爲何上面debug和info沒有輸出,那是由於一個模塊默認的日誌級別是warning,比他級別低的就不會輸出工具

二、日誌級別ui

看一下這幾個日誌級別分別表明什麼意思,如表:this

Level When it’s used
DEBUG 詳細的信息,一般只有在診斷問題時才感興趣。
INFO 確認事情按預期工做。
WARNING 代表發生了意外的事情,或預示在不久的未來會出現一些問題(例如「磁盤空間低」)。該軟件仍按預期運行。
ERROR 因爲一個更嚴重的問題,軟件沒法執行某些功能。
CRITICAL 一個嚴重的錯誤,代表程序自己可能沒法繼續運行。

 

三、將日記寫入文件spa

複製代碼
 1 import logging
 2 
 3 logging.basicConfig(filename='duoduo.log',level=logging.INFO)
 4 logging.debug('This message should go to the log file')
 5 logging.info('So should this')
 6 logging.warning('And this, too')
 7 
 8 #‘duoduo.log’文件輸出
 9 INFO:root:So should this
10 WARNING:root:And this, too   #這日記的級別設置在info,因此比他更低的debug不顯示
複製代碼

重點: 若是咱們想顯示全部級別的日記就要把日記的等級設置爲debug,就在level=logging.DEBUG,設置是級別的名稱要大寫線程

 

四、加入日期格式debug

  感受上面的日誌格式忘記加上時間啦,日誌不知道時間怎麼行呢,下面就來加上

複製代碼
 1 import logging
 2 
 3 logging.basicConfig(filename='duoduo.log',
 4                     level=logging.DEBUG,
 5                     format='%(asctime)s %(message)s',#asctime字符串形式的當前時間,message用戶輸出的消息
 6                     datefmt='%Y-%m-%d %I:%M:%S %p ')
 7 logging.debug("logging debug")
 8 logging.info("logging info")
 9 logging.warning("user [qianduoduo] attempted wrong password more than 3 times")
10 logging.error("logging error")
11 logging.critical("logging critical")
12 
13 #輸出到文件‘duoduo.log’
14 2018-01-27 07:33:30 PM  logging debug
15 2018-01-27 07:33:30 PM  logging info
16 2018-01-27 07:33:30 PM  user [qianduoduo] attempted wrong password more than 3 times
17 2018-01-27 07:33:30 PM  logging error
18 2018-01-27 07:33:30 PM  logging critical
複製代碼

 

五、 format的日誌格式

 

Logger的名字

%(levelno)s

數字形式的日誌級別

%(levelname)s

文本形式的日誌級別

%(pathname)s

調用日誌輸出函數的模塊的完整路徑名,可能沒有

%(filename)s

調用日誌輸出函數的模塊的文件名

%(module)s

調用日誌輸出函數的模塊名

%(funcName)s

調用日誌輸出函數的函數名

%(lineno)d

調用日誌輸出函數的語句所在的代碼行

%(created)f

當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d

輸出日誌信息時的,自Logger建立以 來的毫秒數

%(asctime)s

字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒

%(thread)d

線程ID。可能沒有

%(threadName)s

線程名。可能沒有

%(process)d

進程ID。可能沒有

%(message)s

用戶輸出的消息

 

 六、log的"終極奧義"用法

若是想同時把log打印在屏幕和文件日誌裏,就須要瞭解一點複雜的知識 了

Python 使用logging模塊記錄日誌涉及四個主要類,使用官方文檔中的歸納最爲合適:

一、logger提供了應用程序能夠直接使用的接口;

二、handler將(logger建立的)日誌記錄發送到合適的目的輸出;

三、filter提供了細度設備來決定輸出哪條日誌記錄;

四、formatter決定日誌記錄的最終輸出格式。

1)、logger

①每一個程序在輸出信息以前都須要得到一個logger。logger一般對應了程序的模塊名,好比聊天工具的圖形界面模塊能夠這樣得到它的logger:

1
logger  =  logging.getLogger( "chat.gui" )

核心模塊能夠這樣寫:(本身想叫什麼名稱就叫什麼名稱)

1
logger  =  logging.getLogger( "chat.kernel" )

②logger.setLevel(lel)

說明:指定最低的日誌級別,低於lel的級別將被忽略(debug是最低的內置級別,critical爲最高)

1
logger.setLevel(logging.DEBUG)   #設置級別爲debug級別

③Logger.addFilter(filt)、Logger.removeFilter(filt)

說明:添加或刪除指定的filter

④logger.addHandler(hdlr)、logger.removeHandler(hdlr)

說明:增長或刪除指定的handler

1
2
3
logger.addHandler(ch) #添加handler
 
logger.removeHandler(ch)  #刪除handler

⑤Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()

說明:能夠設置的日誌級別

1
2
3
4
5
logger.debug( 'debug message' )
logger.info( 'info message' )
logger.warn( 'warn message' )
logger.error( 'error message' )
logger.critical( 'critical message' )

⑥獲取handler個數

1
2
3
4
5
handler_len  =  len (logger.handlers)
print (handler_len)
 
#輸出
1

2)、handler

  handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Logger能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler

①Handler.setLevel(lel)

說明:指定被處理的信息級別,低於lel級別的信息將被忽略。

1
2
ch  =  logging.StreamHandler()
ch.setLevel(logging.DEBUG)

②Handler.setFormatter()

說明:給這個handler選擇一個格式

1
2
3
ch_formatter  =  logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" #生成格式,具體須要什麼格式看需求
 
ch.setFormatter(ch_formatter)  #設置格式

③Handler.addFilter(filt)、Handler.removeFilter(filt)

說明:新增或刪除一個filter對象

 

3、handler"終極奧義"詳解

一、logging.StreamHandler

說明:使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息,也就是屏幕輸出。

它的構造函數是:StreamHandler([strm]),其中strm參數是一個文件對象,默認是sys.stderr。具體用法看下面代碼:

複製代碼
 1 import logging
 2  
 3 logger = logging.getLogger("TEST-LOG")     
 4 logger.setLevel(logging.DEBUG)
 5  
 6 ch = logging.StreamHandler() #建立一個StreamHandler對象
 7 ch.setLevel(logging.DEBUG) #設置輸出StreamHandler日誌級別
 8  
 9 ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")   #格式
10 ch.setFormatter(ch_formatter)     #傳入格式參數
11 logger.addHandler(ch)       #增長handler
12 
13 logger.debug('debug message')
14 logger.info('info message')
15 logger.warn('warn message')
16 logger.error('error message')
17 logger.critical('critical message')
18 
19 輸出
20 2018-01-28 21:15:02,111 - TEST-LOG - DEBUG - debug message
21 2018-01-28 21:15:02,112 - TEST-LOG - INFO - info message
22 2018-01-28 21:15:02,112 - TEST-LOG - WARNING - warn message
23 2018-01-28 21:15:02,112 - TEST-LOG - ERROR - error message
24 2018-01-28 21:15:02,112 - TEST-LOG - CRITICAL - critical message
複製代碼

二、logging.FileHandler

說明:和StreamHandler相似,用於向一個文件輸出日誌信息,不過FileHandler會幫你打開這個文件。

它的構造函數是:FileHandler(filename[,mode])。filename是文件名,必須指定一個文件名。mode是文件的打開方式。參見Python內置函數open()的用法。默認是’a',即添加到文件末尾。用法看下面代碼:

複製代碼
 1 import logging
 2  
 3 #create logging
 4 logger = logging.getLogger("TEST-LOG")
 5 logger.setLevel(logging.DEBUG)
 6  
 7 fh = logging.FileHandler("debug.log",encoding="utf-8") #日誌輸出到debug.log文件中
 8 fh.setLevel(logging.INFO) #設置FileHandler日誌級別
 9  
10 fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
11  
12 fh.setFormatter(fh_formatter)
13  
14 logger.addHandler(fh)
15  
16 
17 logger.info('info message')
18 logger.warning('warning message')
19 logger.error('error message')
20 logger.critical('critical message')
21 
22 文件debug.log裏的輸出:
23 2018-01-28 21:19:45,221 logging文件輸出:INFO info message
24 2018-01-28 21:19:45,221 logging文件輸出:WARNING warning message
25 2018-01-28 21:19:45,221 logging文件輸出:ERROR error message
26 2018-01-28 21:19:45,221 logging文件輸出:CRITICAL critical message
複製代碼

三、logging.handlers.RotatingFileHandler

說明:這個Handler相似於上面的FileHandler,可是它能夠管理文件大小。當文件達到必定大小以後,它會自動將當前日誌文件更名,而後建立 一個新的同名日誌文件繼續輸出。好比日誌文件是chat.log。當chat.log達到指定的大小以後,RotatingFileHandler自動把 文件更名爲chat.log.1。不過,若是chat.log.1已經存在,會先把chat.log.1重命名爲chat.log.2。。。最後從新建立 chat.log,繼續輸出日誌信息。

它的構造函數是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]),其中filename和mode兩個參數和FileHandler同樣。

maxBytes用於指定日誌文件的最大文件大小。若是maxBytes爲0,意味着日誌文件能夠無限大,這時上面描述的重命名過程就不會發生。

backupCount用於指定保留的備份文件的個數。好比,若是指定爲2,當上面描述的重命名過程發生時,原有的chat.log.2並不會被改名,而是被刪除。

 用法看下面代碼:

複製代碼
 1 import logging
 2 from logging import handlers  #須要導入handlers
 3  
 4 logger = logging.getLogger(__name__)
 5 log_file = "timelog.log"
 6  
 7 #按文件大小來分割,10個字節maxBytes,保留個數是3個
 8 fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3,encoding="utf-8")
 9 formatter = logging.Formatter('%(asctime)s %(module)s: %(message)s')
10 fh.setFormatter(formatter)
11 logger.addHandler(fh)
12  
13 logger.warning("test11")
14 logger.warning("test12")
15 logger.warning("test13")
16 logger.warning("test14")
17 logger.warning("test15")
18 文件的結果就是
19 timelog.log     2018-01-28 21:31:38,513 logging文件個數保留: test15
20 timelog.log1   2018-01-28 21:31:38,500 logging文件個數保留: test14
21 timelog.log2    2018-01-28 21:31:38,487 logging文件個數保留: test13
22 timelog.log3    2018-01-28 21:31:38,471 logging文件個數保留: test12
複製代碼

四、logging.handlers.TimedRotatingFileHandler

說明:這個Handler和RotatingFileHandler相似,不過,它沒有經過判斷文件大小來決定什麼時候從新建立日誌文件,而是間隔必定時間就 自動建立新的日誌文件。重命名的過程與RotatingFileHandler相似,不過新的文件不是附加數字,而是當前時間。

它的構造函數是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]),其中filename參數和backupCount參數和RotatingFileHandler具備相同的意義。

interval是時間間隔。when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有如下取值:①S:秒②M:分③H:小時④D:天⑤W :每星期(interval==0時表明星期一)⑥midnight:天天凌晨

 

複製代碼
 1 import logging
 2 from logging import handlers
 3 import time
 4  
 5 logger = logging.getLogger(「duoduo-LOG」)
 6 log_file = "timelog.log"
 7 #按時間來分割文件,按5秒一次分割,保留日誌個數是3個
 8 fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3,encoding="utf-8") 
 9 formatter = logging.Formatter('%(asctime)s %(module)s: %(message)s')
10 fh.setFormatter(formatter)
11 logger.addHandler(fh)
12  
13 logger.warning("test11")
14 time.sleep(2)
15 logger.warning("test12")
16 time.sleep(2)
17 logger.warning("test13")
18 
19 time.sleep(2)
20 logger.warning("test14")
21 logger.warning("test15")
22 
23 #文件輸出
24 #這裏就區分了兩個,前面11,12,13屬於一個文件的內容,後面14,15一個文件的內容,可是後面讀秒少因此先建立的文件是後面的14,15
複製代碼

五、控制檯和文件日誌共同輸出

須要什麼樣的輸出,只須要添加相應的handler就ok了。

邏輯圖:

代碼以下:

複製代碼
 1 import logging
 2  
 3 #create logging
 4 logger = logging.getLogger("TEST-LOG")
 5 logger.setLevel(logging.DEBUG)
 6  
 7 #屏幕handler
 8 ch = logging.StreamHandler()
 9 ch.setLevel(logging.DEBUG)
10  
11 #文件handler
12 fh = logging.FileHandler("debug.log",encoding="utf-8")
13 fh.setLevel(logging.INFO)
14 #分別建立輸出日誌格式
15 ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
16 fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
17 #設置handler的輸出格式
18 ch.setFormatter(ch_formatter)
19 fh.setFormatter(fh_formatter)
20 #添加handler
21 logger.addHandler(ch)
22 logger.addHandler(fh)
23  
24 # 'application' code
25 logger.debug('debug message')
26 logger.info('info message')
27 logger.warn('warn message')
28 logger.error('error message')
29 logger.critical('critical message')
相關文章
相關標籤/搜索