feat(command): improve command logging

This commit is contained in:
2023-03-21 23:08:27 +03:00
parent 265c80f082
commit 34dcb5a991
+37 -12
View File
@@ -1,11 +1,14 @@
__all__ = (
"CommandError",
"CommandLogger",
"CommandExecutor",
)
import logging
import os
import subprocess
import threading
from pathlib import Path
logger = logging.getLogger("command")
@@ -14,7 +17,31 @@ logger = logging.getLogger("command")
class CommandError(RuntimeError):
@property
def output(self):
return self.args[0].decode("utf-8").strip()
return self.args[0]
class CommandLogger(threading.Thread):
def __init__(self, level: int):
super().__init__()
self.daemon = False
self.level = level
self.fdRead, self.fdWrite = os.pipe()
self.pipeReader = os.fdopen(self.fdRead)
self.lines = []
self.start()
def fileno(self):
return self.fdWrite
def run(self):
for line in iter(self.pipeReader.readline, ""):
logger.log(self.level, line.strip("\n"))
self.lines.append(line)
self.pipeReader.close()
def close(self):
os.close(self.fdWrite)
class CommandExecutor:
@@ -25,19 +52,17 @@ class CommandExecutor:
def run(self, basepath: Path):
self._logger.debug(self._command)
out_logger = CommandLogger(logging.TRACE)
err_logger = CommandLogger(logging.TRACE)
try:
result = subprocess.run(
self._command.split(" "),
cwd=basepath,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=out_logger,
stderr=err_logger,
)
self._logstd(result.stdout, logging.TRACE)
self._logstd(result.stderr, logging.TRACE)
finally:
out_logger.close()
err_logger.close()
if result.returncode != 0:
raise CommandError(result.stderr)
@classmethod
def _logstd(cls, data: bytes, level: int):
if data:
output = data.decode("utf-8").strip()
cls._logger.log(level, f"\n{output}\n")
raise CommandError("".join(err_logger.lines or out_logger.lines))