Python logging模組

來源:互聯網
上載者:User

標籤:篩選   情況   bsp   逗號   .net   沒有   pytho   開始   src   

一 (簡單應用)

import logging  logging.debug(‘debug message‘)  logging.info(‘info message‘)  logging.warning(‘warning message‘)  logging.error(‘error message‘)  logging.critical(‘critical message‘)  

輸出:

WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

可見,預設情況下Python的logging模組將日誌列印到了標準輸出中,且只顯示了大於等於WARNING層級的日誌,這說明預設的記錄層級設定為WARNING(記錄層級等級CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),預設的日誌格式為記錄層級:Logger名稱:使用者輸出訊息。

 

二  靈活配置記錄層級,日誌格式,輸出位置

import logging  logging.basicConfig(level=logging.DEBUG,                      format=‘%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s‘,                      datefmt=‘%a, %d %b %Y %H:%M:%S‘,                      filename=‘/tmp/test.log‘,                      filemode=‘w‘)    logging.debug(‘debug message‘)  logging.info(‘info message‘)  logging.warning(‘warning message‘)  logging.error(‘error message‘)  logging.critical(‘critical message‘)

查看輸出:
cat /tmp/test.log 
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message

可見在logging.basicConfig()函數中可通過具體參數來更改logging模組預設行為,可用參數有
filename:用指定的檔案名稱建立FiledHandler(後邊會具體講解handler的概念),這樣日誌會被儲存在指定的檔案中。
filemode:檔案開啟檔案,在指定了filename時使用這個參數,預設值為“a”還可指定為“w”。
format:指定handler使用的日誌顯示格式。 
datefmt:指定日期時間格式。 
level:設定rootlogger(後邊會講解具體概念)的記錄層級 
stream:用指定的stream建立StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者檔案(f=open(‘test.log‘,‘w‘)),預設為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。

format參數中可能用到的格式化串:
%(name)s 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使用者輸出的訊息

 

三  logger對象

    上述幾個例子中我們瞭解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分別用以記錄不同層級的日誌資訊),logging.basicConfig()(用預設日誌格式(Formatter)為日誌系統建立一個預設的流處理器(StreamHandler),設定基礎配置(如記錄層級等)並加到root logger(根Logger)中)這幾個logging模組層級別的函數,另外還有一個模組層級別的函數是logging.getLogger([name])(返回一個logger對象,如果沒有指定名字將返回root logger)

     先看一個最簡單的過程:

import logginglogger = logging.getLogger()# 建立一個handler,用於寫入記錄檔fh = logging.FileHandler(‘test.log‘)# 再建立一個handler,用於輸出到控制台ch = logging.StreamHandler()formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)fh.setFormatter(formatter)ch.setFormatter(formatter)logger.addHandler(fh) #logger對象可以添加多個fh和ch對象logger.addHandler(ch)logger.debug(‘logger debug message‘)logger.info(‘logger info message‘)logger.warning(‘logger warning message‘)logger.error(‘logger error message‘)logger.critical(‘logger critical message‘)

      先簡單介紹一下,logging庫提供了多個組件:Logger、Handler、Filter、Formatter。Logger對象提供應用程式可直接使用的介面,Handler發送日誌到適當的目的地,Filter提供了過濾日誌資訊的方法,Formatter指定日誌顯示格式。

     (1)

      Logger是一個樹形層級結構,輸出資訊之前都要獲得一個Logger(如果沒有顯示的擷取則自動建立並使用root Logger,如第一個例子所示)。
      logger = logging.getLogger()返回一個預設的Logger也即root Logger,並應用預設的記錄層級、Handler和Formatter設定。
當然也可以通過Logger.setLevel(lel)指定最低的記錄層級,可用的記錄層級有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
      Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()輸出不同層級的日誌,只有日誌等級大於或等於設定的記錄層級的日誌才會被輸出。 

logger.debug(‘logger debug message‘)  logger.info(‘logger info message‘)  logger.warning(‘logger warning message‘)  logger.error(‘logger error message‘)  logger.critical(‘logger critical message‘)  

只輸出了
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
     從這個輸出可以看出logger = logging.getLogger()返回的Logger名為root。這裡沒有用logger.setLevel(logging.Debug)顯示的為logger設定記錄層級,所以使用預設的記錄層級WARNIING,故結果只輸出了大於等於WARNIING層級的資訊。

     (2) 如果我們再建立兩個logger對象: 

##################################################logger1 = logging.getLogger(‘mylogger‘)logger1.setLevel(logging.DEBUG)logger2 = logging.getLogger(‘mylogger‘)logger2.setLevel(logging.INFO)logger1.addHandler(fh)logger1.addHandler(ch)logger2.addHandler(fh)logger2.addHandler(ch)logger1.debug(‘logger1 debug message‘)logger1.info(‘logger1 info message‘)logger1.warning(‘logger1 warning message‘)logger1.error(‘logger1 error message‘)logger1.critical(‘logger1 critical message‘)  logger2.debug(‘logger2 debug message‘)logger2.info(‘logger2 info message‘)logger2.warning(‘logger2 warning message‘)logger2.error(‘logger2 error message‘)logger2.critical(‘logger2 critical message‘)

結果:

      

這裡有兩個個問題:

      <1>我們明明通過logger1.setLevel(logging.DEBUG)將logger1的記錄層級設定為了DEBUG,為何顯示的時候沒有顯示出DEBUG層級的日誌資訊,而是從INFO層級的日誌開始顯示呢?

       原來logger1和logger2對應的是同一個Logger執行個體,只要logging.getLogger(name)中名稱參數name相同則返回的Logger執行個體就是同一個,且僅有一個,也即name與Logger執行個體一一對應。在logger2執行個體中通過logger2.setLevel(logging.INFO)設定mylogger的記錄層級為logging.INFO,所以最後logger1的輸出遵從了後來設定的記錄層級。

      <2>為什麼logger1、logger2對應的每個輸出分別顯示兩次?
       這是因為我們通過logger = logging.getLogger()顯示的建立了root Logger,而logger1 = logging.getLogger(‘mylogger‘)建立了root Logger的孩子(root.)mylogger,logger2同樣。而孩子,孫子,重孫……既會將訊息分發給他的handler進行處理也會傳遞給所有的祖先Logger處理。

        ok,那麼現在我們把

# logger.addHandler(fh)

# logger.addHandler(ch)  注釋掉,我們再來看效果:

 

因為我們注釋了logger對象顯示的位置,所以才用了預設,即標準輸出方式。因為它的父級沒有設定檔案顯示方式,所以在這裡只列印了一次。

孩子,孫子,重孫……可逐層繼承來自祖先的記錄層級、Handler、Filter設定,也可以通過Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。設定自己特別的記錄層級、Handler、Filter。若不設定則使用繼承來的值。

<3>Filter
     限制只有滿足過濾規則的日誌才會輸出。
     比如我們定義了filter = logging.Filter(‘a.b.c‘),並將這個Filter添加到了一個Handler上,則使用該Handler的Logger中只有名字帶          a.b.c首碼的Logger才能輸出其日誌。

 

     filter = logging.Filter(‘mylogger‘) 

     logger.addFilter(filter)

     這是只對logger這個對象進行篩選

     如果想對所有的對象進行篩選,則:

      filter = logging.Filter(‘mylogger‘) 

      fh.addFilter(filter)

      ch.addFilter(filter)

      這樣,所有添加fh或者ch的logger對象都會進行篩選。

完整代碼1:

 View Code

       完整代碼2:

 View Code

應用:     

 View Code

Python logging模組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.