pipe_handler.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. """
  2. An handler for the stdout and the stderr output
  3. @author: olivier.massot, 05-2020
  4. """
  5. import logging
  6. import os
  7. import threading
  8. class PipeHandler(threading.Thread):
  9. """ Handle the stdout/stderr output from a Popen object """
  10. def __init__(self, logger_name, default_level=logging.INFO):
  11. """ Setup the object with a logger and a loglevel
  12. and start the thread
  13. """
  14. threading.Thread.__init__(self)
  15. self.daemon = False
  16. self.fdRead, self.fdWrite = os.pipe()
  17. self.pipeReader = os.fdopen(self.fdRead, encoding='utf-8')
  18. self.start()
  19. self.logger = logging.getLogger(logger_name)
  20. self.default_level = default_level
  21. def fileno(self):
  22. """ Return the write file descriptor of the pipe
  23. """
  24. return self.fdWrite
  25. def process(self, line):
  26. """ Process the last line that was read
  27. """
  28. self.logger.log(self.default_level, line)
  29. def run(self):
  30. """ Run the thread, logging everything.
  31. """
  32. try:
  33. for line in iter(self.pipeReader.readline, ''):
  34. self.process(line.strip('\n'))
  35. except UnicodeDecodeError:
  36. self.process(' -- Error while decoding the incoming, unable to log --')
  37. finally:
  38. self.pipeReader.close()
  39. def close(self):
  40. """ Close the write end of the pipe.
  41. """
  42. os.close(self.fdWrite)