整理项目文档并优化权限监控与安装脚本
This commit is contained in:
@@ -15,7 +15,7 @@ from sqlalchemy import func, select, desc
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.deps import get_current_user, get_db_session
|
||||
from app.core.permission_monitor import evaluate_permission_system_health, get_permission_monitor
|
||||
from app.core.permission_monitor import get_permission_monitor
|
||||
from app.models.permission_access_log import PermissionAccessLog
|
||||
from app.models.permission_metric_snapshot import PermissionMetricSnapshot
|
||||
from app.models.security_access_log import SecurityAccessLog
|
||||
@@ -31,10 +31,45 @@ router = APIRouter(prefix="/permission-monitoring", tags=["permission-monitoring
|
||||
|
||||
@router.get("/metrics", status_code=status.HTTP_200_OK)
|
||||
async def get_permission_metrics(
|
||||
db: AsyncSession = Depends(get_db_session),
|
||||
_=Depends(get_current_user),
|
||||
hours: int = Query(24, ge=1, le=720),
|
||||
) -> dict:
|
||||
"""从 permission_access_logs 实时聚合权限检查指标"""
|
||||
start_time = datetime.now(timezone.utc) - timedelta(hours=hours)
|
||||
result = await db.execute(
|
||||
select(
|
||||
func.count().label("total_checks"),
|
||||
func.count().filter(PermissionAccessLog.allowed.is_(True)).label("allowed_checks"),
|
||||
func.count().filter(PermissionAccessLog.allowed.is_(False)).label("denied_checks"),
|
||||
func.coalesce(func.sum(PermissionAccessLog.elapsed_ms), 0).label("total_time_ms"),
|
||||
func.coalesce(func.min(PermissionAccessLog.elapsed_ms), 0).label("min_time_ms"),
|
||||
func.coalesce(func.max(PermissionAccessLog.elapsed_ms), 0).label("max_time_ms"),
|
||||
func.coalesce(func.avg(PermissionAccessLog.elapsed_ms), 0).label("avg_time_ms"),
|
||||
).where(PermissionAccessLog.created_at >= start_time)
|
||||
)
|
||||
row = result.one()
|
||||
total = row.total_checks or 0
|
||||
monitor = get_permission_monitor()
|
||||
return monitor.get_metrics()
|
||||
cache_metrics = monitor.metrics.cache_metrics.to_dict()
|
||||
return {
|
||||
"window_hours": hours,
|
||||
"check_metrics": {
|
||||
"total_checks": total,
|
||||
"allowed_checks": row.allowed_checks or 0,
|
||||
"denied_checks": row.denied_checks or 0,
|
||||
"total_time": round(float(row.total_time_ms) / 1000, 3),
|
||||
"min_time": round(float(row.min_time_ms) / 1000, 3),
|
||||
"max_time": round(float(row.max_time_ms) / 1000, 3),
|
||||
"avg_time": round(float(row.avg_time_ms) / 1000, 3),
|
||||
"allow_rate": round(row.allowed_checks / total * 100, 2) if total else 0,
|
||||
"deny_rate": round(row.denied_checks / total * 100, 2) if total else 0,
|
||||
"error_rate": 0,
|
||||
"errors": 0,
|
||||
},
|
||||
"cache_metrics": cache_metrics,
|
||||
"uptime_seconds": monitor.metrics.uptime_seconds,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/cache-stats", status_code=status.HTTP_200_OK)
|
||||
@@ -78,12 +113,54 @@ async def clear_alerts(
|
||||
|
||||
@router.get("/health", status_code=status.HTTP_200_OK)
|
||||
async def permission_system_health(
|
||||
db: AsyncSession = Depends(get_db_session),
|
||||
_=Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""从 DB 聚合最近 1 小时数据评估权限系统健康状态"""
|
||||
start_time = datetime.now(timezone.utc) - timedelta(hours=1)
|
||||
result = await db.execute(
|
||||
select(
|
||||
func.count().label("total"),
|
||||
func.count().filter(PermissionAccessLog.allowed.is_(False)).label("denied"),
|
||||
func.coalesce(func.avg(PermissionAccessLog.elapsed_ms), 0).label("avg_ms"),
|
||||
).where(PermissionAccessLog.created_at >= start_time)
|
||||
)
|
||||
row = result.one()
|
||||
total = row.total or 0
|
||||
avg_ms = float(row.avg_ms)
|
||||
deny_rate = round(row.denied / total * 100, 2) if total else 0
|
||||
|
||||
monitor = get_permission_monitor()
|
||||
metrics = monitor.get_metrics()
|
||||
cache_stats = monitor.get_cache_stats()
|
||||
return evaluate_permission_system_health(metrics, cache_stats)
|
||||
cache_metrics = monitor.metrics.cache_metrics
|
||||
|
||||
health_score = 100
|
||||
issues = []
|
||||
|
||||
if avg_ms > 10:
|
||||
health_score -= 10
|
||||
issues.append("权限检查响应时间过长")
|
||||
if deny_rate > 50:
|
||||
health_score -= 5
|
||||
issues.append("权限拒绝率过高")
|
||||
if (
|
||||
cache_metrics.total_accesses >= 10
|
||||
and cache_metrics.hit_rate < 50
|
||||
):
|
||||
health_score -= 10
|
||||
issues.append("缓存命中率过低")
|
||||
|
||||
return {
|
||||
"status": "healthy" if health_score >= 80 else "degraded" if health_score >= 50 else "unhealthy",
|
||||
"health_score": max(0, health_score),
|
||||
"issues": issues,
|
||||
"last_hour": {
|
||||
"total_checks": total,
|
||||
"denied_checks": row.denied or 0,
|
||||
"deny_rate": deny_rate,
|
||||
"avg_elapsed_ms": round(avg_ms, 2),
|
||||
},
|
||||
"cache_stats": monitor.get_cache_stats(),
|
||||
}
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user