我成功使用python3程序中的logging
模块将日志消息发送到日志文件,例如/var/log/myprogram.log
。在某些情况下,我希望这些消息的子集也转到stdout
,它们通过我的logging.Logger
实例格式化,就像它们转到日志文件时格式化一样。
假设我的记录器实例被称为loginstance
,我想在loginstance.log(level, msg)
周围添加某种包装,让我选择消息是否仅转到/var/log/myprogram.log
,或者它是否去了stdout
,如下:
# Assume `loginstance` has already been instantiated
# as a global, and that it knows to send logging info
# to `/var/log/myprogram.log` by default.
def mylogger(level, msg, with_stdout=False):
if with_stdout:
# Somehow send `msg` through `loginstance` so
# that it goes BOTH to `/var/log/myprogram.log`
# AND to `stdout`, with identical formatting.
else:
# Send only to `/var/log/myprogram.log` by default.
loginstance.log(level, msg)
我希望使用一个单logging.Logger
个实例来管理它,这样如果我想更改格式或其他日志记录行为,我只需要在一个地方执行此操作。
我猜测这涉及对logging.Logger
和/或logging.Formatter
进行子类化,但我还没弄清楚如何做到这一点。
提前感谢您提出任何建议。
答案 0 :(得分:0)
我想出了怎么做。它只需要我使用 Dim MondaySheetRow as Range
MondaySheetRow = Sheets("Monday").Rows(8)
MondaySheetRow.Insert Shift:=xlDown
子类并将额外的参数传递给FileHandler
......
log()
实例化我的记录器时,我这样做......
class MyFileHandler(logging.FileHandler):
def emit(self, record):
super().emit(record)
also_use_stdout = getattr(record, 'also_use_stdout', False)
if also_use_stdout:
savestream = self.stream
self.stream = sys.stdout
try:
super().emit(record)
finally:
self.stream = savestream
然后,我上面描述的logger = logging.getLogger('myprogram')
logger.addHandler(MyFileHandler('/var/log/myprogram.log'))
函数将如下所示:
mylogger
这是有效的,因为传递给可选def mylogger(level, msg, with_stdout=False):
loginstance.log(level, msg, extra={'also_use_stdout': with_stdout})
字典中的log
函数的任何内容都会成为最终传递给extra
的{{1}}对象的属性。