"""Logging configuration routes: get/set log levels, filters, components.""" from fastapi import APIRouter from routes.models import LogConfigUpdateRequest, LogFilterUpdateRequest from utils.logger import get_logger, list_components, get_component_stats from utils.log_config import ( load_config as load_log_config, update_component, reload_all_loggers, update_api_filters, reset_to_defaults, update_timestamp_format, ) logger = get_logger('api') router = APIRouter() @router.get("/api/log/config") async def get_log_config(): """Get current logging configuration.""" try: config = load_log_config() logger.debug("Log config requested") return {"success": True, "config": config} except Exception as e: logger.error(f"Failed to get log config: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/config") async def update_log_config(request: LogConfigUpdateRequest): """Update logging configuration.""" try: if request.component: success = update_component( request.component, enabled=request.enabled, enabled_levels=request.enabled_levels ) if not success: return {"success": False, "error": f"Failed to update component {request.component}"} logger.info(f"Log config updated: component={request.component}, enabled_levels={request.enabled_levels}, enabled={request.enabled}") return {"success": True, "message": "Configuration updated"} except Exception as e: logger.error(f"Failed to update log config: {e}") return {"success": False, "error": str(e)} @router.get("/api/log/components") async def get_log_components(): """Get list of all logging components with their descriptions.""" try: components = list_components() stats = get_component_stats() logger.debug("Log components list requested") return { "success": True, "components": components, "stats": stats } except Exception as e: logger.error(f"Failed to get log components: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/reload") async def reload_log_config(): """Reload logging configuration from file.""" try: success = reload_all_loggers() if success: logger.info("Log configuration reloaded") return {"success": True, "message": "Configuration reloaded"} else: return {"success": False, "error": "Failed to reload configuration"} except Exception as e: logger.error(f"Failed to reload log config: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/filters") async def update_log_filters(request: LogFilterUpdateRequest): """Update API request filtering configuration.""" try: success = update_api_filters( exclude_paths=request.exclude_paths, exclude_status=request.exclude_status, include_slow_requests=request.include_slow_requests, slow_threshold_ms=request.slow_threshold_ms ) if success: logger.info(f"API filters updated: {request.dict(exclude_none=True)}") return {"success": True, "message": "Filters updated"} else: return {"success": False, "error": "Failed to update filters"} except Exception as e: logger.error(f"Failed to update filters: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/reset") async def reset_log_config(): """Reset logging configuration to defaults.""" try: success = reset_to_defaults() if success: logger.info("Log configuration reset to defaults") return {"success": True, "message": "Configuration reset to defaults"} else: return {"success": False, "error": "Failed to reset configuration"} except Exception as e: logger.error(f"Failed to reset log config: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/global-level") async def update_global_level_endpoint(level: str, enabled: bool): """Enable or disable a specific log level across all components.""" try: from utils.log_config import update_global_level success = update_global_level(level, enabled) if success: action = "enabled" if enabled else "disabled" logger.info(f"Global level {level} {action} across all components") return {"success": True, "message": f"Level {level} {action} globally"} else: return {"success": False, "error": f"Failed to update global level {level}"} except Exception as e: logger.error(f"Failed to update global level: {e}") return {"success": False, "error": str(e)} @router.post("/api/log/timestamp-format") async def update_timestamp_format_endpoint(format_type: str): """Update timestamp format for all log outputs.""" try: success = update_timestamp_format(format_type) if success: logger.info(f"Timestamp format updated to: {format_type}") return {"success": True, "message": f"Timestamp format set to: {format_type}"} else: return {"success": False, "error": f"Invalid timestamp format: {format_type}"} except Exception as e: logger.error(f"Failed to update timestamp format: {e}") return {"success": False, "error": str(e)} @router.get("/api/log/files/{component}") async def get_log_file(component: str, lines: int = 100): """Get last N lines from a component's log file.""" try: from pathlib import Path log_dir = Path('/app/memory/logs') log_file = log_dir / f'{component.replace(".", "_")}.log' if not log_file.exists(): return {"success": False, "error": "Log file not found"} with open(log_file, 'r', encoding='utf-8') as f: all_lines = f.readlines() last_lines = all_lines[-lines:] if len(all_lines) >= lines else all_lines logger.debug(f"Log file requested: {component} ({lines} lines)") return { "success": True, "component": component, "lines": last_lines, "total_lines": len(all_lines) } except Exception as e: logger.error(f"Failed to read log file for {component}: {e}") return {"success": False, "error": str(e)}