236 lines
8.0 KiB
Python
236 lines
8.0 KiB
Python
"""
|
|
Monitoring and Optimization Routes
|
|
Endpoints for performance monitoring, cache optimization, and system health
|
|
"""
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel
|
|
from typing import Dict, Optional
|
|
import logging
|
|
from app.modules.cache_optimizer import CacheOptimizer
|
|
from app.modules.performance_monitor import PerformanceMonitor
|
|
from app.modules.knowledge_base import KnowledgeBase
|
|
from app.modules.cache_manager import CacheManager
|
|
|
|
router = APIRouter(prefix="/api/monitoring", tags=["Monitoring"])
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Initialize modules
|
|
_cache_manager = CacheManager()
|
|
_cache_optimizer = CacheOptimizer(_cache_manager)
|
|
_performance_monitor = PerformanceMonitor()
|
|
_knowledge_base = KnowledgeBase()
|
|
|
|
|
|
@router.get("/cache/stats")
|
|
async def get_cache_stats() -> Dict:
|
|
"""Get current cache statistics"""
|
|
try:
|
|
stats = _cache_optimizer.get_cache_stats()
|
|
return {
|
|
"status": "success",
|
|
"cache_stats": stats,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting cache stats: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/cache/optimization")
|
|
async def get_cache_optimization() -> Dict:
|
|
"""Get cache optimization recommendations"""
|
|
try:
|
|
recommendations = _cache_optimizer.optimize_cache_settings()
|
|
return {
|
|
"status": "success",
|
|
"recommendations": recommendations,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting cache recommendations: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.post("/cache/clear")
|
|
async def clear_cache(pattern: Optional[str] = None) -> Dict:
|
|
"""Clear cache"""
|
|
try:
|
|
if pattern:
|
|
count = _cache_optimizer.invalidate_pattern(pattern)
|
|
message = f"Invalidated {count} cache keys matching {pattern}"
|
|
else:
|
|
_cache_optimizer.clear_l1_cache()
|
|
count = _cache_manager.clear_prefix("*")
|
|
message = f"Cleared all cache ({count} keys)"
|
|
|
|
return {
|
|
"status": "success",
|
|
"message": message,
|
|
"items_cleared": count,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error clearing cache: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/performance/summary")
|
|
async def get_performance_summary() -> Dict:
|
|
"""Get overall performance summary"""
|
|
try:
|
|
summary = _performance_monitor.get_performance_summary()
|
|
return {
|
|
"status": "success",
|
|
"performance": summary,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting performance summary: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/performance/endpoints")
|
|
async def get_endpoint_stats(endpoint: Optional[str] = None) -> Dict:
|
|
"""Get performance stats for endpoints"""
|
|
try:
|
|
stats = _performance_monitor.get_endpoint_stats(endpoint)
|
|
return {
|
|
"status": "success",
|
|
"endpoint_stats": stats,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting endpoint stats: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/performance/throughput")
|
|
async def get_throughput(window_seconds: int = 60) -> Dict:
|
|
"""Get current throughput"""
|
|
try:
|
|
throughput = _performance_monitor.get_throughput(window_seconds)
|
|
return {
|
|
"status": "success",
|
|
"throughput": throughput,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting throughput: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/alerts")
|
|
async def get_alerts(severity: Optional[str] = None, limit: int = 10) -> Dict:
|
|
"""Get system alerts"""
|
|
try:
|
|
alerts = _performance_monitor.get_alerts(severity, limit)
|
|
return {
|
|
"status": "success",
|
|
"alerts": alerts,
|
|
"total": len(alerts),
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting alerts: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/knowledge/stats")
|
|
async def get_knowledge_stats() -> Dict:
|
|
"""Get knowledge base statistics"""
|
|
try:
|
|
stats = _knowledge_base.get_statistics()
|
|
return {
|
|
"status": "success",
|
|
"statistics": stats,
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting knowledge stats: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/knowledge/categories")
|
|
async def get_knowledge_categories() -> Dict:
|
|
"""Get all knowledge categories"""
|
|
try:
|
|
categories = _knowledge_base.get_all_categories()
|
|
return {
|
|
"status": "success",
|
|
"categories": categories,
|
|
"count": len(categories),
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting categories: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/knowledge/search")
|
|
async def search_knowledge(query: str, category: Optional[str] = None) -> Dict:
|
|
"""Search knowledge base"""
|
|
try:
|
|
if category:
|
|
results = _knowledge_base.search_by_category(category)
|
|
else:
|
|
results = _knowledge_base.search_by_keyword(query)
|
|
|
|
results_data = [
|
|
{
|
|
'id': r.id,
|
|
'title': r.title,
|
|
'category': r.category,
|
|
'tags': r.tags,
|
|
'preview': r.content[:150] + '...' if len(r.content) > 150 else r.content
|
|
}
|
|
for r in results[:10]
|
|
]
|
|
|
|
return {
|
|
"status": "success",
|
|
"query": query,
|
|
"results": results_data,
|
|
"total": len(results_data),
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error searching knowledge: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/knowledge/recommendations")
|
|
async def get_knowledge_recommendations(query: str) -> Dict:
|
|
"""Get knowledge recommendations for a query"""
|
|
try:
|
|
recommendations = _knowledge_base.get_recommendations_for_query(query)
|
|
return {
|
|
"status": "success",
|
|
"query": query,
|
|
"recommendations": recommendations,
|
|
"total": len(recommendations),
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"❌ Error getting recommendations: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Error: {str(e)}")
|
|
|
|
|
|
@router.get("/health")
|
|
async def health_check() -> Dict:
|
|
"""Health check for monitoring system"""
|
|
cache_health = _cache_optimizer.health_check()
|
|
perf_health = _performance_monitor.health_check()
|
|
kb_health = _knowledge_base.health_check()
|
|
|
|
return {
|
|
"status": "healthy",
|
|
"components": {
|
|
"cache_optimizer": cache_health,
|
|
"performance_monitor": perf_health,
|
|
"knowledge_base": kb_health
|
|
},
|
|
"timestamp": __import__("datetime").datetime.now().isoformat()
|
|
}
|