業(yè)務(wù)代碼用的是python原生的logging模塊。
現(xiàn)在碰到這么一個需求:當(dāng)處理error級別日志時雹嗦,將錯誤信息統(tǒng)一進(jìn)行某種操作逊抡。比如發(fā)送到一個消息隊列里荡含。不能改變現(xiàn)有的業(yè)務(wù)代碼結(jié)構(gòu)。
首先想到的是logging模塊是否有類似回調(diào)方法的設(shè)定甚垦。經(jīng)過查詢茶鹃,果然logging中有一個handler屬性,可以自定義對異常信息的處理艰亮。logging自帶幾種handler闭翩,比如StreamHandler、FileHandler等迄埃。為了將功能最大化疗韵,我們選擇其中的NullHandler,它什么都不干侄非。我們實現(xiàn)一個新的類來繼承它蕉汪,再在其中自定義我們的邏輯流译。
代碼:
# encoding: utf-8
import logging
from logging import NullHandler
class MyHandler(NullHandler):
? ? def handle(self, record):
? ? ? ? # print "=====,%s" % (str(record.__dict__))
? ? ? ? msg = record.msg
? ? ? ? msg = record.message? # 在服務(wù)中該字段叫'message'
? ? ? ? if record.levelno == 10:? # DEBUG
? ? ? ? ? ? pass
? ? ? ? elif record.levelno == 20:? # INFO
? ? ? ? ? ? pass
? ? ? ? elif record.levelno == 30:? # WARNING
? ? ? ? ? ? pass
? ? ? ? elif record.levelno == 40:? # ERROR
? ? ? ? ? ? print u"在這里執(zhí)行對error的處理:%s" % msg
? ? ? ? elif record.levelno == 50:? # CRITICAL
? ? ? ? ? ? print u"在這里執(zhí)行對critical的處理:%s" % msg
logging.getLogger("").setLevel(logging.NOTSET)
logging.basicConfig()
logging.getLogger("").addHandler(MyHandler())
if __name__ == "__main__":
? ? logging.debug(u"這是一條 DEBUG 信息")
? ? logging.info(u"這是一條 INFO 信息")
? ? logging.warning(u"這是一條 WARNING 信息")
? ? logging.error(u"這是一條 ERROR 信息")
? ? logging.critical(u"這是一條 CRITICAL 信息")
上述中的“l(fā)ogging.basicConfig()”一行主要實現(xiàn)這么一個功能:由于我們?yōu)閘ogging設(shè)置了自定義的handler,那么所有的錯誤級別日志肤无,都需要我們在handle方法中自定義先蒋。但是我們現(xiàn)在只想對error級別以上的錯誤進(jìn)行預(yù)處理,對于更低級別的日志宛渐,我們希望它就按原來的樣式原封不動輸出就好竞漾。經(jīng)過查看源代碼,發(fā)現(xiàn)可以用?basicConfig()方法窥翩,這個方法寫在logging模塊原生的debug()业岁、info()、warning()...... 等所有級別的方法中寇蚊,它實現(xiàn)的是:如果發(fā)現(xiàn)用戶沒有設(shè)置任何handler笔时,那么進(jìn)行若干步初始化設(shè)置,就是這些初始化設(shè)置實現(xiàn)了我們在控制臺看到的不同顏色仗岸、縮進(jìn)等樣式輸出的日志≡使ⅲ現(xiàn)在我們首先實現(xiàn)logging.basicConfig(),再添加自定義的handler扒怖,那兩塊邏輯就同時實現(xiàn)了较锡。
正因為如此,
logging.basicConfig()
logging.getLogger("").addHandler(MyHandler())
這兩行的順序不能調(diào)換盗痒。