feat: dashboard top hosts/types, problems 24h, drill-down (d2-2)
- Extend /dashboards/summary; Events filters from query (hostname, severity) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,6 +15,17 @@ from app.services.host_health import DAILY_REPORT_SSH, HEARTBEAT_TYPE, count_sta
|
||||
router = APIRouter(prefix="/dashboards", tags=["dashboards"])
|
||||
|
||||
|
||||
class TopHostItem(BaseModel):
|
||||
host_id: int
|
||||
hostname: str
|
||||
count: int
|
||||
|
||||
|
||||
class TopTypeItem(BaseModel):
|
||||
type: str
|
||||
count: int
|
||||
|
||||
|
||||
class DashboardSummary(BaseModel):
|
||||
events_last_24h: int
|
||||
hosts_total: int
|
||||
@@ -22,7 +33,11 @@ class DashboardSummary(BaseModel):
|
||||
heartbeats_24h: int
|
||||
daily_reports_24h: int
|
||||
problems_open: int
|
||||
problems_opened_24h: int
|
||||
problems_resolved_24h: int
|
||||
severity_24h: dict[str, int]
|
||||
top_hosts: list[TopHostItem]
|
||||
top_event_types: list[TopTypeItem]
|
||||
recent_events: list[EventSummary]
|
||||
|
||||
|
||||
@@ -52,6 +67,40 @@ def dashboard_summary(
|
||||
problems_open = (
|
||||
db.scalar(select(func.count()).select_from(Problem).where(Problem.status == "open")) or 0
|
||||
)
|
||||
problems_opened_24h = (
|
||||
db.scalar(select(func.count()).select_from(Problem).where(Problem.created_at >= since)) or 0
|
||||
)
|
||||
problems_resolved_24h = (
|
||||
db.scalar(
|
||||
select(func.count()).select_from(Problem).where(
|
||||
Problem.status == "resolved",
|
||||
Problem.updated_at >= since,
|
||||
)
|
||||
)
|
||||
or 0
|
||||
)
|
||||
|
||||
top_host_rows = db.execute(
|
||||
select(Host.id, Host.hostname, func.count())
|
||||
.select_from(Event)
|
||||
.join(Host, Event.host_id == Host.id)
|
||||
.where(Event.received_at >= since)
|
||||
.group_by(Host.id, Host.hostname)
|
||||
.order_by(func.count().desc())
|
||||
.limit(10)
|
||||
).all()
|
||||
top_hosts = [
|
||||
TopHostItem(host_id=row[0], hostname=row[1], count=row[2]) for row in top_host_rows
|
||||
]
|
||||
|
||||
top_type_rows = db.execute(
|
||||
select(Event.type, func.count())
|
||||
.where(Event.received_at >= since)
|
||||
.group_by(Event.type)
|
||||
.order_by(func.count().desc())
|
||||
.limit(10)
|
||||
).all()
|
||||
top_event_types = [TopTypeItem(type=row[0], count=row[1]) for row in top_type_rows]
|
||||
|
||||
severity_rows = db.execute(
|
||||
select(Event.severity, func.count())
|
||||
@@ -92,6 +141,10 @@ def dashboard_summary(
|
||||
heartbeats_24h=heartbeats_24h,
|
||||
daily_reports_24h=daily_reports_24h,
|
||||
problems_open=problems_open,
|
||||
problems_opened_24h=problems_opened_24h,
|
||||
problems_resolved_24h=problems_resolved_24h,
|
||||
severity_24h=severity_24h,
|
||||
top_hosts=top_hosts,
|
||||
top_event_types=top_event_types,
|
||||
recent_events=recent_events,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user