更改一个处理程序的日志记录格式会更改所有处理程序
Changing logging format for one handler changes it for all
我想将一个记录器流式传输到多个流。更改标准格式有效,但更改 formatException
函数会改变所有格式!
不确定这是否是一项功能,我误解了什么。
请参阅下面的示例,其中我使用标准 logging.Formatter 和带有 limit
变量的修改版:
import logging, io, traceback
class TermFormatter(logging.Formatter):
def __init__(self, *args, stack_limit=1, **kwargs):
super().__init__(*args, **kwargs)
self.stack_limit = stack_limit
def formatException(self, ei):
"""
Format and return the specified exception information as a string.
This default implementation just uses
traceback.print_exception()
"""
sio = io.StringIO()
tb = ei[2]
# See issues #9427, #1553375. Commented out for now.
#if getattr(self, 'fullstack', False):
# traceback.print_stack(tb.tb_frame.f_back, file=sio)
traceback.print_exception(ei[0], ei[1], tb, self.stack_limit, sio)
s = sio.getvalue()
sio.close()
if s[-1:] == "\n":
s = s[:-1]
if self.stack_limit ==0:
return "Hello my friend!"
else:
return s
stream_handler = logging.StreamHandler()
stream_handler.terminator = " \n"
formatter0 = TermFormatter("F1 %(asctime)s [%(levelname)s]: %(message)s",
stack_limit=2)
stream_handler.setFormatter(formatter0)
stream_handler.setLevel(logging.ERROR)
#check the internals of the err logging
stream_handler2 = logging.StreamHandler()
stream_handler2.terminator = " \n"
formatter = TermFormatter("F2 %(asctime)s [%(levelname)s]: %(message)s",
stack_limit=0)
stream_handler2.setFormatter(formatter)
stream_handler2.setLevel(logging.DEBUG)
term_handler = logging.StreamHandler()
term_handler.setFormatter(logging.Formatter("F3 %(asctime)s [%(levelname)s]: %(message)s"))
term_handler.setLevel(logging.DEBUG)
logger= logging.getLogger()
logger.addHandler(stream_handler2)
logger.addHandler(stream_handler)
logger.addHandler(term_handler)
logger.error('wow!')
try:
raise Exception('oh bad')
except:
logger.exception("very ugly")
输出:
F2 2021-07-04 14:16:42,889 [ERROR]: wow!
F1 2021-07-04 14:16:42,889 [ERROR]: wow!
F3 2021-07-04 14:16:42,889 [ERROR]: wow!
F2 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
F1 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
F3 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
我希望在最后三个日志中看到:对于 F1,限制为 2 的堆栈跟踪,对于 F2,显示什么,对于 F3,完整堆栈跟踪是默认行为。我在所有情况下都是第二种情况。
此行为的原因记录在此处:
https://docs.python.org/3/library/logging.html?highlight=exc_text#logging.Formatter.format
”请注意,格式化的异常信息缓存在属性 exc_text 中。这很有用,因为异常信息可以被 pickle 并通过网络发送,但如果您有多个 Formatter,则应小心自定义异常信息格式的子类。在这种情况下,您必须在格式化程序完成格式化后清除缓存值,以便下一个处理事件的格式化程序不会使用缓存值,而是重新计算它。 “
我想将一个记录器流式传输到多个流。更改标准格式有效,但更改 formatException
函数会改变所有格式!
不确定这是否是一项功能,我误解了什么。
请参阅下面的示例,其中我使用标准 logging.Formatter 和带有 limit
变量的修改版:
import logging, io, traceback
class TermFormatter(logging.Formatter):
def __init__(self, *args, stack_limit=1, **kwargs):
super().__init__(*args, **kwargs)
self.stack_limit = stack_limit
def formatException(self, ei):
"""
Format and return the specified exception information as a string.
This default implementation just uses
traceback.print_exception()
"""
sio = io.StringIO()
tb = ei[2]
# See issues #9427, #1553375. Commented out for now.
#if getattr(self, 'fullstack', False):
# traceback.print_stack(tb.tb_frame.f_back, file=sio)
traceback.print_exception(ei[0], ei[1], tb, self.stack_limit, sio)
s = sio.getvalue()
sio.close()
if s[-1:] == "\n":
s = s[:-1]
if self.stack_limit ==0:
return "Hello my friend!"
else:
return s
stream_handler = logging.StreamHandler()
stream_handler.terminator = " \n"
formatter0 = TermFormatter("F1 %(asctime)s [%(levelname)s]: %(message)s",
stack_limit=2)
stream_handler.setFormatter(formatter0)
stream_handler.setLevel(logging.ERROR)
#check the internals of the err logging
stream_handler2 = logging.StreamHandler()
stream_handler2.terminator = " \n"
formatter = TermFormatter("F2 %(asctime)s [%(levelname)s]: %(message)s",
stack_limit=0)
stream_handler2.setFormatter(formatter)
stream_handler2.setLevel(logging.DEBUG)
term_handler = logging.StreamHandler()
term_handler.setFormatter(logging.Formatter("F3 %(asctime)s [%(levelname)s]: %(message)s"))
term_handler.setLevel(logging.DEBUG)
logger= logging.getLogger()
logger.addHandler(stream_handler2)
logger.addHandler(stream_handler)
logger.addHandler(term_handler)
logger.error('wow!')
try:
raise Exception('oh bad')
except:
logger.exception("very ugly")
输出:
F2 2021-07-04 14:16:42,889 [ERROR]: wow!
F1 2021-07-04 14:16:42,889 [ERROR]: wow!
F3 2021-07-04 14:16:42,889 [ERROR]: wow!
F2 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
F1 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
F3 2021-07-04 14:16:42,890 [ERROR]: very ugly
Hello my friend!
我希望在最后三个日志中看到:对于 F1,限制为 2 的堆栈跟踪,对于 F2,显示什么,对于 F3,完整堆栈跟踪是默认行为。我在所有情况下都是第二种情况。
此行为的原因记录在此处:
https://docs.python.org/3/library/logging.html?highlight=exc_text#logging.Formatter.format
”请注意,格式化的异常信息缓存在属性 exc_text 中。这很有用,因为异常信息可以被 pickle 并通过网络发送,但如果您有多个 Formatter,则应小心自定义异常信息格式的子类。在这种情况下,您必须在格式化程序完成格式化后清除缓存值,以便下一个处理事件的格式化程序不会使用缓存值,而是重新计算它。 “