import os import shutil from datetime import datetime, timedelta from src.log_registry import LogRegistry class LogPruner: """ Handles the automated deletion of old and insignificant session logs. Ensures that only whitelisted or significant sessions (based on size/content) are preserved long-term. """ def __init__(self, log_registry: LogRegistry, logs_dir: str) -> None: """ Initializes the LogPruner. Args: log_registry: An instance of LogRegistry to check session data. logs_dir: The path to the directory containing session sub-directories. """ self.log_registry = log_registry self.logs_dir = logs_dir def prune(self, max_age_days: int = 1, min_size_kb: int = 2) -> None: """ Prunes old and small session directories from the logs directory. Deletes session directories that meet the following criteria: 1. The session start time is older than max_age_days. 2. The session name is NOT in the whitelist provided by the LogRegistry. 3. The total size of all files within the session directory is less than min_size_kb. """ now = datetime.now() cutoff_time = now - timedelta(days=max_age_days) # Ensure the base logs directory exists. if not os.path.isdir(self.logs_dir): return # Get sessions that are old and not whitelisted from the registry old_sessions_to_check = self.log_registry.get_old_non_whitelisted_sessions(cutoff_time) # Prune sessions if their size is less than threshold for session_info in old_sessions_to_check: session_id = session_info['session_id'] session_path = session_info['path'] if not session_path: continue # Resolve path resolved_path = session_path if not os.path.isabs(resolved_path): if resolved_path.startswith('logs' + os.sep) or resolved_path.startswith('logs/'): # Resolve relative to the project root (two levels up from self.logs_dir) project_root = os.path.dirname(os.path.dirname(os.path.abspath(self.logs_dir))) resolved_path = os.path.join(project_root, resolved_path) if not os.path.isdir(resolved_path): continue # Calculate total size of files in the directory total_size = 0 try: for entry in os.scandir(resolved_path): if entry.is_file(): total_size += entry.stat().st_size except OSError: continue # Prune if the total size is less than threshold if total_size < (min_size_kb * 1024): try: shutil.rmtree(resolved_path) # Also remove from registry to keep it in sync if session_id in self.log_registry.data: del self.log_registry.data[session_id] except OSError: pass self.log_registry.save_registry()