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.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)

View File

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

View File

@ -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