Python中內建的日誌模組logging用法詳解,pythonlogging

來源:互聯網
上載者:User

Python中內建的日誌模組logging用法詳解,pythonlogging

logging模組簡介

Python的logging模組提供了通用的日誌系統,可以方便第三方模組或者是應用使用。這個模組提供不同的記錄層級,並可以採用不同的方式記錄日誌,比如檔案,HTTP GET/POST,SMTP,Socket等,甚至可以自己實現具體的日誌記錄方式。
logging模組與log4j的機制是一樣的,只是具體的實現細節不同。模組提供logger,handler,filter,formatter。

  • logger:提供日誌介面,供應用代碼使用。logger最長用的操作有兩類:配置和發送日誌訊息。可以通過logging.getLogger(name)擷取logger對象,如果不指定name則返回root對象,多次使用相同的name調用getLogger方法返回同一個logger對象。
  • handler:將日誌記錄(log record)發送到合適的目的地(destination),比如檔案,socket等。一個logger對象可以通過addHandler方法添加0到多個handler,每個handler又可以定義不同記錄層級,以實現日誌分級過濾顯示。
  •  filter:提供一種優雅的方式決定一個日誌記錄是否發送到handler。
  •  formatter:指定日誌記錄輸出的具體格式。formatter的構造方法需要兩個參數:訊息的格式字串和日期文字,這兩個參數都是可選的。

與log4j類似,logger,handler和日誌訊息的調用可以有具體的記錄層級(Level),只有在日誌訊息的層級大於logger和handler的層級。

logging用法解析

1. 初始化 logger = logging.getLogger("endlesscode"),getLogger()方法後面最好加上所要日誌記錄的模組名字,後面的日誌格式中的%(name)s 對應的是這裡的模組名字
2. 順位 logger.setLevel(logging.DEBUG),Logging中有NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL這幾種層級,日誌會記錄順位以上的日誌
3. Handler,常用的是StreamHandler和FileHandler,windows下你可以簡單理解為一個是console和檔案日誌,一個列印在CMD視窗上,一個記錄在一個檔案上
4. formatter,定義了最終log資訊的順序,結構和內容,我喜歡用這樣的格式 '[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S',
%(name)s Logger的名字
%(levelname)s 文本形式的記錄層級
%(message)s 使用者輸出的訊息
%(asctime)s 字串形式的目前時間。預設格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒
%(levelno)s 數字形式的記錄層級
%(pathname)s 調用日誌輸出函數的模組的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模組的檔案名稱
%(module)s  調用日誌輸出函數的模組名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的程式碼
%(created)f 目前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌資訊時的,自Logger建立以 來的毫秒數
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
5. 記錄 使用object.debug(message)來記錄日誌
下面來寫一個執行個體,在CMD視窗上只打出error以上層級的日誌,但是在日誌中打出debug以上的資訊

import logginglogger = logging.getLogger("simple_example")logger.setLevel(logging.DEBUG)# 建立一個filehandler來把日誌記錄在檔案裡,層級為debug以上fh = logging.FileHandler("spam.log")fh.setLevel(logging.DEBUG)# 建立一個streamhandler來把日誌打在CMD視窗上,層級為error以上ch = logging.StreamHandler()ch.setLevel(logging.ERROR)# 設定日誌格式formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")ch.setFormatter(formatter)fh.setFormatter(formatter)#將相應的handler添加在logger對象中logger.addHandler(ch)logger.addHandler(fh)# 開始打日誌logger.debug("debug message")logger.info("info message")logger.warn("warn message")logger.error("error message")logger.critical("critical message")

運行一下將會看到CMD視窗只記錄兩條,spam.log中記錄了五條日誌

當一個項目比較大的時候,不同的檔案中都要用到Log,可以考慮將其封裝為一個類來使用

#! /usr/bin/env python#coding=gbkimport logging,osclass Logger: def __init__(self, path,clevel = logging.DEBUG,Flevel = logging.DEBUG):  self.logger = logging.getLogger(path)  self.logger.setLevel(logging.DEBUG)  fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')  #設定CMD日誌  sh = logging.StreamHandler()  sh.setFormatter(fmt)  sh.setLevel(clevel)  #設定檔案日誌  fh = logging.FileHandler(path)  fh.setFormatter(fmt)  fh.setLevel(Flevel)  self.logger.addHandler(sh)  self.logger.addHandler(fh) def debug(self,message):  self.logger.debug(message) def info(self,message):  self.logger.info(message) def war(self,message):  self.logger.warn(message) def error(self,message):  self.logger.error(message) def cri(self,message):  self.logger.critical(message)if __name__ =='__main__': logyyx = Logger('yyx.log',logging.ERROR,logging.DEBUG) logyyx.debug('一個debug資訊') logyyx.info('一個info資訊') logyyx.war('一個warning資訊') logyyx.error('一個error資訊') logyyx.cri('一個致命critical資訊')

這樣每次使用的時候只要執行個體化一個對象就可以了

logobj = Logger(‘filename',clevel,Flevel)

如果想在CMD視窗中對於error的日誌標紅,warning的日誌標黃,那麼可以使用ctypes模組

#! /usr/bin/env python#coding=gbkimport logging,osimport ctypesFOREGROUND_WHITE = 0x0007FOREGROUND_BLUE = 0x01 # text color contains blue.FOREGROUND_GREEN= 0x02 # text color contains green.FOREGROUND_RED = 0x04 # text color contains red.FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREENSTD_OUTPUT_HANDLE= -11std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)def set_color(color, handle=std_out_handle): bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color) return boolclass Logger: def __init__(self, path,clevel = logging.DEBUG,Flevel = logging.DEBUG):  self.logger = logging.getLogger(path)  self.logger.setLevel(logging.DEBUG)  fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')  #設定CMD日誌  sh = logging.StreamHandler()  sh.setFormatter(fmt)  sh.setLevel(clevel)  #設定檔案日誌  fh = logging.FileHandler(path)  fh.setFormatter(fmt)  fh.setLevel(Flevel)  self.logger.addHandler(sh)  self.logger.addHandler(fh) def debug(self,message):  self.logger.debug(message) def info(self,message):  self.logger.info(message) def war(self,message,color=FOREGROUND_YELLOW):  set_color(color)  self.logger.warn(message)  set_color(FOREGROUND_WHITE) def error(self,message,color=FOREGROUND_RED):  set_color(color)  self.logger.error(message)  set_color(FOREGROUND_WHITE) def cri(self,message):  self.logger.critical(message)if __name__ =='__main__': logyyx = Logger('yyx.log',logging.WARNING,logging.DEBUG) logyyx.debug('一個debug資訊') logyyx.info('一個info資訊') logyyx.war('一個warning資訊') logyyx.error('一個error資訊') logyyx.cri('一個致命critical資訊')

多模組使用logging
logging模組保證在同一個python解譯器內,多次調用logging.getLogger('log_name')都會返回同一個logger執行個體,即使是在多個模組的情況下。所以典型的多模組情境下使用logging的方式是在main模組中配置logging,這個配置會作用於多個的子模組,然後在其他模組中直接通過getLogger擷取Logger對象即可。
設定檔:

[loggers] keys=root,main  [handlers] keys=consoleHandler,fileHandler  [formatters] keys=fmt  [logger_root] level=DEBUG handlers=consoleHandler  [logger_main] level=DEBUG qualname=main handlers=fileHandler  [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=fmt args=(sys.stdout,)  [handler_fileHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=fmt args=('tst.log','a',20000,5,)  [formatter_fmt] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt= 

主模組main.py:

import logging import logging.config  logging.config.fileConfig('logging.conf') root_logger = logging.getLogger('root') root_logger.debug('test root logger...')  logger = logging.getLogger('main') logger.info('test main logger') logger.info('start import module \'mod\'...') import mod  logger.debug('let\'s test mod.testLogger()') mod.testLogger()  root_logger.info('finish test...') 

子模組mod.py:

import logging import submod  logger = logging.getLogger('main.mod') logger.info('logger of mod say something...')  def testLogger():   logger.debug('this is mod.testLogger...')   submod.tst() 

子子模組submod.py:

import logging  logger = logging.getLogger('main.mod.submod') logger.info('logger of submod say something...')  def tst():   logger.info('this is submod.tst()...') 

然後運行python main.py,控制台輸出:

2012-03-09 18:22:22,793 - root - DEBUG - test root logger... 2012-03-09 18:22:22,793 - main - INFO - test main logger 2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'... 2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something... 2012-03-09 18:22:22,809 - main.mod - INFO - logger say something... 2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger() 2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger... 2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()... 2012-03-09 18:22:22,841 - root - INFO - finish test... 

可以看出,和預想的一樣,然後在看一下tst.log,logger配置中的輸出的目的地:

2012-03-09 18:22:22,793 - main - INFO - test main logger 2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'... 2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something... 2012-03-09 18:22:22,809 - main.mod - INFO - logger say something... 2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger() 2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger... 2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()... 

tst.log中沒有root logger輸出的資訊,因為logging.conf中配置了只有main logger及其子logger使用RotatingFileHandler,而root logger是輸出到標準輸出。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.