Tôi có một logger có RotatingFileHandler
. Tôi muốn chuyển hướng tất cả Stdout
và Stderr
tới trình ghi nhật ký. Làm thế nào để làm như vậy?Cách chuyển hướng stdout và stderr sang logger bằng Python
Trả lời
Nếu nó là một hệ thống hoàn toàn Python (tức là không có thư viện C bằng văn bản cho FDS trực tiếp, khi Ignacio Vazquez-Abrams được hỏi về) sau đó bạn có thể sử dụng một cách tiếp cận như đề xuất 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)
và sau đó đặt sys.stdout
và sys.stderr
thành LoggerWriter
trường hợp.
cảm ơn bạn, đã làm công việc, nhưng vì lý do nào đó 'stderr' gửi thông điệp của nó mỗi từ một cách riêng biệt, bạn có biết tại sao không? – orenma
@orenma có lẽ vì viết được gọi là từng từ. Bạn có thể điều chỉnh mã ví dụ của tôi để phù hợp với nhu cầu của bạn chặt chẽ hơn. –
Nếu sys.stderr.flush() được gọi sau khi chuyển hướng stderr thì sao? – Moberg
Không đủ đại diện để nhận xét, nhưng tôi muốn thêm phiên bản này làm việc cho tôi trong trường hợp những người khác đang ở trong tình huống tương tự.
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)
và điều này sẽ giống như thế:
log = logging.getLogger('foobar')
sys.stdout = LoggerWriter(log.debug)
sys.stderr = LoggerWriter(log.warning)
Tôi nhận được một đầu ra lạ vì phương pháp tuôn ra: 'warning archan_pylint: 18:
Với tuôn thêm vào Vinay Sajip của câu trả lời:
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
Tất cả các câu trả lời trước dường như có vấn đề thêm dòng mới thêm nơi họ không cần thiết. Các giải pháp phù hợp nhất đối với tôi là từ http://www.electricmonk.nl/log/2011/08/14/redirect-stdout-and-stderr-to-a-logger-in-python/, nơi ông trình bày cách gửi cả stdout và stderr đến logger:
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')
Kết quả trông giống như:
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
Lưu ý rằng self.linebuf = ' 'là nơi tuôn ra đang được xử lý, thay vì thực hiện một chức năng tuôn ra.
Mã này được cấp phép [GPL] (https://www.electricmonk.nl/log/posting-license/). Tôi không chắc liệu nó có thể được đăng trên SO hay không, yêu cầu khả năng tương thích với [CC by-sa] (https://meta.stackexchange.com/help/licensing). – asmeurer
Bạn có thể sử dụng redirect_stdout quản lý bối cảnh:
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')
hay như thế này
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. Chuyển hướng stdout sang logger bằng Python
- 2. Cách chuyển hướng STDOUT và STDERR sang biến số
- 3. Về stdout/stderr chuyển hướng
- 4. Chuyển hướng đầu ra 'in' của Python sang Logger
- 5. Phân chia nhật ký bằng Python giữa stdout và stderr
- 6. Kiểm tra stdout và stderr chuyển hướng trong bash script
- 7. Chuyển hướng stdout và stderr sang ổ cắm cho chương trình shell được phân phối
- 8. log4j chuyển hướng stdout sang DailyRollingFileAppender
- 9. Chuyển hướng stderr phụ tiến trình tới stdout
- 10. Chuyển hướng stdout + stderr trên dịch vụ C# Windows
- 11. Gửi STDERR đến logger
- 12. Piping cả stdout và stderr trong bash?
- 13. Chuyển hướng bash stdout/stderr đến hai địa điểm?
- 14. Làm thế nào để chuyển hướng quá trình con stdout/stderr cho quá trình stdout/stderr chính trong Java?
- 15. Python Subprocess - Chuyển hướng stdout/err đến hai địa điểm
- 16. Bat chuyển hướng stderr sang stdout có hành vi kỳ lạ
- 17. Perl: Chuyển hướng STDOUT sang hai tệp
- 18. Chuyển hướng stdout sang logcat trong Android NDK
- 19. Cách chính xác để chuyển hướng cả stdout và stderr trong bash là gì?
- 20. Apache Spark Stderr và Stdout
- 21. linux g ++ trình biên dịch chuyển hướng stderr và stdout tạo tệp trống
- 22. Redirect stderr để Logger dụ
- 23. Làm cách nào để chuyển hướng STDOUT sang NSTextView?
- 24. đàn áp/chuyển hướng stderr khi gọi python webrowser
- 25. Chụp stdout/stderr với NDK
- 26. chuyển hướng sys.stdout sang nhật ký python
- 27. khởi chạy ứng dụng, chụp stdout và stderr bằng C++
- 28. Lỗi khi chuyển hướng stdout và stderr của tập lệnh powershell
- 29. Làm thế nào để chuyển hướng cả stdout và stderr vào một tập tin
- 30. Sao chép stdout thành stderr
Bạn có module bên ngoài/thư viện mà viết thư cho FD 1 và 2 trực tiếp? –
@ IgnacioVazquez-Abrams Tôi thực sự không hiểu ý bạn là gì nhưng tôi sẽ cố gắng giải thích. Tôi đang sử dụng một số quy trình python, và từ tất cả chúng tôi muốn chuyển hướng tất cả các thông báo 'stdout' và' stderr' tới logger của tôi. – orenma
Có thể trùng lặp [Làm cách nào để sao chép sys.stdout vào tệp nhật ký trong python?] (Https://stackoverflow.com/questions/616645/how-do-i-duplicate-sys-stdout-to-a-log -file-in-python) – user