将C模块的stderr输出重定向到自定义python writer

时间:2019-02-19 14:02:25

标签: python

我想捕获程序的stderr输出并应用一些自定义的预处理,然后再将其显示在终端上。

stderr由我不控制的某些C / C ++模块编写。

with redirect_stderr():
  # foo() execute `std::cerr << "some log" << std::endl`
  some_module.foo()
  # I would like to redirect the `std::cerr` string to MyCustomLogger.write

我当前的代码将stderr重定向到一些临时文件,以后我可以阅读。

@contextlib.contextmanager
def redirect_stderr():
  """Context manager which redirect all stderr output to."""
  # Original stderr file descriptor id
  stderr_fd = sys.stderr.fileno()
  # Duplcate original file descriptor to be able to restore it
  dup_stderr_fd = os.dup(stderr_fd)

  # Create new file descriptor
  tfile = tempfile.TemporaryFile(mode='w+b')

  def _redirect_stream(to_fd):
    # Flush and close original file descriptor
    sys.stderr.close()
    # Use the tempfile instead of stderr
    os.dup2(to_fd, stderr_fd)
    # Tell Python to use the new file to write to stderr
    sys.stderr = os.fdopen(stderr_fd, 'w')

  try:
    # Replace stderr by the new temp file
    _redirect_stream(tfile.fileno())
    yield
  finally:
    # Replace the new temp file by the original stderr
    _redirect_stream(dup_stderr_fd)

  tfile.flush()
  tfile.seek(0, io.SEEK_SET)
  print(tfile.read())

是否可以在生成输出字符串后立即对其进行处理(而不必等待上下文管理器的结尾)?

可能有一个线程每隔X秒钟定期查看tfile,但是我想知道是否有更好的解决方案?

0 个答案:

没有答案