ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python日志记录:禁用堆栈跟踪

2019-11-08 07:55:40  阅读:250  来源: 互联网

标签:traceback python python-logging


有没有一种简单的方法可以在Handler或Formatter中禁用Python 3中的异常堆栈跟踪记录?

我需要在另一个处理程序中进行堆栈跟踪,因此在对Logger的调用中将exc_info = False设置为不可.是否有比定义自己的格式化程序更简单的方法?

解决方法:

禁用每个处理程序回溯输出的最简单选项是添加一个自定义logging.Filter subclass,它会更改记录对象(而不是过滤掉记录).

过滤器只需要将记录的exc_text设置为字符串,即可替换None默认值:

class SetTracebackCacheFilter(logging.Filter):
    """Set the exception cache text on log records to a specific value"""
    def __init__(self, exc_text):
        self.exc_text = exc_text
    def filter(self, record):
        record.exc_text = self.exc_text
        return True

add that filter on your handler,将缓存的文本设置为空字符串:

# do not display tracebacks in messages handled with this handler,
# by setting the traceback cache to an empty string:
handler_with_no_tracebacks.addFilter(SetTracebackCacheFilter(''))

之所以有效,是因为Formatter.format() method将LogRecord.exc_text明确记录为在其中存储格式化回溯的属性:

Note that the formatted exception information is cached in attribute exc_text. This is useful because the exception information can be pickled and sent across the wire, but you should be careful if you have more than one Formatter subclass which customizes the formatting of exception information. In this case, you will have to clear the cached value after a formatter has done its formatting, so that the next formatter to handle the event doesn’t use the cached value but recalculates it afresh.

上面的过滤器使用它来防止完全生成回溯文本.每次将消息传递给处理程序时,都会调用上述过滤器以查看处理程序是否要处理记录实例,然后我们“缓存”一个空的异常文本.

但是,处理程序不会复制日志记录,以后再传递给同一日志记录的任何其他处理程序也会忽略格式化回溯.因此,您还需要在具有上述过滤器的处理程序之后直接配置logger.handlers列表中列出的下一个处理程序:

idx = logger.handlers.index(handler_with_no_tracebacks)
if len(logger.handlers) >= idx:
    # clear the traceback text cache again for further handlers
    logger.handlers[idx + 1].addFilter(SetTracebackCacheFilter(None))

如果您想在任何地方禁用所有回溯输出,那么向所有处理程序或记录器添加自定义过滤器可能会变得很乏味.在这种情况下,另一个选择是在logging.setLogRecordFactory() function中注册自定义记录工厂.只需将记录的exc_text属性设置为空字符串即可:

record_factory = logging.getLogRecordFactory()

def clear_exc_text(*args, **kwargs):
    record = record_factory(*args, **kwargs)
    record.exc_text = ''
    return record

logging.setLogRecordFactory(clear_exc_text)

请注意,默认工厂只是logging.LogRecord class,但是上述功能可以与任何已设置的自定义工厂一起使用.

过滤器和定制记录工厂都没有清除exc_info元组,因此您仍然可以在其他地方访问它.

当然,您也可以创建自己的Handler子类,该类在Handler.handle()中设置和清除exc_text属性:

class NoTracebackHandler(logging.Handler):
    def handle(self, record):
        old, record.exc_text = record.exc_text, ''
        try:
            super().handle(record)
        finally:
            record.exc_text = old

标签:traceback,python,python-logging
来源: https://codeday.me/bug/20191108/2006637.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有