Give wishlist modules their own loggers

- add module-level loggers for the wishlist package instead of threading the web server logger through runtime objects
- default wishlist helper runtimes and cleanup helpers to their package logger while still allowing test overrides
- keep web_server.py as a thin caller that no longer injects its logger into wishlist flows
This commit is contained in:
Antti Kettunen 2026-04-28 17:21:57 +03:00
parent d2af9f8bdf
commit f5226bd5b5
No known key found for this signature in database
GPG key ID: C6B2A3D250359BD7
6 changed files with 23 additions and 23 deletions

View file

@ -8,7 +8,7 @@ from typing import Any, Dict, Optional
from utils.logging_config import get_logger
logger = get_logger("wishlist_service")
logger = get_logger("wishlist.payloads")
def sanitize_track_data_for_processing(track_data):

View file

@ -12,6 +12,11 @@ from typing import Any, Callable, Dict
from core.wishlist.payloads import build_failed_track_wishlist_context
from core.wishlist.selection import filter_wishlist_tracks_by_category, sanitize_and_dedupe_wishlist_tracks
from core.wishlist.state import get_wishlist_cycle, set_wishlist_cycle
from utils.logging_config import get_logger
module_logger = get_logger("wishlist.processing")
logger = module_logger
@dataclass
@ -32,9 +37,9 @@ class WishlistAutoProcessingRuntime:
run_full_missing_tracks_process: Callable[[str, str, list[dict[str, Any]]], Any]
get_batch_max_concurrent: Callable[[], int]
get_active_server: Callable[[], str]
logger: Any
current_time_fn: Callable[[], float]
profile_id: int = 1
logger: Any = module_logger
def remove_completed_tracks_from_wishlist(
@ -42,7 +47,7 @@ def remove_completed_tracks_from_wishlist(
download_tasks: Dict[str, Dict[str, Any]],
remove_from_wishlist: Callable[[Dict[str, Any]], Any],
*,
logger,
logger=logger,
) -> int:
"""Remove completed batch tasks from the wishlist."""
removed_count = 0
@ -65,7 +70,7 @@ def add_cancelled_tracks_to_failed_tracks(
download_tasks: Dict[str, Dict[str, Any]],
permanently_failed_tracks: list[Dict[str, Any]],
*,
logger,
logger=logger,
max_process: int = 100,
) -> int:
"""Promote cancelled-but-missing tasks into the failed-track list."""
@ -111,7 +116,7 @@ def recover_uncaptured_failed_tracks(
download_tasks: Dict[str, Dict[str, Any]],
permanently_failed_tracks: list[Dict[str, Any]],
*,
logger,
logger=logger,
) -> int:
"""Recover tasks force-marked failed/not_found so wishlist processing does not skip them."""
recovered_count = 0
@ -164,7 +169,7 @@ def finalize_auto_wishlist_completion(
add_activity_item: Callable[[Any, Any, Any, Any], Any],
automation_engine,
db_factory: Callable[[], Any],
logger,
logger=logger,
) -> Dict[str, Any]:
"""Finalize auto wishlist processing after a batch finishes."""
tracks_added = completion_summary.get('tracks_added', 0)
@ -222,7 +227,7 @@ def remove_tracks_already_in_library(
music_database,
active_server: str,
*,
logger,
logger=logger,
skip_track_fn: Callable[[dict[str, Any]], bool] | None = None,
log_prefix: str = "[Auto-Wishlist]",
) -> int:
@ -296,8 +301,8 @@ class WishlistManualDownloadRuntime:
get_batch_max_concurrent: Callable[[], int]
add_activity_item: Callable[[Any, Any, Any, Any], Any]
active_server: str
logger: Any
profile_id: int
logger: Any = module_logger
def start_manual_wishlist_download_batch(
@ -411,7 +416,7 @@ def cleanup_wishlist_against_library(
profile_id: int,
active_server: str,
*,
logger,
logger=logger,
) -> tuple[Dict[str, Any], int]:
"""Remove wishlist tracks that already exist in the library for one profile."""
try:
@ -617,7 +622,7 @@ def automatic_wishlist_cleanup_after_db_update(
profiles_database=None,
music_database=None,
active_server: str | None = None,
logger,
logger=logger,
) -> int:
"""Remove wishlist entries that already exist in the library after a DB update."""
try:

View file

@ -16,7 +16,7 @@ from database.music_database import get_database
from utils.logging_config import get_logger
logger = get_logger("imports.side_effects")
logger = get_logger("wishlist.resolution")
def _primary_track_artist_name(track_info: Dict[str, Any]) -> str:

View file

@ -12,6 +12,11 @@ from core.wishlist.reporting import build_wishlist_stats_payload
from core.wishlist.selection import prepare_wishlist_tracks_for_display
from core.wishlist.state import get_wishlist_cycle as _get_wishlist_cycle
from core.wishlist.state import set_wishlist_cycle as _set_wishlist_cycle
from utils.logging_config import get_logger
module_logger = get_logger("wishlist.routes")
logger = module_logger
@dataclass
@ -28,8 +33,8 @@ class WishlistRouteRuntime:
is_wishlist_actually_processing: Callable[[], bool]
reset_wishlist_processing_state: Callable[[], None]
add_activity_item: Callable[[Any, Any, Any, Any], Any]
logger: Any
active_server: str
logger: Any = module_logger
get_next_run_seconds: Callable[[str], int] | None = None
thread_factory: Callable[..., Any] = threading.Thread

View file

@ -11,7 +11,7 @@ from database.music_database import get_database
from utils.logging_config import get_logger
logger = get_logger("wishlist_service")
logger = get_logger("wishlist.service")
class WishlistService:

View file

@ -17442,7 +17442,6 @@ def check_and_recover_stuck_flags():
timeout_seconds=stuck_timeout,
now=current_time,
label="Wishlist auto-processing",
logger=logger,
reset_callback=_reset_wishlist_processing_state,
):
return True
@ -17476,7 +17475,6 @@ def is_wishlist_actually_processing():
timeout_seconds=900,
now=current_time,
on_stuck=check_and_recover_stuck_flags,
logger=logger,
)
def is_watchlist_actually_scanning():
@ -17542,7 +17540,6 @@ def _process_wishlist_automatically(automation_id=None):
run_full_missing_tracks_process=_run_full_missing_tracks_process,
get_batch_max_concurrent=_get_batch_max_concurrent,
get_active_server=config_manager.get_active_media_server,
logger=logger,
current_time_fn=time.time,
profile_id=1,
)
@ -18366,7 +18363,6 @@ def _build_wishlist_route_runtime(
is_wishlist_actually_processing=is_actually_processing_fn or is_wishlist_actually_processing,
reset_wishlist_processing_state=reset_wishlist_processing_state or (lambda: None),
add_activity_item=add_activity_item,
logger=logger,
active_server=config_manager.get_active_media_server(),
get_next_run_seconds=get_next_run_seconds,
)
@ -18405,7 +18401,6 @@ def start_wishlist_missing_downloads():
get_batch_max_concurrent=_get_batch_max_concurrent,
add_activity_item=add_activity_item,
active_server=config_manager.get_active_media_server(),
logger=logger,
profile_id=manual_profile_id,
)
@ -18456,7 +18451,6 @@ def cleanup_wishlist():
db,
get_current_profile_id(),
active_server,
logger=logger,
)
return jsonify(payload), status_code
@ -20353,7 +20347,6 @@ def _process_failed_tracks_to_wishlist_exact(batch_id):
batch,
download_tasks,
_check_and_remove_from_wishlist,
logger=logger,
)
# STEP 1: Add cancelled tracks that were missing to permanently_failed_tracks (replicating sync.py)
@ -20364,7 +20357,6 @@ def _process_failed_tracks_to_wishlist_exact(batch_id):
batch,
download_tasks,
permanently_failed_tracks,
logger=logger,
)
logger.warning(f"[Wishlist Processing] Processed {processed_count} cancelled tracks")
@ -20376,7 +20368,6 @@ def _process_failed_tracks_to_wishlist_exact(batch_id):
batch,
download_tasks,
permanently_failed_tracks,
logger=logger,
)
if recovered_count:
logger.warning(f"[Wishlist Processing] Recovered {recovered_count} uncaptured failed tracks for wishlist")
@ -20535,7 +20526,6 @@ def _process_failed_tracks_to_wishlist_exact_with_auto_completion(batch_id):
add_activity_item=add_activity_item,
automation_engine=automation_engine,
db_factory=MusicDatabase,
logger=logger,
)
except Exception as e: