mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									9b7d4d0a8f
								
							
						
					
					
						commit
						c11ca42fb5
					
				@ -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)
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user