我有一個記錄器,它有一個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. Tomcat將'stderr'內容重定向到'stdout'
- 7. 將子進程stderr重定向到stdout
- 8. 在Python的子進程/ Popen中將stdout重定向到stderr
- 9. 如何將STDOUT和STDERR重定向到變量
- 10. 如何將stderr/stdout重定向到我在C++中的日誌?
- 11. 如何將stderr重定向到Ant JUnit目標中的stdout?
- 12. 在DOSKEY宏中重定向STDERR和STDOUT
- 13. 將stdout和stderr重定向到C++中的文件
- 14. 將stdout和stderr重定向到C++中的單個文件
- 15. 如何將stdout和stderr重定向到文件AND仍只輸出stderr?
- 16. 將stdout和stderr重定向到單獨的文件和屏幕
- 17. nohup和sed,重定向stderr和stdout
- 18. 重定向stdout和stderr的輸出?
- 19. 如何在Python中重定向stderr/stdout的Gtk.Window()調用?
- 20. 將stderr和stdout重定向到dev/null的語法
- 21. 將STDOUT的PHP通知和警告重定向到STDERR
- 22. ksh將stdout和stderr重定向到不同的進程
- 23. 捕捉變量stdout和stderr重定向
- 24. Bash stderr和stdout重定向失敗
- 25. 實時重定向stdout和stderr
- 26. 在Linux系統上,我如何將stdout重定向到stderr?
- 27. 如何將raw_input重定向到stderr而不是stdout
- 28. 如何將STDOUT和STDERR重定向到Perl中的日誌文件?
- 29. PERL無法將stdout和stderr重定向到輸出文件
- 30. 將perl中的STDOUT/STDERR重定向到一個txt文件?
你有寫文件描述符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