Add function wrapper to redirect stdout and stderr to logpipe

This commit is contained in:
Nicolas Mowen 2025-06-24 15:45:40 -06:00
parent 0e8c504800
commit 782c08e9f2
2 changed files with 27 additions and 2 deletions

View File

@ -11,6 +11,7 @@ from scipy import stats
from frigate.config import FrigateConfig from frigate.config import FrigateConfig
from frigate.const import MODEL_CACHE_DIR from frigate.const import MODEL_CACHE_DIR
from frigate.embeddings.onnx.face_embedding import ArcfaceEmbedding, FaceNetEmbedding from frigate.embeddings.onnx.face_embedding import ArcfaceEmbedding, FaceNetEmbedding
from frigate.log import redirect_stdout_to_logpipe
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -37,6 +38,7 @@ class FaceRecognizer(ABC):
def classify(self, face_image: np.ndarray) -> tuple[str, float] | None: def classify(self, face_image: np.ndarray) -> tuple[str, float] | None:
pass pass
@redirect_stdout_to_logpipe(__name__, logging.DEBUG)
def init_landmark_detector(self) -> None: def init_landmark_detector(self) -> None:
landmark_model = os.path.join(MODEL_CACHE_DIR, "facedet/landmarkdet.yaml") landmark_model = os.path.join(MODEL_CACHE_DIR, "facedet/landmarkdet.yaml")

View File

@ -6,6 +6,7 @@ import sys
import threading import threading
from collections import deque from collections import deque
from enum import Enum from enum import Enum
from functools import wraps
from logging.handlers import QueueHandler, QueueListener from logging.handlers import QueueHandler, QueueListener
from multiprocessing.managers import SyncManager from multiprocessing.managers import SyncManager
from queue import Queue from queue import Queue
@ -102,11 +103,11 @@ os.register_at_fork(after_in_child=reopen_std_streams)
# based on https://codereview.stackexchange.com/a/17959 # based on https://codereview.stackexchange.com/a/17959
class LogPipe(threading.Thread): class LogPipe(threading.Thread):
def __init__(self, log_name: str): def __init__(self, log_name: str, level: int = logging.ERROR):
"""Setup the object with a logger and start the thread""" """Setup the object with a logger and start the thread"""
super().__init__(daemon=False) super().__init__(daemon=False)
self.logger = logging.getLogger(log_name) self.logger = logging.getLogger(log_name)
self.level = logging.ERROR self.level = level
self.deque: Deque[str] = deque(maxlen=100) self.deque: Deque[str] = deque(maxlen=100)
self.fdRead, self.fdWrite = os.pipe() self.fdRead, self.fdWrite = os.pipe()
self.pipeReader = os.fdopen(self.fdRead) self.pipeReader = os.fdopen(self.fdRead)
@ -135,3 +136,25 @@ class LogPipe(threading.Thread):
def close(self) -> None: def close(self) -> None:
"""Close the write end of the pipe.""" """Close the write end of the pipe."""
os.close(self.fdWrite) os.close(self.fdWrite)
def redirect_stdout_to_logpipe(log_name: str, level: int):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
current_log_pipe = LogPipe()
old_stdout = sys.stdout
sys.stdout = current_log_pipe
try:
result = func(*args, **kwargs)
finally:
sys.stdout = old_stdout
current_log_pipe.dump()
return result
return wrapper
return decorator