将记录器消息存储在字符串中

tru*_*rup 6 python logging

我想将所有中间日志消息(警告,信息,错误)存储到python中的字符串,最后在程序结束时,将所有内容显示为控制台的报告.

我尝试按照http://opensourcehacker.com/2011/02/23/temporarily-capturing-python-logging-output-to-a-string-buffer/中列出的步骤进行操作, 但未成功.

有人能告诉我一个简短,干净的方法吗?

这就是我现在尝试过的:

    log  = logging.getLogger('basic_logger')
    log.setLevel(logging.DEBUG)
    report=""

            memory_handler=logging.handlers.MemoryHandler(1024*20,logging.ERROR,report)
memory_handler.setLevel(logging.DEBUG)
log.addHandler(memory_handler)

log.info("hello world")
memory_handler.flush()
print "report:",report
Run Code Online (Sandbox Code Playgroud)

xjc*_*jcl 20

请注意,涉及所有其他记录器继承的basicConfig记录器的设置属性的解决方案可能是不需要的,因为库也会记录到它。我的用例是一个调用数据处理模块的网站,我只想专门捕获该模块的日志。这还有一个优点是允许记录到文件和终端的现有处理程序持续存在:

import io, logging
from django.http import HttpResponse

log_stream = io.StringIO()
log_handler = logging.StreamHandler(log_stream)
logging.getLogger('algorithm.user_output').addHandler(log_handler)

algorithm()
return HttpResponse(f'<pre>{log_stream.getvalue()}</pre>')
Run Code Online (Sandbox Code Playgroud)

algorithm.py

logger = logging.getLogger(__name__ + '.user_output')  # 'algorithm.user_output'
Run Code Online (Sandbox Code Playgroud)


mha*_*wke 17

它可以像记录到StringIO对象一样简单:

import logging
try:
    from cStringIO import StringIO      # Python 2
except ImportError:
    from io import StringIO

log_stream = StringIO()    
logging.basicConfig(stream=log_stream, level=logging.INFO)

logging.info('hello world')
logging.warning('be careful!')
logging.debug("you won't see this")
logging.error('you will see this')
logging.critical('critical is logged too!')

print(log_stream.getvalue())
Run Code Online (Sandbox Code Playgroud)

产量

INFO:root:hello world
WARNING:root:be careful!
ERROR:root:you will see this
CRITICAL:root:critical is logged too!


如果您只想在WARN,INFO和ERROR级别记录这些消息,则可以使用过滤器进行记录.LevelFilter下面检查每个日志记录的级别号,只允许那些所需级别的记录:

import logging
try:
    from cStringIO import StringIO      # Python 2
except ImportError:
    from io import StringIO

class LevelFilter(logging.Filter):
    def __init__(self, levels):
        self.levels = levels

    def filter(self, record):
        return record.levelno in self.levels

log_stream = StringIO()    
logging.basicConfig(stream=log_stream, level=logging.NOTSET)
logging.getLogger().addFilter(LevelFilter((logging.INFO, logging.WARNING, logging.ERROR)))

logging.info('hello world')
logging.warning('be careful!')
logging.debug("you won't see this")
logging.error('you will see this')
logging.critical('critical is no longer logged!')

print(log_stream.getvalue())
Run Code Online (Sandbox Code Playgroud)

产量

INFO:root:hello world
WARNING:root:be careful!
ERROR:root:you will see this


小智 7

您还可以编写自己的流类。正如https://docs.python.org/2/library/logging.handlers.html所说,仅writeflush用于流式传输。

例子:

import logging

class LogStream(object):
    def __init__(self):
        self.logs = ''

    def write(self, str):
        self.logs += str

    def flush(self):
        pass

    def __str__(self):
        return self.logs

log_stream = LogStream()
logging.basicConfig(stream=log_stream, level=logging.DEBUG)

log = logging.getLogger('test')
log.debug('debugging something')
log.info('informing user')

print(log_stream)
Run Code Online (Sandbox Code Playgroud)

输出:

DEBUG:test:debugging something
INFO:test:informing user
Run Code Online (Sandbox Code Playgroud)