日志 python 模块上的堆栈溢出



我在使用 python 3 时遇到了问题,我正在尝试将 stdout 和 stderr 记录到日志文件中。我能够用 http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/

弄清楚

这样做的目的是让日志文件和控制台输出正常,同时仅使用 print 语句。(我知道这不是你应该这样做的方式,我正在尝试记录别人的代码)

我想出了这个:

import logging
import sys
import traceback
class StreamToLogger(object):
    def __init__(self, logger, log_level, std):
        self.logger = logger
        self.log_level = log_level
        self.linebuf = ''
        self.std = std
    def write(self, buf):
        for line in buf.rstrip().splitlines():
            self.logger.log(self.log_level, line.rstrip())
            self.std.write(line+"n")
            self.std.flush()
    def flush(self):
        return
logging.basicConfig(
   level=logging.DEBUG,
   format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
   filename="history.log",
   filemode='a'
)
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO, sys.__stdout__)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR, sys.__stderr__)
sys.stderr = sl
try:
    import bot
    #program that I am logging
except Exception as e:
    traceback.print_exc()
    sys.exit(1)

这工作得很好,直到日志文件变得很大,无法处理。

所以我的想法是使用旋转日志文件的东西。不幸的是,我想出的旋转日志文件的实现在程序第一次打印任何内容后立即导致堆栈溢出。

这是新代码:

import logging
import sys
import traceback
import logging.handlers
class StreamToLogger(object):
    def __init__(self, logger, log_level, std, handler):
        self.handler = handler
        self.logger = logger
        self.log_level = log_level
        self.linebuf = ''
        self.std = std
    def write(self, buf):
        for line in buf.rstrip().splitlines():
            self.handler.emit(line)
            #^^STACK OVERFLOW^^
            self.logger.log(self.log_level, line.rstrip())
            self.std.write(line+"n")
            self.std.flush()
    def flush(self):
        return

hand = logging.handlers.TimedRotatingFileHandler("bot.log", when="S", interval=20)
#my attempt at handling

stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO, sys.__stdout__, hand)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR, sys.__stderr__, hand)
sys.stderr = sl
try:
    import bot
except Exception as e:
    traceback.print_exc()
    sys.exit(1)

有人有什么想法可以提供帮助吗?

我发现了错误,实际上发射器是由记录器调用的,所以你只需要使用 streamlogger.addHandler 添加处理程序。

更新的代码

__author__ = 'Girish'
import logging
import sys
import traceback
import logging.handlers

class StreamToLogger(object):
    def __init__(self, logger, log_level, std):
        self.logger = logger
        self.log_level = log_level
        self.linebuf = ''
        self.std = std
    def write(self, buf):
        for line in buf.rstrip().splitlines():
            # ^^STACK OVERFLOW^^
            self.logger.log(self.log_level, line.rstrip())
            self.std.write(line + "n")
    def flush(self):
        self.std.flush()

logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
    filename="history.log",
    filemode='a'
)
hand = logging.handlers.TimedRotatingFileHandler("bot.log", when="S", interval=20)
# my attempt at handling

stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO, sys.__stdout__)
stderr_logger = logging.getLogger('STDERR')
stderr_logger.addHandler(hand) #here
sl = StreamToLogger(stderr_logger, logging.ERROR, sys.__stderr__)
sys.stdout = sl
for i in range(2):
    sl.write("is this working")

最新更新