我有一个记录器,它有一个RotatingFileHandler
。 我想将所有Stdout
和Stderr
重定向到记录器。 如何做?如何将stdout和stderr重定向到Python中的记录器
回答
如果它是一个全功能的Python系统(即没有C库写入FDS直接作为伊格纳西奥巴斯克斯 - 艾布拉姆斯问),然后根据提示here你也许可以使用的方法:
class LoggerWriter:
def __init__(self, logger, level):
self.logger = logger
self.level = level
def write(self, message):
if message != '\n':
self.logger.log(self.level, message)
和然后将sys.stdout
和sys.stderr
设置为LoggerWriter
实例。
没有足够的评论意见,但我想添加这个工作的版本,以防其他人处于类似的情况。
class LoggerWriter:
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level
def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message != '\n':
self.level(message)
def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level(sys.stderr)
,这看起来是这样的:
log = logging.getLogger('foobar')
sys.stdout = LoggerWriter(log.debug)
sys.stderr = LoggerWriter(log.warning)
由于flush方法,我得到一个奇怪的输出:'警告archan_pylint:18:
平齐加入维奈Sajip的回答是:
class LoggerWriter:
def __init__(self, logger, level):
self.logger = logger
self.level = level
def write(self, message):
if message != '\n':
self.logger.log(self.level, message)
def flush(self):
pass
所有之前的答案似乎都增加了额外的换行符的问题,他们不需要。最适合我的解决方案是从http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/,在那里他展示了如何stdout和标准错误发送到记录器:
import logging
import sys
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
filename="out.log",
filemode='a'
)
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
print "Test to standard out"
raise Exception('Test to standard error')
输出看起来像:
2011-08-14 14:46:20,573:INFO:STDOUT:Test to standard out
2011-08-14 14:46:20,573:ERROR:STDERR:Traceback (most recent call last):
2011-08-14 14:46:20,574:ERROR:STDERR: File "redirect.py", line 33, in
2011-08-14 14:46:20,574:ERROR:STDERR:raise Exception('Test to standard error')
2011-08-14 14:46:20,574:ERROR:STDERR:Exception
2011-08-14 14:46:20,574:ERROR:STDERR::
2011-08-14 14:46:20,574:ERROR:STDERR:Test to standard error
注意self.linebuf =' '是正在处理刷新的地方,而不是执行刷新功能。
此代码已获得许可[GPL](https://www.electricmonk.nl/log/posting-license/)。我不确定它是否可以发布到SO上,这需要与[CC by-sa](https://meta.stackexchange.com/help/licensing)兼容。 – asmeurer
您可以使用redirect_stdout情况管理器:
import logging
from contextlib import redirect_stdout
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.write = lambda msg: logging.info(msg) if msg != '\n' else None
with redirect_stdout(logging):
print('Test')
或类似这样的
import logging
from contextlib import redirect_stdout
logger = logging.getLogger('Meow')
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
fmt='[{name}] {asctime} {levelname}: {message}',
datefmt='%m/%d/%Y %H:%M:%S',
style='{'
)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.write = lambda msg: logger.info(msg) if msg != '\n' else None
with redirect_stdout(logger):
print('Test')
- 1. 将stdout和stderr重定向到函数
- 2. 如何将stderr重定向到Ant中的stderr或stdout?
- 3. 将stdout重定向到Python中的记录器
- 4. 如何重定向stdout和stderr流(Multiplatform)?
- 5. 如何在Java中将子进程stdout/stderr重定向到主进程stdout/stderr?
- 6. 将子进程stderr重定向到stdout
- 7. Tomcat将'stderr'内容重定向到'stdout'
- 8. 如何将STDOUT和STDERR重定向到变量
- 9. 如何将stderr重定向到Ant JUnit目标中的stdout?
- 10. 在DOSKEY宏中重定向STDERR和STDOUT
- 11. 如何将stdout和stderr重定向到文件AND仍只输出stderr?
- 12. 将stdout和stderr重定向到单独的文件和屏幕
- 13. nohup和sed,重定向stderr和stdout
- 14. 重定向stdout和stderr的输出?
- 15. 如何在Python中重定向stderr/stdout的Gtk.Window()调用?
- 16. ksh将stdout和stderr重定向到不同的进程
- 17. 将STDOUT的PHP通知和警告重定向到STDERR
- 18. 将stderr和stdout重定向到dev/null的语法
- 19. Bash stderr和stdout重定向失败
- 20. 实时重定向stdout和stderr
- 21. 捕捉变量stdout和stderr重定向
- 22. 如何将raw_input重定向到stderr而不是stdout
- 23. 如何将STDOUT和STDERR重定向到Perl中的日志文件?
- 24. PERL无法将stdout和stderr重定向到输出文件
- 25. 将perl中的STDOUT/STDERR重定向到一个txt文件?
- 26. 重定向stdout/stderr在C中运行
- 27. 如何将stdout和stderr重定向到管道但保持它们的有序
- 28. 在AIX中将STDERR&STDOUT重定向到/ dev/null失败
- 29. 如何在Jetty中将不同文件中的stderr和stdout重定向?
- 30. 如何使用Unix重定向将滚动文件中的stdout和stderr重定向到
你有写文件描述符1和2的直接外部模块/库? –
@ IgnacioVazquez-Abrams我真的不明白你的意思,但我会尽力解释。我正在使用几个python进程,并且从所有这些进程中,我想将所有'stdout'和'stderr'消息重定向到我的记录器。 – orenma
可能的重复[如何将sys.stdout复制到python中的日志文件?](https://stackoverflow.com/questions/616645/how-do-i-duplicate-sys-stdout-to-a-log -python) – user