我想加強我的Python腳本中的日誌記錄,我很感激能不能與我分享最佳實踐。現在我創造了這個小腳本(我應該說我運行Python 3.4)多流處理程序
import logging
import io
import sys
def Streamhandler(stream, level, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"):
ch = logging.StreamHandler(stream)
ch.setLevel(level)
formatter = logging.Formatter(format)
ch.setFormatter(formatter)
return ch
# get the root logger
logger = logging.getLogger()
stream = io.StringIO()
logger.addHandler(Streamhandler(stream, logging.WARN))
stream_error = io.StringIO()
logger.addHandler(Streamhandler(stream_error, logging.ERROR))
logger.addHandler(Streamhandler(stream=sys.stdout, level=logging.DEBUG))
print(logger)
for h in logger.handlers:
print(h)
print(h.level)
# 'application' code # goes to the root logger!
logging.debug('debug message')
logging.info('info message')
logging.warning('warn message')
logging.error('error message')
logging.critical('critical message')
print(stream.getvalue())
print(stream_error.getvalue())
我有三個處理,其中2寫入到io.StringIO(這似乎工作)。我需要這個來簡化測試,但也需要通過HTTP電子郵件服務發送日誌。然後有一個控制檯的Streamhandler。但是,儘管將該級別明確設置得足夠低,但在控制檯上會忽略logging.debug和logging.info消息?
我想我最終解釋了logger = logging.getLogger(「MyLogger」)到模塊和包的更深層次。我對模塊定義自己的記錄器持懷疑態度...... – tschm
@tschm模塊需要一個記錄器來記錄任何東西,它需要的只是一個「導入記錄; logger = logging.getLogger(__ name __)'行開頭(** no ** config在這裏完成)。這是進行日誌記錄的預期方式:記錄器根據記錄器名稱形成一個層次結構('foo.bar'是'foo'的子元素,它是'root'的子元素),如果沒有明確配置,記錄器會傳播給它parent - 這樣做可以確保我們正確構建了這個層次結構,然後如果需要,您可以完全控制每個包/模塊/子模塊的日誌配置,或者只需配置根日誌記錄器。 –
它開始有意義:-)。雖然我的主要功能是調用3個不同的包(這可能表明我應該做一些重構)。在這個階段,我決定使用def f(x,logger = None):並且在使用日誌記錄的函數和類中包含logger = logger或logging.getLogger(__ name__)。所以我可以解析我的主要功能的記錄器給我的客戶,但我不必。使用這個(骯髒的)技巧,我只需要配置一個記錄器來統一它們。 – tschm