python logging模組

來源:互聯網
上載者:User

標籤:路徑   改名   out   midnight   相同   card   網路   logger   最大   

  很多程式員都有記錄日誌的需求,並且日誌中包含的資訊即有正常的程式訪問日誌,還可能有錯誤,警告等資訊輸出,python的logging模組提供了標準的日誌介面,你可以通過它儲存各種各樣的日誌,你可以通過它儲存各種格式的日誌,logging的日誌可以分為debug(),info(),warning(),error() 和 critical()五個層級。

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

一,logging模組簡介

  logging模組是Python內建的標準模組,主要用於輸出作業記錄,可以設定輸出日誌的等級、日誌儲存路徑、記錄檔復原等;相比print,具備如下優點:

  1. 可以通過設定不同的日誌等級,在release版本中只輸出重要訊息,而不必顯示大量的調試資訊;
  2. print將所有資訊都輸出到標準輸出中,嚴重影響開發人員從標準輸出中查看其它資料;logging則可以由開發人員決定將資訊輸出到什麼地方,以及怎麼輸出;
二,基本用法
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 messageERROR:root:error messageCRITICAL: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=‘test.log‘,                      filemode=‘w‘)    logging.debug(‘debug message‘)  logging.info(‘info message‘)  logging.warning(‘warning message‘)  logging.error(‘error message‘)  logging.critical(‘critical message‘)            

  在test.log中查看輸出:

Wed, 14 Mar 2018 09:39:09 log模組.py[line:24] DEBUG debug messageWed, 14 Mar 2018 09:39:09 log模組.py[line:25] INFO info messageWed, 14 Mar 2018 09:39:09 log模組.py[line:26] WARNING warning messageWed, 14 Mar 2018 09:39:09 log模組.py[line:27] ERROR error messageWed, 14 Mar 2018 09:39:09 log模組.py[line:28] 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)

     先看一個最簡單的過程:

# _*_ coding: utf-8 _*_ import logginglogger = logging.getLogger()# 建立一個handler,用於寫入記錄檔,檔案輸出對象fh = logging.FileHandler(‘test1.log‘)# 再建立一個handler,用於輸出到控制台 ,螢幕輸出對象ch = logging.StreamHandler()#format 是輸出格式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‘)

  結果:

2018-03-14 10:19:39,478 - root - WARNING - logger warning message2018-03-14 10:19:39,478 - root - ERROR - logger error message2018-03-14 10:19:39,478 - root - CRITICAL - logger critical message
4.1  將日誌寫入檔案

  設定logging,建立一個FileHandler,並對輸出訊息的格式進行設定,將其添加到logger,然後將日誌寫入到指定的檔案中,

import logginglogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)handler = logging.FileHandler("log.txt")handler.setLevel(logging.INFO)formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)handler.setFormatter(formatter)logger.addHandler(handler)logger.info("Start print log")logger.debug("Do something")logger.warning("Something maybe fail.")logger.info("Finish")

  log.txt中日誌輸出資料為:

2018-03-14 22:47:14,497 - __main__ - INFO - Start print log2018-03-14 22:47:14,523 - __main__ - WARNING - Something maybe fail.2018-03-14 22:47:14,523 - __main__ - INFO - Finish

  

五,日誌同時輸出到螢幕和檔案

  如果想同時把log列印到螢幕和檔案日誌裡面,就需要瞭解一點複雜的知識了

  python使用logging模組記錄日誌涉及及格主要類,使用官方文檔中的概括最為合適:

  • logger提供了應用程式可以直接使用的介面
  • handle將(logger建立的)日誌記錄發送到合適的目的輸出
  • filter提供了細節裝置來決定輸出哪條日誌記錄
  • formatter決定日誌記錄的最終輸出格式

他們之間的關係如下:

 logger

每個程式在輸出資訊之前都要獲得一個Logger,Logger通常對應了程式的模組名,比如聊天工具的圖形介面模組可以這樣獲得它的Logger:

LOG = logging.getLogger("chat,gui")

而核心模組可以這樣:

LOG=logging.getLogger(”chat.kernel”)

  還可以綁著handle 和 filters

Logger.setLevel(lel):指定最低的記錄層級,低於lel的層級將被忽略。                            debug是最低的內建層級,critical為最高Logger.addFilter(filt)、Logger.removeFilter(filt):添加或刪除指定的filterLogger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或刪除指定的handler

  Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以設定的記錄層級

handler

handler對象負責發送相關的資訊到指定目的地,Python的日誌系統有多種Handler可以使用,有些handler可以把資訊輸出到控制台,有些Handler可以把資訊輸出到檔案,還有些Handler可以把資訊發送到網路上,如果覺得不夠用,還可以編寫自己的Handler,可以通過addHandler()方法添加多個Handler

Handler.setLevel(lel):指定被處理的資訊層級,低於lel層級的資訊將被忽略Handler.setFormatter():給這個handler選擇一個格式Handler.addFilter(filt)、Handler.removeFilter(filt):新增或刪除一個filter對象

  每個Logger可以附加多個Handler。接下來我們就來介紹一些常用的Handler:

1,logging.StreamHandler 使用這個Handler可以向類似與sys.stdout或者sys.stderr的任何檔案對象(file object)輸出資訊。

2,logging.FileHandler 和StreamHandler 類似,用於向一個檔案輸出日誌資訊。不過FileHandler會幫你開啟這個檔案

3,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並不會被更名,而是被刪除。

4,logging.handlers.TimedRotatingFileHandler

這個Handler和RotatingFileHandler類似,不過,它沒有通過判斷檔案大小來決定何時重新建立記錄檔,而是間隔一定時間就 自動建立新的記錄檔。重新命名的過程與RotatingFileHandler類似,不過新的檔案不是附加數字,而是目前時間。它的函數是:

TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])

  其中filename參數和backupCount參數和RotatingFileHandler具有相同的意義。

  interval是時間間隔

  when參數是一個字串,表示時間間隔的單位,不區分大小寫,它有以下取值:

S 秒M 分H 小時D 天W 每星期(interval==0時代表星期一)midnight 每天淩晨

  

formatter組件

  日誌的formatter是個獨立的組件,可以根handler組合

fh = logging.FileHandler("access.log")formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)fh.setFormatter(formatter) #把formmater綁定到fh上

  

filter組件

如果你相對記錄檔內容進行過濾,就可以自訂一個filter

class IgnoreBackupLogFilter(logging.Filter):    """忽略帶db backup 的日誌"""    def filter(self, record): #固定寫法        return   "db backup" not in record.getMessage()

  注意filter函數會返加True or False,logger根據此值決定是否輸出此日誌

然後把這個filter添加到logger中

logger.addFilter(IgnoreBackupLogFilter())

  下面的日誌就會把符合filter條件的過濾掉

logger.debug("test ....")logger.info("test info ....")logger.warning("start to run db backup job ....")logger.error("test error ....")
六,應用執行個體 6.1 一個同時輸出到螢幕、檔案、帶filter的完成例子
import loggingclass IgnoreBackupLogFilter(logging.Filter):    """忽略帶db backup 的日誌"""    def filter(self, record): #固定寫法        return   "db backup" not in record.getMessage()#console handlerch = logging.StreamHandler()ch.setLevel(logging.INFO)#file handlerfh = logging.FileHandler(‘mysql.log‘)#fh.setLevel(logging.WARNING)#formatterformatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)#bind formatter to chch.setFormatter(formatter)fh.setFormatter(formatter)logger = logging.getLogger("Mysql")logger.setLevel(logging.DEBUG) #logger 優先順序高於其它輸出途徑的#add handler   to logger instancelogger.addHandler(ch)logger.addHandler(fh)#add filterlogger.addFilter(IgnoreBackupLogFilter())logger.debug("test ....")logger.info("test info ....")logger.warning("start to run db backup job ....")logger.error("test error ....")

 

6.2  檔案自動截斷例子
import loggingfrom logging import handlerslogger = logging.getLogger(__name__)log_file = "timelog.log"#fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)formatter = logging.Formatter(‘%(asctime)s %(module)s:%(lineno)d %(message)s‘)fh.setFormatter(formatter)logger.addHandler(fh)logger.warning("test1")logger.warning("test12")logger.warning("test13")logger.warning("test14")

  

6.3  應用到atm程式中記錄檔的例子
import osimport timeimport loggingfrom config import settingsdef get_logger(card_num, struct_time):    if struct_time.tm_mday < 23:        file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon, 22)    else:        file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon+1, 22)    file_handler = logging.FileHandler(        os.path.join(settings.USER_DIR_FOLDER, card_num, ‘record‘, file_name),        encoding=‘utf-8‘    )    fmt = logging.Formatter(fmt="%(asctime)s :  %(message)s")    file_handler.setFormatter(fmt)    logger1 = logging.Logger(‘user_logger‘, level=logging.INFO)    logger1.addHandler(file_handler)    return logger1

  

 

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.