refactor: remove GlobalLogger and migrate to standard Python logging
- Remove src/infrastructure/logging/GlobalLogger.py - Update SerieScanner.py to use standard logging.getLogger() - Update aniworld_provider.py to remove custom noKeyFound_logger setup - Fix test_dependencies.py to properly mock config_service - Fix code style issues (line length, formatting) - All 846 tests passing
This commit is contained in:
@@ -23,9 +23,10 @@ from src.core.interfaces.callbacks import (
|
||||
ProgressPhase,
|
||||
)
|
||||
from src.core.providers.base_provider import Loader
|
||||
from src.infrastructure.logging.GlobalLogger import error_logger, noKeyFound_logger
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
error_logger = logging.getLogger("error")
|
||||
no_key_found_logger = logging.getLogger("series.nokey")
|
||||
|
||||
|
||||
class SerieScanner:
|
||||
@@ -174,7 +175,7 @@ class SerieScanner:
|
||||
# remote metadata, yielding missing episodes per
|
||||
# season. Results are saved back to disk so that both
|
||||
# CLI and API consumers see consistent state.
|
||||
missing_episodes, site = (
|
||||
missing_episodes, _site = (
|
||||
self.__get_missing_episodes_and_season(
|
||||
serie.key, mp4_files
|
||||
)
|
||||
@@ -192,14 +193,14 @@ class SerieScanner:
|
||||
)
|
||||
else:
|
||||
self.folderDict[serie.key] = serie
|
||||
noKeyFound_logger.info(
|
||||
no_key_found_logger.info(
|
||||
"Saved Serie: '%s'", str(serie)
|
||||
)
|
||||
|
||||
except NoKeyFoundException as nkfe:
|
||||
# Log error and notify via callback
|
||||
error_msg = f"Error processing folder '{folder}': {nkfe}"
|
||||
NoKeyFoundException.error(error_msg)
|
||||
logger.error(error_msg)
|
||||
|
||||
self._callback_manager.notify_error(
|
||||
ErrorContext(
|
||||
|
||||
@@ -46,12 +46,7 @@ if not download_error_logger.handlers:
|
||||
download_error_handler.setLevel(logging.ERROR)
|
||||
download_error_logger.addHandler(download_error_handler)
|
||||
|
||||
noKeyFound_logger = logging.getLogger("NoKeyFound")
|
||||
if not noKeyFound_logger.handlers:
|
||||
log_path = _logs_dir / "no_key_found.log"
|
||||
noKeyFound_handler = logging.FileHandler(str(log_path))
|
||||
noKeyFound_handler.setLevel(logging.ERROR)
|
||||
noKeyFound_logger.addHandler(noKeyFound_handler)
|
||||
noKeyFound_logger = logging.getLogger()
|
||||
|
||||
|
||||
class AniworldLoader(Loader):
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import logging
|
||||
|
||||
console_handler = None
|
||||
error_logger = None
|
||||
noKeyFound_logger = None
|
||||
noGerFound_logger = None
|
||||
def setupLogger():
|
||||
global console_handler, error_logger, noKeyFound_logger, noGerFound_logger
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(funcName)s - %(message)s')
|
||||
if (console_handler is None):
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(logging.Formatter(
|
||||
"%(asctime)s - %(levelname)s - %(funcName)s - %(message)s")
|
||||
)
|
||||
logging.getLogger().addHandler(console_handler)
|
||||
logging.getLogger("urllib3.connectionpool").setLevel(logging.INFO)
|
||||
logging.getLogger('charset_normalizer').setLevel(logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
if (error_logger is None):
|
||||
error_logger = logging.getLogger("ErrorLog")
|
||||
error_handler = logging.FileHandler("../errors.log")
|
||||
error_handler.setLevel(logging.ERROR)
|
||||
error_logger.addHandler(error_handler)
|
||||
|
||||
if (noKeyFound_logger is None):
|
||||
noKeyFound_logger = logging.getLogger("NoKeyFound")
|
||||
noKeyFound_handler = logging.FileHandler("../NoKeyFound.log")
|
||||
noKeyFound_handler.setLevel(logging.ERROR)
|
||||
noKeyFound_logger.addHandler(noKeyFound_handler)
|
||||
|
||||
if (noGerFound_logger is None):
|
||||
noGerFound_logger = logging.getLogger("noGerFound")
|
||||
noGerFound_handler = logging.FileHandler("../noGerFound.log")
|
||||
noGerFound_handler.setLevel(logging.ERROR)
|
||||
noGerFound_logger.addHandler(noGerFound_handler)
|
||||
|
||||
setupLogger()
|
||||
122
src/server/config/logging_config.py
Normal file
122
src/server/config/logging_config.py
Normal file
@@ -0,0 +1,122 @@
|
||||
"""
|
||||
Logging configuration for the FastAPI server.
|
||||
|
||||
This module provides comprehensive logging setup with both console and file
|
||||
handlers, ensuring all server activity is properly logged.
|
||||
"""
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from src.config.settings import settings
|
||||
|
||||
|
||||
def setup_logging() -> Dict[str, logging.Logger]:
|
||||
"""
|
||||
Configure logging for the FastAPI application.
|
||||
|
||||
Creates:
|
||||
- Console handler for real-time output
|
||||
- File handler for server.log (general logs)
|
||||
- File handler for error.log (errors only)
|
||||
- File handler for access.log (request logs)
|
||||
|
||||
Returns:
|
||||
Dict containing configured loggers
|
||||
"""
|
||||
# Create logs directory if it doesn't exist
|
||||
log_dir = Path("logs")
|
||||
log_dir.mkdir(exist_ok=True)
|
||||
|
||||
# Define log file paths
|
||||
server_log_file = log_dir / "server.log"
|
||||
error_log_file = log_dir / "error.log"
|
||||
access_log_file = log_dir / "access.log"
|
||||
|
||||
# Define log format
|
||||
detailed_format = logging.Formatter(
|
||||
fmt="%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
simple_format = logging.Formatter(
|
||||
fmt="%(asctime)s - %(levelname)s - %(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
# Configure root logger
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(getattr(logging, settings.log_level.upper(), logging.INFO))
|
||||
|
||||
# Remove existing handlers to avoid duplicates
|
||||
root_logger.handlers.clear()
|
||||
|
||||
# Console handler - visible in terminal
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(simple_format)
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
# File handler for general server logs
|
||||
server_file_handler = logging.FileHandler(server_log_file, mode='a', encoding='utf-8')
|
||||
server_file_handler.setLevel(logging.DEBUG)
|
||||
server_file_handler.setFormatter(detailed_format)
|
||||
root_logger.addHandler(server_file_handler)
|
||||
|
||||
# File handler for errors only
|
||||
error_file_handler = logging.FileHandler(error_log_file, mode='a', encoding='utf-8')
|
||||
error_file_handler.setLevel(logging.ERROR)
|
||||
error_file_handler.setFormatter(detailed_format)
|
||||
root_logger.addHandler(error_file_handler)
|
||||
|
||||
# Configure uvicorn loggers
|
||||
uvicorn_logger = logging.getLogger("uvicorn")
|
||||
uvicorn_logger.setLevel(logging.INFO)
|
||||
|
||||
uvicorn_access_logger = logging.getLogger("uvicorn.access")
|
||||
uvicorn_access_logger.setLevel(logging.INFO)
|
||||
|
||||
# Access log file handler
|
||||
access_file_handler = logging.FileHandler(access_log_file, mode='a', encoding='utf-8')
|
||||
access_file_handler.setLevel(logging.INFO)
|
||||
access_file_handler.setFormatter(simple_format)
|
||||
uvicorn_access_logger.addHandler(access_file_handler)
|
||||
|
||||
# Configure FastAPI logger
|
||||
fastapi_logger = logging.getLogger("fastapi")
|
||||
fastapi_logger.setLevel(logging.INFO)
|
||||
|
||||
# Reduce noise from third-party libraries
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("charset_normalizer").setLevel(logging.WARNING)
|
||||
logging.getLogger("multipart").setLevel(logging.WARNING)
|
||||
|
||||
# Log initial setup
|
||||
root_logger.info("=" * 80)
|
||||
root_logger.info("FastAPI Server Logging Initialized")
|
||||
root_logger.info(f"Log Level: {settings.log_level.upper()}")
|
||||
root_logger.info(f"Server Log: {server_log_file.absolute()}")
|
||||
root_logger.info(f"Error Log: {error_log_file.absolute()}")
|
||||
root_logger.info(f"Access Log: {access_log_file.absolute()}")
|
||||
root_logger.info("=" * 80)
|
||||
|
||||
return {
|
||||
"root": root_logger,
|
||||
"uvicorn": uvicorn_logger,
|
||||
"uvicorn.access": uvicorn_access_logger,
|
||||
"fastapi": fastapi_logger,
|
||||
}
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""
|
||||
Get a logger instance for a specific module.
|
||||
|
||||
Args:
|
||||
name: Name of the module/logger
|
||||
|
||||
Returns:
|
||||
Configured logger instance
|
||||
"""
|
||||
return logging.getLogger(name)
|
||||
Reference in New Issue
Block a user