diff --git a/frigate/app.py b/frigate/app.py index ca419e045..1d1ee10f3 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -6,7 +6,7 @@ import secrets import shutil from multiprocessing import Queue from multiprocessing.synchronize import Event as MpEvent -from typing import Any, Optional +from typing import Optional import psutil import uvicorn @@ -30,7 +30,6 @@ from frigate.comms.webpush import WebPushClient from frigate.comms.ws import WebSocketClient from frigate.comms.zmq_proxy import ZmqProxy from frigate.config.config import FrigateConfig -from frigate.config.logger import LogLevel from frigate.const import ( CACHE_DIR, CLIPS_DIR, @@ -78,10 +77,8 @@ logger = logging.getLogger(__name__) class FrigateApp: - audio_process: Optional[mp.Process] = None - - # TODO: Fix FrigateConfig usage, so we can properly annotate it here without mypy erroring out. - def __init__(self, config: Any) -> None: + def __init__(self, config: FrigateConfig) -> None: + self.audio_process: Optional[mp.Process] = None self.stop_event: MpEvent = mp.Event() self.detection_queue: Queue = mp.Queue() self.detectors: dict[str, ObjectDetectProcess] = {} @@ -92,7 +89,7 @@ class FrigateApp: self.ptz_metrics: dict[str, PTZMetrics] = {} self.processes: dict[str, int] = {} self.region_grids: dict[str, list[list[dict[str, int]]]] = {} - self.config: FrigateConfig = config + self.config = config def ensure_dirs(self) -> None: for d in [ @@ -388,12 +385,12 @@ class FrigateApp: # create or update region grids for each camera for camera in self.config.cameras.values(): - if camera.name: - self.region_grids[camera.name] = get_camera_regions_grid( - camera.name, - camera.detect, - max(self.config.model.width, self.config.model.height), - ) + assert camera.name is not None + self.region_grids[camera.name] = get_camera_regions_grid( + camera.name, + camera.detect, + max(self.config.model.width, self.config.model.height), + ) def start_camera_processors(self) -> None: for name, config in self.config.cameras.items(): @@ -564,19 +561,6 @@ class FrigateApp: def start(self) -> None: logger.info(f"Starting Frigate ({VERSION})") - # setup logging - logging.getLogger().setLevel(self.config.logger.default.value.upper()) - - log_levels = { - "werkzeug": LogLevel.error, - "ws4py": LogLevel.error, - "httpx": LogLevel.error, - **self.config.logger.logs, - } - - for log, level in log_levels.items(): - logging.getLogger(log).setLevel(level.value.upper()) - # Ensure global state. self.ensure_dirs() diff --git a/frigate/config/config.py b/frigate/config/config.py index 49db0a640..b2373fdcc 100644 --- a/frigate/config/config.py +++ b/frigate/config/config.py @@ -289,7 +289,9 @@ class FrigateConfig(FrigateBaseModel): default_factory=dict, title="Frigate environment variables." ) logger: LoggerConfig = Field( - default_factory=LoggerConfig, title="Logging configuration." + default_factory=LoggerConfig, + title="Logging configuration.", + validate_default=True, ) # Global config diff --git a/frigate/config/logger.py b/frigate/config/logger.py index 8b77067fe..120642042 100644 --- a/frigate/config/logger.py +++ b/frigate/config/logger.py @@ -1,6 +1,8 @@ +import logging from enum import Enum -from pydantic import Field +from pydantic import Field, ValidationInfo, model_validator +from typing_extensions import Self from .base import FrigateBaseModel @@ -20,3 +22,17 @@ class LoggerConfig(FrigateBaseModel): logs: dict[str, LogLevel] = Field( default_factory=dict, title="Log level for specified processes." ) + + @model_validator(mode="after") + def post_validation(self, info: ValidationInfo) -> Self: + if isinstance(info.context, dict) and info.context.get("install", False): + logging.getLogger().setLevel(self.default.value.upper()) + + log_levels = { + "werkzeug": LogLevel.error, + "ws4py": LogLevel.error, + **self.logs, + } + + for log, level in log_levels.items(): + logging.getLogger(log).setLevel(level.value.upper())