Python中內置的日志模塊logging用法詳解
logging模塊簡介
Python的logging模塊提供了通用的日志系統,可以方便第三方模塊或者是應用使用。這個模塊提供不同的日志級別,并可以采用不同的方式記錄日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己實現具體的日志記錄方式。
logging模塊與log4j的機制是一樣的,只是具體的實現細節(jié)不同。模塊提供logger,handler,filter,formatter。
- logger:提供日志接口,供應用代碼使用。logger最長用的操作有兩類:配置和發(fā)送日志消息??梢酝ㄟ^logging.getLogger(name)獲取logger對象,如果不指定name則返回root對象,多次使用相同的name調用getLogger方法返回同一個logger對象。
- handler:將日志記錄(log record)發(fā)送到合適的目的地(destination),比如文件,socket等。一個logger對象可以通過addHandler方法添加0到多個handler,每個handler又可以定義不同日志級別,以實現日志分級過濾顯示。
- filter:提供一種優(yōu)雅的方式決定一個日志記錄是否發(fā)送到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創(chuàng)建以 來的毫秒數
%(thread)d 線程ID??赡軟]有
%(threadName)s 線程名??赡軟]有
%(process)d 進程ID??赡軟]有
5. 記錄 使用object.debug(message)來記錄日志
下面來寫一個實例,在CMD窗口上只打出error以上級別的日志,但是在日志中打出debug以上的信息
import logging logger = 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=gbk import logging,os class 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=gbk import logging,os import ctypes FOREGROUND_WHITE = 0x0007 FOREGROUND_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_GREEN STD_OUTPUT_HANDLE= -11 std_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 bool class 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是輸出到標準輸出。
相關文章
在python里創(chuàng)建一個任務(Task)實例
這篇文章主要介紹了在python里創(chuàng)建一個任務(Task)實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04python3+openCV 獲取圖片中文本區(qū)域的最小外接矩形實例
這篇文章主要介紹了python3+openCV 獲取圖片中文本區(qū)域的最小外接矩形實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python神經網絡tensorflow利用訓練好的模型進行預測
這篇文章主要為大家介紹了python神經網絡tensorflow利用訓練好的模型進行預測,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05python數據批量寫入ScrolledText的優(yōu)化方法
今天小編就為大家分享一篇python數據批量寫入ScrolledText的優(yōu)化方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10Flask如何獲取用戶的ip,查詢用戶的登錄次數,并且封ip
這篇文章主要介紹了Flask如何獲取用戶的ip,查詢用戶的登錄次數,并且封ip問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01