From c11ca42fb5afae24f417ee03f7505462362bf052 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 29 May 2025 10:02:17 -0500 Subject: [PATCH] Logging bugfix (#18465) * use mp Manager to handle logging queues A Python bug (https://github.com/python/cpython/issues/91555) was preventing logs from the embeddings maintainer process from printing. The bug is fixed in Python 3.14, but a viable workaround is to use the multiprocessing Manager, which better manages mp queues and causes the logging to work correctly. * consolidate * fix typing --- frigate/app.py | 4 ++++ frigate/log.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/frigate/app.py b/frigate/app.py index 703877f6d..cb3da1f54 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -44,6 +44,7 @@ from frigate.embeddings import EmbeddingsContext, manage_embeddings from frigate.events.audio import AudioProcessor from frigate.events.cleanup import EventCleanup from frigate.events.maintainer import EventProcessor +from frigate.log import _stop_logging from frigate.models import ( Event, Export, @@ -771,4 +772,7 @@ class FrigateApp: shm.close() shm.unlink() + # exit the mp Manager process + _stop_logging() + os._exit(os.EX_OK) diff --git a/frigate/log.py b/frigate/log.py index 53e9004f5..096b52215 100644 --- a/frigate/log.py +++ b/frigate/log.py @@ -1,3 +1,4 @@ +# In log.py import atexit import logging import multiprocessing as mp @@ -6,6 +7,7 @@ import sys import threading from collections import deque from logging.handlers import QueueHandler, QueueListener +from queue import Queue from typing import Deque, Optional from frigate.util.builtin import clean_camera_user_pass @@ -32,12 +34,14 @@ LOG_HANDLER.addFilter( ) log_listener: Optional[QueueListener] = None +log_queue: Optional[Queue] = None +manager = None def setup_logging() -> None: - global log_listener - - log_queue: mp.Queue = mp.Queue() + global log_listener, log_queue, manager + manager = mp.Manager() + log_queue = manager.Queue() log_listener = QueueListener(log_queue, LOG_HANDLER, respect_handler_level=True) atexit.register(_stop_logging) @@ -53,11 +57,13 @@ def setup_logging() -> None: def _stop_logging() -> None: - global log_listener - + global log_listener, manager if log_listener is not None: log_listener.stop() log_listener = None + if manager is not None: + manager.shutdown() + manager = None # When a multiprocessing.Process exits, python tries to flush stdout and stderr. However, if the