我遇到了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)
任何人都有任何想法可以提供帮助吗?
答案 0 :(得分:0)
我发现了错误,实际上记录器调用了emit,所以你只需要使用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")