Add storage maintainer and calculate average sizes

This commit is contained in:
Nick Mowen 2022-09-25 09:30:16 -06:00
parent 3186046d45
commit ddf35495f5
2 changed files with 48 additions and 7 deletions

View File

@ -1,23 +1,17 @@
import json
import logging import logging
import multiprocessing as mp import multiprocessing as mp
from multiprocessing.queues import Queue from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event from multiprocessing.synchronize import Event
from multiprocessing.context import Process
import os import os
import signal import signal
import sys import sys
import threading
from logging.handlers import QueueHandler
from typing import Optional from typing import Optional
from types import FrameType from types import FrameType
import traceback import traceback
import yaml
from peewee_migrate import Router from peewee_migrate import Router
from playhouse.sqlite_ext import SqliteExtDatabase from playhouse.sqlite_ext import SqliteExtDatabase
from playhouse.sqliteq import SqliteQueueDatabase from playhouse.sqliteq import SqliteQueueDatabase
from pydantic import ValidationError
from frigate.config import DetectorTypeEnum, FrigateConfig from frigate.config import DetectorTypeEnum, FrigateConfig
from frigate.const import CACHE_DIR, CLIPS_DIR, RECORD_DIR from frigate.const import CACHE_DIR, CLIPS_DIR, RECORD_DIR
@ -32,6 +26,7 @@ from frigate.output import output_frames
from frigate.plus import PlusApi from frigate.plus import PlusApi
from frigate.record import RecordingCleanup, RecordingMaintainer from frigate.record import RecordingCleanup, RecordingMaintainer
from frigate.stats import StatsEmitter, stats_init from frigate.stats import StatsEmitter, stats_init
from frigate.storage import StorageMaintainer
from frigate.version import VERSION from frigate.version import VERSION
from frigate.video import capture_camera, track_camera from frigate.video import capture_camera, track_camera
from frigate.watchdog import FrigateWatchdog from frigate.watchdog import FrigateWatchdog
@ -310,6 +305,12 @@ class FrigateApp:
self.recording_cleanup = RecordingCleanup(self.config, self.stop_event) self.recording_cleanup = RecordingCleanup(self.config, self.stop_event)
self.recording_cleanup.start() self.recording_cleanup.start()
def start_storage_maintainer(self) -> None:
self.storage_maintainer = StorageMaintainer(
self.config, self.stop_event
)
self.storage_maintainer.start()
def start_stats_emitter(self) -> None: def start_stats_emitter(self) -> None:
self.stats_emitter = StatsEmitter( self.stats_emitter = StatsEmitter(
self.config, self.config,
@ -369,6 +370,7 @@ class FrigateApp:
self.start_event_cleanup() self.start_event_cleanup()
self.start_recording_maintainer() self.start_recording_maintainer()
self.start_recording_cleanup() self.start_recording_cleanup()
self.start_storage_maintainer()
self.start_stats_emitter() self.start_stats_emitter()
self.start_watchdog() self.start_watchdog()
# self.zeroconf = broadcast_zeroconf(self.config.mqtt.client_id) # self.zeroconf = broadcast_zeroconf(self.config.mqtt.client_id)

View File

@ -1,6 +1,45 @@
"""Handle storage retention and usage.""" """Handle storage retention and usage."""
import logging
import threading import threading
from peewee import SqliteDatabase, operator, fn, DoesNotExist
from frigate.config import FrigateConfig
from frigate.models import Recordings
logger = logging.getLogger(__name__)
class StorageMaintainer(threading.Thread): class StorageMaintainer(threading.Thread):
"""Maintain frigates recording storage.""" """Maintain frigates recording storage."""
def __init__(self, config: FrigateConfig, stop_event):
threading.Thread.__init__(self)
self.name = "recording_cleanup"
self.config = config
self.stop_event = stop_event
self.avg_segment_sizes = {}
def calculate_camera_segment_sizes(self):
"""Calculate the size of each cameras recording segments over the last hour."""
for camera in self.config.cameras.keys():
if not self.config.cameras[camera].record.enabled:
continue
self.avg_segment_sizes[camera] = (
Recordings.select(fn.AVG(Recordings.segment_size))
.where(Recordings.camera == camera)
.where(Recordings.segment_size != 0)
.scalar()
)
def run(self):
# Check storage consumption every 5 minutes
while not self.stop_event.wait(20):
if not self.avg_segment_sizes:
self.calculate_camera_segment_sizes()
logger.debug(f"Default camera segment sizes: {self.avg_segment_sizes}")
logger.info(f"Exiting storage maintainer...")