Compare commits

..

2 Commits

Author SHA1 Message Date
Nicolas Mowen
27914fc3b8
Don't run bird classification if model is not downloaded yet (#18474) 2025-05-29 16:15:25 -05:00
Josh Hawkins
c11ca42fb5
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
2025-05-29 09:02:17 -06:00
3 changed files with 18 additions and 5 deletions

View File

@ -44,6 +44,7 @@ from frigate.embeddings import EmbeddingsContext, manage_embeddings
from frigate.events.audio import AudioProcessor from frigate.events.audio import AudioProcessor
from frigate.events.cleanup import EventCleanup from frigate.events.cleanup import EventCleanup
from frigate.events.maintainer import EventProcessor from frigate.events.maintainer import EventProcessor
from frigate.log import _stop_logging
from frigate.models import ( from frigate.models import (
Event, Event,
Export, Export,
@ -771,4 +772,7 @@ class FrigateApp:
shm.close() shm.close()
shm.unlink() shm.unlink()
# exit the mp Manager process
_stop_logging()
os._exit(os.EX_OK) os._exit(os.EX_OK)

View File

@ -97,6 +97,9 @@ class BirdRealTimeProcessor(RealTimeProcessorApi):
line = f.readline() line = f.readline()
def process_frame(self, obj_data, frame): def process_frame(self, obj_data, frame):
if not self.interpreter:
return
if obj_data["label"] != "bird": if obj_data["label"] != "bird":
return return

View File

@ -1,3 +1,4 @@
# In log.py
import atexit import atexit
import logging import logging
import multiprocessing as mp import multiprocessing as mp
@ -6,6 +7,7 @@ import sys
import threading import threading
from collections import deque from collections import deque
from logging.handlers import QueueHandler, QueueListener from logging.handlers import QueueHandler, QueueListener
from queue import Queue
from typing import Deque, Optional from typing import Deque, Optional
from frigate.util.builtin import clean_camera_user_pass from frigate.util.builtin import clean_camera_user_pass
@ -32,12 +34,14 @@ LOG_HANDLER.addFilter(
) )
log_listener: Optional[QueueListener] = None log_listener: Optional[QueueListener] = None
log_queue: Optional[Queue] = None
manager = None
def setup_logging() -> None: def setup_logging() -> None:
global log_listener global log_listener, log_queue, manager
manager = mp.Manager()
log_queue: mp.Queue = mp.Queue() log_queue = manager.Queue()
log_listener = QueueListener(log_queue, LOG_HANDLER, respect_handler_level=True) log_listener = QueueListener(log_queue, LOG_HANDLER, respect_handler_level=True)
atexit.register(_stop_logging) atexit.register(_stop_logging)
@ -53,11 +57,13 @@ def setup_logging() -> None:
def _stop_logging() -> None: def _stop_logging() -> None:
global log_listener global log_listener, manager
if log_listener is not None: if log_listener is not None:
log_listener.stop() log_listener.stop()
log_listener = None 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 # When a multiprocessing.Process exits, python tries to flush stdout and stderr. However, if the