KPIs audit complet: reboot, disque 90%/80%, uptime > 4 mois, filtres cliquables
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
09a039a6fd
commit
2864a15817
@ -25,9 +25,60 @@ async def audit_full_list(request: Request, db=Depends(get_db)):
|
||||
return RedirectResponse(url="/dashboard")
|
||||
|
||||
audits = get_latest_audits(db)
|
||||
filtre = request.query_params.get("filter", "")
|
||||
|
||||
# KPIs
|
||||
kpis = db.execute(text("""
|
||||
SELECT
|
||||
COUNT(*) as total,
|
||||
COUNT(*) FILTER (WHERE reboot_required = true) as needs_reboot,
|
||||
COUNT(*) FILTER (WHERE EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(disk_usage) d
|
||||
WHERE (d->>'pct')::int >= 90
|
||||
)) as disk_critical,
|
||||
COUNT(*) FILTER (WHERE EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(disk_usage) d
|
||||
WHERE (d->>'pct')::int >= 80 AND (d->>'pct')::int < 90
|
||||
)) as disk_warning,
|
||||
COUNT(*) FILTER (WHERE
|
||||
uptime LIKE '%month%' OR uptime LIKE '%year%'
|
||||
OR uptime LIKE '%week%' AND (
|
||||
CASE WHEN uptime ~ '(\d+) week' THEN (substring(uptime from '(\d+) week'))::int ELSE 0 END >= 17
|
||||
)
|
||||
) as uptime_long
|
||||
FROM server_audit_full
|
||||
WHERE status = 'ok'
|
||||
AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
|
||||
""")).fetchone()
|
||||
|
||||
# Filtrer si demande
|
||||
if filtre == "reboot":
|
||||
audits = [a for a in audits if a.reboot_required]
|
||||
elif filtre == "disk_critical":
|
||||
ids = db.execute(text("""
|
||||
SELECT saf.id FROM server_audit_full saf
|
||||
WHERE saf.status = 'ok' AND EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 90
|
||||
) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
|
||||
""")).fetchall()
|
||||
id_set = {r.id for r in ids}
|
||||
audits = [a for a in audits if a.id in id_set]
|
||||
elif filtre == "disk_warning":
|
||||
ids = db.execute(text("""
|
||||
SELECT saf.id FROM server_audit_full saf
|
||||
WHERE saf.status = 'ok' AND EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(saf.disk_usage) d WHERE (d->>'pct')::int >= 80
|
||||
) AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status = 'ok' ORDER BY hostname, audit_date DESC)
|
||||
""")).fetchall()
|
||||
id_set = {r.id for r in ids}
|
||||
audits = [a for a in audits if a.id in id_set]
|
||||
elif filtre == "uptime":
|
||||
audits = [a for a in audits if a.uptime and ("month" in a.uptime or "year" in a.uptime)]
|
||||
|
||||
ctx = base_context(request, db, user)
|
||||
ctx.update({
|
||||
"app_name": APP_NAME, "audits": audits,
|
||||
"app_name": APP_NAME, "audits": audits, "kpis": kpis,
|
||||
"filter": filtre,
|
||||
"msg": request.query_params.get("msg"),
|
||||
})
|
||||
return templates.TemplateResponse("audit_full_list.html", ctx)
|
||||
|
||||
@ -24,6 +24,34 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if kpis %}
|
||||
<div class="flex gap-3 mb-4">
|
||||
<a href="/audit-full" class="card p-3 text-center flex-1 hover:bg-cyber-hover {% if not filter %}ring-1 ring-cyber-accent{% endif %}">
|
||||
<div class="text-lg font-bold text-cyber-accent">{{ kpis.total }}</div>
|
||||
<div class="text-xs text-gray-500">Total</div>
|
||||
</a>
|
||||
<a href="/audit-full?filter=reboot" class="card p-3 text-center flex-1 hover:bg-cyber-hover {% if filter == 'reboot' %}ring-1 ring-cyber-red{% endif %}">
|
||||
<div class="text-lg font-bold {% if kpis.needs_reboot > 0 %}text-cyber-red{% else %}text-cyber-green{% endif %}">{{ kpis.needs_reboot }}</div>
|
||||
<div class="text-xs text-gray-500">Reboot requis</div>
|
||||
</a>
|
||||
<a href="/audit-full?filter=disk_critical" class="card p-3 text-center flex-1 hover:bg-cyber-hover {% if filter == 'disk_critical' %}ring-1 ring-cyber-red{% endif %}">
|
||||
<div class="text-lg font-bold {% if kpis.disk_critical > 0 %}text-cyber-red{% else %}text-cyber-green{% endif %}">{{ kpis.disk_critical }}</div>
|
||||
<div class="text-xs text-gray-500">Disque >= 90%</div>
|
||||
</a>
|
||||
<a href="/audit-full?filter=disk_warning" class="card p-3 text-center flex-1 hover:bg-cyber-hover {% if filter == 'disk_warning' %}ring-1 ring-cyber-yellow{% endif %}">
|
||||
<div class="text-lg font-bold {% if kpis.disk_warning > 0 %}text-cyber-yellow{% else %}text-cyber-green{% endif %}">{{ kpis.disk_warning }}</div>
|
||||
<div class="text-xs text-gray-500">Disque >= 80%</div>
|
||||
</a>
|
||||
<a href="/audit-full?filter=uptime" class="card p-3 text-center flex-1 hover:bg-cyber-hover {% if filter == 'uptime' %}ring-1 ring-cyber-yellow{% endif %}">
|
||||
<div class="text-lg font-bold {% if kpis.uptime_long > 0 %}text-cyber-yellow{% else %}text-cyber-green{% endif %}">{{ kpis.uptime_long }}</div>
|
||||
<div class="text-xs text-gray-500">Uptime > 4 mois</div>
|
||||
</a>
|
||||
</div>
|
||||
{% if filter %}
|
||||
<div class="mb-3 text-xs text-gray-400">Filtre actif : <span class="text-cyber-accent">{{ filter }}</span> ({{ audits|length }} serveurs) — <a href="/audit-full" class="text-cyber-accent underline">Tout voir</a></div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if audits %}
|
||||
<div class="card overflow-x-auto">
|
||||
<table class="w-full table-cyber text-xs">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user