我目睹記錄模塊的行爲有趣。我錯過了什麼嗎?奇怪:記錄器只使用第一個處理程序的格式化程序的例外
我正在做兩個處理程序的常見事情:一個StreamHandler只記錄信息和更高的控制檯,和一個FileHandler,它也將處理所有的DEBUG信息。
它工作得很好,直到我決定使用不同的格式。我想在文件中使用完整的堆棧跟蹤,但只是控制檯上的異常類型和值。由於處理程序有一個setFormatter函數,並且由於編寫logging.Formatter的子類似乎很容易,所以我認爲它會起作用。
控制檯處理程序和文件處理程序都有自己的格式化程序。代碼中的打印語句證明了這一點。但是,對logger.exception的調用將只使用第一個處理程序的formatException = added異常將以其在控制檯中應具有的格式記錄在文件中。更改logger.addHandler行的順序,然後是各處使用的文件處理程序的formatException。
import logging
import sys
class ConsoleFormatter(logging.Formatter):
def formatException(self, exc_info):
# Ugly but obvious way to see who's talking.
return "CONSOLE EXCEPTION %s: %s" % exc_info[:2]
def setup(path):
logger = logging.getLogger()
#
file_handler = logging.FileHandler(path, mode='w')
if __debug__:
file_handler.setLevel(logging.DEBUG)
else:
file_handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s %(levelname)-8s "
"%(name)-16s %(message)s "
"[%(filename)[email protected]%(lineno)d in %(funcName)s]")
file_handler.setFormatter(formatter)
#
console_handler = logging.StreamHandler(sys.stderr)
console_handler.setLevel(logging.INFO)
console_formatter = ConsoleFormatter("%(levelname)-8s - %(message)s")
console_handler.setFormatter(console_formatter)
# >>> FUN HAPPENS HERE <<<
# Only the formatter of the first handler is used ! Both on the console
# and in the file. Change the order of these two lines to see.
logger.addHandler(console_handler)
logger.addHandler(file_handler)
#
# Proof that the two handlers have different formatters:
print logger.handlers
print file_handler.formatter.formatException
print console_formatter.formatException
#
logger.setLevel(logging.DEBUG)
logger.info("Logger ready.")
setup('test.log')
logger = logging.getLogger()
logger.debug("Only visible in the file.")
try:
1/0
except ZeroDivisionError:
logger.exception("boom")
發生了什麼事?
編輯:我使用的是Python 2.6的方式。 編輯:關於「console_formatter」變量名稱的代碼錯誤更正。
優秀!通過繼承logging.Formatter,我可以覆蓋format()。這個重寫方法在調用超類'format()之前將record.exc_text設置爲None,並將其恢復到之前的值。這樣,我禁用了緩存異常文本而不重複任何代碼。然後,我使用這個CachelessFormatter作爲我的兩個處理程序的基類,它可以工作\ o /。謝謝 ! – Niriel 2011-05-04 06:27:16