
Python logging模塊詳解_python 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 message
ERROR:root:error message
CRITICAL:root:critical message
可見,默認(rèn)情況下python的logging模塊將日志打印到了標(biāo)準(zhǔn)輸出中,且只顯示了大于等于WARNING級別的日志,這說明默認(rèn)的日志級別設(shè)置為WARNING(日志級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默認(rèn)的日志格式為日志級別: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()函數(shù)中可通過具體參數(shù)來更改logging模塊默認(rèn)行為,可用參數(shù)有
filename:用指定的文件名創(chuàng)建FiledHandler(后邊會具體講解handler的概念),這樣日志會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數(shù),默認(rèn)值為“a”還可指定為“w”。
format:指定handler使用的日志顯示格式。
datefmt:指定日期時間格式。
level:設(shè)置rootlogger(后邊會講解具體概念)的日志級別
stream:用指定的stream創(chuàng)建StreamHandler??梢灾付ㄝ敵龅絪ys.stderr,sys.stdout或者文件,默認(rèn)為sys.stderr。若同時列出了filename和stream兩個參數(shù),則stream參數(shù)會被忽略。
format參數(shù)中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 數(shù)字形式的日志級別
%(levelname)s 文本形式的日志級別
%(pathname)s 調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒有
%(filename)s 調(diào)用日志輸出函數(shù)的模塊的文件名
%(module)s 調(diào)用日志輸出函數(shù)的模塊名
%(funcName)s 調(diào)用日志輸出函數(shù)的函數(shù)名
%(lineno)d 調(diào)用日志輸出函數(shù)的語句所在的代碼行
%(created)f 當(dāng)前時間,用UNIX標(biāo)準(zhǔn)的表示時間的浮 點(diǎn)數(shù)表示
%(relativeCreated)d 輸出日志信息時的,自Logger創(chuàng)建以 來的毫秒數(shù)
%(asctime)s 字符串形式的當(dāng)前時間。默認(rèn)格式是 “2003-07-08 16:49:45,896”。逗號后面的是毫秒
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名??赡軟]有
%(process)d 進(jìn)程ID??赡軟]有
%(message)s用戶輸出的消息
若要對logging進(jìn)行更多靈活的控制有必要了解一下Logger,Handler,F(xiàn)ormatter,F(xiàn)ilter的概念
上述幾個例子中我們了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分別用以記錄不同級別的日志信息),logging.basicConfig()(用默認(rèn)日志格式(Formatter)為日志系統(tǒng)建立一個默認(rèn)的流處理器(StreamHandler),設(shè)置基礎(chǔ)配置(如日志級別等)并加到root logger(根Logger)中)這幾個logging模塊級別的函數(shù),另外還有一個模塊級別的函數(shù)是logging.getLogger([name])(返回一個logger對象,如果沒有指定名字將返回root
logger)
先看一個具體的例子
#coding:utf-8 import logging # 創(chuàng)建一個logger logger = logging.getLogger() logger1 = logging.getLogger('mylogger') logger1.setLevel(logging.DEBUG) logger2 = logging.getLogger('mylogger') logger2.setLevel(logging.INFO) logger3 = logging.getLogger('mylogger.child1') logger3.setLevel(logging.WARNING) logger4 = logging.getLogger('mylogger.child1.child2') logger4.setLevel(logging.DEBUG) logger5 = logging.getLogger('mylogger.child1.child2.child3') logger5.setLevel(logging.DEBUG) # 創(chuàng)建一個handler,用于寫入日志文件 fh = logging.FileHandler('/tmp/test.log') # 再創(chuàng)建一個handler,用于輸出到控制臺 ch = logging.StreamHandler() # 定義handler的輸出格式formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) #定義一個filter #filter = logging.Filter('mylogger.child1.child2') #fh.addFilter(filter) # 給logger添加handler #logger.addFilter(filter) logger.addHandler(fh) logger.addHandler(ch) #logger1.addFilter(filter) logger1.addHandler(fh) logger1.addHandler(ch) logger2.addHandler(fh) logger2.addHandler(ch) #logger3.addFilter(filter) logger3.addHandler(fh) logger3.addHandler(ch) #logger4.addFilter(filter) logger4.addHandler(fh) logger4.addHandler(ch) logger5.addHandler(fh) logger5.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') 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') logger3.debug('logger3 debug message') logger3.info('logger3 info message') logger3.warning('logger3 warning message') logger3.error('logger3 error message') logger3.critical('logger3 critical message') logger4.debug('logger4 debug message') logger4.info('logger4 info message') logger4.warning('logger4 warning message') logger4.error('logger4 error message') logger4.critical('logger4 critical message') logger5.debug('logger5 debug message') logger5.info('logger5 info message') logger5.warning('logger5 warning message') logger5.error('logger5 error message') logger5.critical('logger5 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
2014-05-06 12:54:43,224 – mylogger – INFO – logger1 info message
2014-05-06 12:54:43,224 – mylogger – INFO – logger1 info message
2014-05-06 12:54:43,225 – mylogger – WARNING – logger1 warning message
2014-05-06 12:54:43,225 – mylogger – WARNING – logger1 warning message
2014-05-06 12:54:43,226 – mylogger – ERROR – logger1 error message
2014-05-06 12:54:43,226 – mylogger – ERROR – logger1 error message
2014-05-06 12:54:43,227 – mylogger – CRITICAL – logger1 critical message
2014-05-06 12:54:43,227 – mylogger – CRITICAL – logger1 critical message
2014-05-06 12:54:43,228 – mylogger – INFO – logger2 info message
2014-05-06 12:54:43,228 – mylogger – INFO – logger2 info message
2014-05-06 12:54:43,229 – mylogger – WARNING – logger2 warning message
2014-05-06 12:54:43,229 – mylogger – WARNING – logger2 warning message
2014-05-06 12:54:43,230 – mylogger – ERROR – logger2 error message
2014-05-06 12:54:43,230 – mylogger – ERROR – logger2 error message
2014-05-06 12:54:43,231 – mylogger – CRITICAL – logger2 critical message
2014-05-06 12:54:43,231 – mylogger – CRITICAL – logger2 critical message
2014-05-06 12:54:43,232 – mylogger.child1 – WARNING – logger3 warning message
2014-05-06 12:54:43,232 – mylogger.child1 – WARNING – logger3 warning message
2014-05-06 12:54:43,232 – mylogger.child1 – WARNING – logger3 warning message
2014-05-06 12:54:43,234 – mylogger.child1 – ERROR – logger3 error message
2014-05-06 12:54:43,234 – mylogger.child1 – ERROR – logger3 error message
2014-05-06 12:54:43,234 – mylogger.child1 – ERROR – logger3 error message
2014-05-06 12:54:43,235 – mylogger.child1 – CRITICAL – logger3 critical message
2014-05-06 12:54:43,235 – mylogger.child1 – CRITICAL – logger3 critical message
2014-05-06 12:54:43,235 – mylogger.child1 – CRITICAL – logger3 critical message
2014-05-06 12:54:43,237 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 12:54:43,237 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 12:54:43,237 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 12:54:43,237 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 12:54:43,239 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 12:54:43,239 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 12:54:43,239 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 12:54:43,239 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 12:54:43,240 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 12:54:43,240 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 12:54:43,240 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 12:54:43,240 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 12:54:43,242 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 12:54:43,242 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 12:54:43,242 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 12:54:43,242 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 12:54:43,243 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 12:54:43,243 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 12:54:43,243 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 12:54:43,243 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 12:54:43,244 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 12:54:43,244 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 12:54:43,244 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 12:54:43,244 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 12:54:43,244 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 12:54:43,246 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 12:54:43,246 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 12:54:43,246 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 12:54:43,246 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 12:54:43,246 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 12:54:43,247 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 12:54:43,247 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 12:54:43,247 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 12:54:43,247 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 12:54:43,247 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 12:54:43,249 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 12:54:43,249 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 12:54:43,249 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 12:54:43,249 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 12:54:43,249 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 12:54:43,250 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 12:54:43,250 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 12:54:43,250 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 12:54:43,250 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 12:54:43,250 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
先簡單介紹一下,logging庫提供了多個組件:Logger、Handler、Filter、Formatter。Logger對象提供應(yīng)用程序可直接使用的接口,Handler發(fā)送日志到適當(dāng)?shù)哪康牡兀現(xiàn)ilter提供了過濾日志信息的方法,F(xiàn)ormatter指定日志顯示格式。
Logger
Logger是一個樹形層級結(jié)構(gòu),輸出信息之前都要獲得一個Logger(如果沒有顯示的獲取則自動創(chuàng)建并使用root Logger,如第一個例子所示)。
logger = logging.getLogger()返回一個默認(rèn)的Logger也即root Logger,并應(yīng)用默認(rèn)的日志級別、Handler和Formatter設(shè)置。
當(dāng)然也可以通過Logger.setLevel(lel)指定最低的日志級別,可用的日志級別有l(wèi)ogging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()輸出不同級別的日志,只有日志等級大于或等于設(shè)置的日志級別的日志才會被輸出。
我們看到程序中
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()顯示的為logger設(shè)置日志級別,所以使用默認(rèn)的日志級別WARNIING,故結(jié)果只輸出了大于等于WARNIING級別的信息。
另外,我們明明通過logger1.setLevel(logging.DEBUG)將logger1的日志級別設(shè)置為了DEBUG,為何顯示的時候沒有顯示出DEBUG級別的日志信息,而是從INFO級別的日志開始顯示呢?原來logger1和logger2對應(yīng)的是同一個Logger實(shí)例,只要logging.getLogger(name)中名稱參數(shù)name相同則返回的Logger實(shí)例就是同一個,且僅有一個,也即name與Logger實(shí)例一一對應(yīng)。在logger2實(shí)例中通過logger2.setLevel(logging.INFO)設(shè)置mylogger的日志級別為logging.INFO,所以最后logger1的輸出遵從了后來設(shè)置的日志級別。
logger1 = logging.getLogger('mylogger') logger1.setLevel(logging.DEBUG) logger2 = logging.getLogger('mylogger') logger2.setLevel(logging.INFO)
為什么logger1、logger2對應(yīng)的每個輸出分別顯示兩次,logger3對應(yīng)的輸出顯示3次,logger4對應(yīng)的輸出顯示4次……呢?
這是因為我們通過logger = logging.getLogger()顯示的創(chuàng)建了root Logger,而logger1 = logging.getLogger(‘mylogger’)創(chuàng)建了root Logger的孩子(root.)mylogger,logger2同樣。
logger3 = logging.getLogger(‘mylogger.child1’)創(chuàng)建了(root.)mylogger.child1
logger4 = logging.getLogger(‘mylogger.child1.child2’)創(chuàng)建了(root.)mylogger.child1.child2
logger5 = logging.getLogger(‘mylogger.child1.child2.child3’)創(chuàng)建了(root.)mylogger.child1.child2.child3
而孩子,孫子,重孫……既會將消息分發(fā)給他的handler進(jìn)行處理也會傳遞給所有的祖先Logger處理。
試著注釋掉如下一行程序,觀察程序輸出
#logger.addHandler(fh)
發(fā)現(xiàn)標(biāo)準(zhǔn)輸出中每條記錄對應(yīng)兩行(因為root Logger默認(rèn)使用StreamHandler)
2014-05-06 15:10:10,980 – mylogger – INFO – logger1 info message
2014-05-06 15:10:10,980 – mylogger – INFO – logger1 info message
2014-05-06 15:10:10,981 – mylogger – WARNING – logger1 warning message
2014-05-06 15:10:10,981 – mylogger – WARNING – logger1 warning message
2014-05-06 15:10:10,982 – mylogger – ERROR – logger1 error message
2014-05-06 15:10:10,982 – mylogger – ERROR – logger1 error message
2014-05-06 15:10:10,984 – mylogger – CRITICAL – logger1 critical message
2014-05-06 15:10:10,984 – mylogger – CRITICAL – logger1 critical message
……
而在文件輸出中每條記錄對應(yīng)一行(因為我們注釋掉了logger.addHandler(fh),沒有對root Logger啟用FileHandler)
2014-05-06 15:10:10,980 – mylogger – INFO – logger1 info message
2014-05-06 15:10:10,981 – mylogger – WARNING – logger1 warning message
2014-05-06 15:10:10,982 – mylogger – ERROR – logger1 error message
2014-05-06 15:10:10,984 – mylogger – CRITICAL – logger1 critical message
孩子,孫子,重孫……可逐層繼承來自祖先的日志級別、Handler、Filter設(shè)置,也可以通過Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。設(shè)置自己特別的日志級別、Handler、Filter。若不設(shè)置則使用繼承來的值。
Handler
上述例子的輸出在標(biāo)準(zhǔn)輸出和指定的日志文件中均可以看到,這是因為我們定義并使用了兩種Handler。
fh = logging.FileHandler('/tmp/test.log') ch = logging.StreamHandler()
Handler對象負(fù)責(zé)發(fā)送相關(guān)的信息到指定目的地,有幾個常用的Handler方法:
Handler.setLevel(lel):指定日志級別,低于lel級別的日志將被忽略
Handler.setFormatter():給這個handler選擇一個Formatter
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或刪除一個filter對象
可以通過addHandler()方法為Logger添加多個Handler:
logger.addHandler(fh) logger.addHandler(ch)
有多中可用的Handler:
logging.StreamHandler 可以向類似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息
logging.FileHandler 用于向一個文件輸出日志信息
logging.handlers.RotatingFileHandler 類似于上面的FileHandler,但是它可以管理文件大小。當(dāng)文件達(dá)到一定大小之后,它會自動將當(dāng)前日志文件改名,然后創(chuàng)建一個新的同名日志文件繼續(xù)輸出
logging.handlers.TimedRotatingFileHandler 和RotatingFileHandler類似,不過,它沒有通過判斷文件大小來決定何時重新創(chuàng)建日志文件,而是間隔一定時間就自動創(chuàng)建新的日志文件
logging.handlers.SocketHandler 使用TCP協(xié)議,將日志信息發(fā)送到網(wǎng)絡(luò)。
logging.handlers.DatagramHandler 使用UDP協(xié)議,將日志信息發(fā)送到網(wǎng)絡(luò)。
logging.handlers.SysLogHandler 日志輸出到syslog
logging.handlers.NTEventLogHandler 遠(yuǎn)程輸出日志到Windows NT/2000/XP的事件日志
logging.handlers.SMTPHandler 遠(yuǎn)程輸出日志到郵件地址
logging.handlers.MemoryHandler 日志輸出到內(nèi)存中的制定buffer
logging.handlers.HTTPHandler 通過”GET”或”POST”遠(yuǎn)程輸出到HTTP服務(wù)器
各個Handler的具體用法可查看參考書冊:
https://docs.python.org/2/library/logging.handlers.html#module-logging.handlers
Formatter
Formatter對象設(shè)置日志信息最后的規(guī)則、結(jié)構(gòu)和內(nèi)容,默認(rèn)的時間格式為%Y-%m-%d %H:%M:%S。
#定義Formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') #為Handler添加Formatter fh.setFormatter(formatter) ch.setFormatter(formatter)
Formatter參數(shù)中可能用到的格式化串參見上文(logging.basicConfig()函數(shù)format參數(shù)中可能用到的格式化串:)
Filter
限制只有滿足過濾規(guī)則的日志才會輸出。
比如我們定義了filter = logging.Filter(‘a(chǎn).b.c’),并將這個Filter添加到了一個Handler上,則使用該Handler的Logger中只有名字帶a.b.c前綴的Logger才能輸出其日志。
取消下列兩行程序的注釋
#filter = logging.Filter('mylogger.child1.child2') #fh.addFilter(filter)
標(biāo)準(zhǔn)輸出中輸出結(jié)果并沒有發(fā)生變化,但日志文件輸出中只顯示了如下內(nèi)容:
2014-05-06 15:27:36,227 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:27:36,227 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:27:36,227 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:27:36,227 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:27:36,228 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:27:36,228 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:27:36,228 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:27:36,228 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:27:36,230 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:27:36,230 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:27:36,230 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:27:36,230 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:27:36,232 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:27:36,232 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:27:36,232 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:27:36,232 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:27:36,233 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:27:36,233 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:27:36,233 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:27:36,233 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:27:36,235 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:27:36,235 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:27:36,235 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:27:36,235 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:27:36,235 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:27:36,236 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:27:36,236 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:27:36,236 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:27:36,236 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:27:36,236 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:27:36,238 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:27:36,238 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:27:36,238 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:27:36,238 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:27:36,238 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:27:36,240 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:27:36,240 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:27:36,240 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:27:36,240 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:27:36,240 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:27:36,242 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:27:36,242 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:27:36,242 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:27:36,242 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:27:36,242 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
當(dāng)然也可以直接給Logger加Filter。若為Handler加Filter則所有使用了該Handler的Logger都會受到影響。而為Logger添加Filter只會影響到自身。
注釋掉
#fh.addFilter(filter)
并取消如下幾行的注釋
#logger.addFilter(filter) #logger1.addFilter(filter) #logger3.addFilter(filter) #logger4.addFilter(filter)
輸出結(jié)果
2014-05-06 15:32:10,746 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:32:10,746 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:32:10,746 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:32:10,746 – mylogger.child1.child2 – DEBUG – logger4 debug message
2014-05-06 15:32:10,748 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:32:10,748 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:32:10,748 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:32:10,748 – mylogger.child1.child2 – INFO – logger4 info message
2014-05-06 15:32:10,751 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:32:10,751 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:32:10,751 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:32:10,751 – mylogger.child1.child2 – WARNING – logger4 warning message
2014-05-06 15:32:10,753 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:32:10,753 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:32:10,753 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:32:10,753 – mylogger.child1.child2 – ERROR – logger4 error message
2014-05-06 15:32:10,754 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:32:10,754 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:32:10,754 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:32:10,754 – mylogger.child1.child2 – CRITICAL – logger4 critical message
2014-05-06 15:32:10,755 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:32:10,755 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:32:10,755 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:32:10,755 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:32:10,755 – mylogger.child1.child2.child3 – DEBUG – logger5 debug message
2014-05-06 15:32:10,757 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:32:10,757 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:32:10,757 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:32:10,757 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:32:10,757 – mylogger.child1.child2.child3 – INFO – logger5 info message
2014-05-06 15:32:10,759 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:32:10,759 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:32:10,759 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:32:10,759 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:32:10,759 – mylogger.child1.child2.child3 – WARNING – logger5 warning message
2014-05-06 15:32:10,761 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:32:10,761 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:32:10,761 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:32:10,761 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:32:10,761 – mylogger.child1.child2.child3 – ERROR – logger5 error message
2014-05-06 15:32:10,762 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:32:10,762 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:32:10,762 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:32:10,762 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
2014-05-06 15:32:10,762 – mylogger.child1.child2.child3 – CRITICAL – logger5 critical message
發(fā)現(xiàn)root、mylogger、mylogger.child1的輸出全部被過濾掉了。
除了直接在程序中設(shè)置Logger,Handler,Filter,Formatter外還可以將這些信息寫進(jìn)配置文件中。
例如典型的logging.conf
[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt=
程序可以這么寫
import logging import logging.config logging.config.fileConfig("logging.conf") # 采用配置文件 # create logger logger = logging.getLogger("simpleExample") # "application" code logger.debug("debug message") logger.info("info message") logger.warn("warn message") logger.error("error message") logger.critical("critical message")
多模塊使用logging
logging模塊保證在同一個python解釋器內(nèi),多次調(diào)用logging.getLogger(‘log_name’)都會返回同一個logger實(shí)例,即使是在多個模塊的情況下。所以典型的多模塊場景下使用logging的方式是在main模塊中配置logging,這個配置會作用于多個的子模塊,然后在其他模塊中直接通過getLogger獲取Logger對象即可。
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()...')數(shù)據(jù)分析培訓(xùn)
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預(yù)測分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢預(yù)判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預(yù)測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03