优化系统健康评分与缓存监测

This commit is contained in:
Cheng Zhou
2026-06-30 10:43:24 +08:00
parent b25055775e
commit 668e719b6d
10 changed files with 412 additions and 42 deletions
+75 -17
View File
@@ -15,7 +15,11 @@ from sqlalchemy import func, select, desc
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.deps import get_current_user, get_db_session, is_system_admin
from app.core.permission_monitor import get_permission_monitor
from app.core.permission_monitor import (
CACHE_HIT_RATE_HEALTH_MIN_ACCESSES,
CACHE_METRICS_WINDOW_SECONDS,
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
@@ -78,7 +82,7 @@ async def get_permission_metrics(
row = result.one()
total = row.total_checks or 0
monitor = get_permission_monitor()
cache_metrics = monitor.metrics.cache_metrics.to_dict()
cache_metrics = monitor.metrics.cache_metrics.window_stats()
return {
"window_hours": hours,
"check_metrics": {
@@ -178,33 +182,87 @@ async def permission_system_health(
deny_rate = round(row.denied / total * 100, 2) if total else 0
monitor = get_permission_monitor()
cache_metrics = monitor.metrics.cache_metrics
cache_metrics = monitor.metrics.cache_metrics.window_stats()
now_timestamp = datetime.now(timezone.utc).timestamp()
recent_alerts = [
alert
for alert in monitor.get_alerts(limit=1000)
if alert["timestamp"] >= now_timestamp - 3600
]
health_score = 100
issues = []
deductions: dict[str, int] = {
"performance": 0,
"deny_rate": 0,
"cache": 0,
"alerts": 0,
}
issues: list[str] = []
if avg_ms > 200:
deductions["performance"] = 40
elif avg_ms > 50:
deductions["performance"] = 25
elif avg_ms > 10:
deductions["performance"] = 10
if deductions["performance"]:
issues.append(f"权限检查平均响应时间过长({avg_ms:.2f}ms")
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("缓存命中率过低")
deductions["deny_rate"] = 20
elif deny_rate > 20:
deductions["deny_rate"] = 10
if deductions["deny_rate"]:
issues.append(f"权限拒绝率偏高({deny_rate:.2f}%")
cache_sample_sufficient = (
cache_metrics["total_accesses"] >= CACHE_HIT_RATE_HEALTH_MIN_ACCESSES
)
if cache_sample_sufficient:
if cache_metrics["hit_rate"] < 20:
deductions["cache"] = 25
elif cache_metrics["hit_rate"] < 50:
deductions["cache"] = 20
elif cache_metrics["hit_rate"] < 80:
deductions["cache"] = 10
if deductions["cache"]:
issues.append(f"近 1 小时缓存命中率偏低({cache_metrics['hit_rate']:.2f}%")
error_alert_count = sum(alert["level"] == "error" for alert in recent_alerts)
warning_alert_count = sum(alert["level"] == "warning" for alert in recent_alerts)
if error_alert_count:
deductions["alerts"] = 15
issues.append(f"近 1 小时发生 {error_alert_count} 条错误告警")
elif warning_alert_count:
deductions["alerts"] = 5
issues.append(f"近 1 小时发生 {warning_alert_count} 条警告")
health_score = max(0, 100 - sum(deductions.values()))
sample_sufficient = total >= 10
return {
"status": "healthy" if health_score >= 80 else "degraded" if health_score >= 50 else "unhealthy",
"health_score": max(0, health_score),
"health_score": health_score,
"issues": issues,
"sample_sufficient": sample_sufficient,
"score_breakdown": {
"performance": {"weight": 40, "deduction": deductions["performance"]},
"deny_rate": {"weight": 20, "deduction": deductions["deny_rate"]},
"cache": {
"weight": 25,
"deduction": deductions["cache"],
"sample_sufficient": cache_sample_sufficient,
"scope": "sliding_window",
"window_seconds": CACHE_METRICS_WINDOW_SECONDS,
},
"alerts": {"weight": 15, "deduction": deductions["alerts"]},
},
"last_hour": {
"total_checks": total,
"denied_checks": row.denied or 0,
"deny_rate": deny_rate,
"avg_elapsed_ms": round(avg_ms, 2),
"error_alerts": error_alert_count,
"warning_alerts": warning_alert_count,
},
"cache_stats": monitor.get_cache_stats(),
}