From 782c08e9f203284b3d29f1dad0d98bfb72370913 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Tue, 24 Jun 2025 15:45:40 -0600 Subject: [PATCH] Add function wrapper to redirect stdout and stderr to logpipe --- frigate/data_processing/common/face/model.py | 2 ++ frigate/log.py | 27 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/frigate/data_processing/common/face/model.py b/frigate/data_processing/common/face/model.py index 0aeb76792..29bb67592 100644 --- a/frigate/data_processing/common/face/model.py +++ b/frigate/data_processing/common/face/model.py @@ -11,6 +11,7 @@ from scipy import stats from frigate.config import FrigateConfig from frigate.const import MODEL_CACHE_DIR from frigate.embeddings.onnx.face_embedding import ArcfaceEmbedding, FaceNetEmbedding +from frigate.log import redirect_stdout_to_logpipe logger = logging.getLogger(__name__) @@ -37,6 +38,7 @@ class FaceRecognizer(ABC): def classify(self, face_image: np.ndarray) -> tuple[str, float] | None: pass + @redirect_stdout_to_logpipe(__name__, logging.DEBUG) def init_landmark_detector(self) -> None: landmark_model = os.path.join(MODEL_CACHE_DIR, "facedet/landmarkdet.yaml") diff --git a/frigate/log.py b/frigate/log.py index 2e9c781f1..4191f1cdb 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -6,6 +6,7 @@ import sys import threading from collections import deque from enum import Enum +from functools import wraps from logging.handlers import QueueHandler, QueueListener from multiprocessing.managers import SyncManager 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 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""" super().__init__(daemon=False) self.logger = logging.getLogger(log_name) - self.level = logging.ERROR + self.level = level self.deque: Deque[str] = deque(maxlen=100) self.fdRead, self.fdWrite = os.pipe() self.pipeReader = os.fdopen(self.fdRead) @@ -135,3 +136,25 @@ class LogPipe(threading.Thread): def close(self) -> None: """Close the write end of the pipe.""" 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