58 lines
2.3 KiB
Python
58 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.constants import DeviceStatus
|
|
from app.core.exceptions import NotFoundException
|
|
from app.models.mariadb.monitoring import Alert, AlertRule
|
|
from app.repositories.device_repo import DeviceRepository
|
|
from app.repositories.monitoring_repo import AlertRepository, AlertRuleRepository
|
|
from app.schemas.monitoring import AlertRead, AlertRuleCreate, AlertRuleRead, SystemHealthResponse
|
|
|
|
|
|
class MonitoringService:
|
|
def __init__(self, session: AsyncSession):
|
|
self.alert_rule_repo = AlertRuleRepository(session)
|
|
self.alert_repo = AlertRepository(session)
|
|
self.device_repo = DeviceRepository(session)
|
|
|
|
async def create_alert_rule(self, data: AlertRuleCreate, user_id: int) -> AlertRuleRead:
|
|
rule = AlertRule(**data.model_dump(), created_by=user_id)
|
|
rule = await self.alert_rule_repo.create(rule)
|
|
return AlertRuleRead.model_validate(rule)
|
|
|
|
async def list_alert_rules(self) -> list[AlertRuleRead]:
|
|
rules = await self.alert_rule_repo.get_all()
|
|
return [AlertRuleRead.model_validate(r) for r in rules]
|
|
|
|
async def list_active_alerts(self, skip: int = 0, limit: int = 50) -> list[AlertRead]:
|
|
alerts = await self.alert_repo.get_unacknowledged(skip=skip, limit=limit)
|
|
return [AlertRead.model_validate(a) for a in alerts]
|
|
|
|
async def acknowledge_alert(self, alert_id: int, user_id: int) -> AlertRead:
|
|
alert = await self.alert_repo.get_by_id(alert_id)
|
|
if not alert:
|
|
raise NotFoundException("Alert not found")
|
|
alert = await self.alert_repo.update(alert, {
|
|
"is_acknowledged": True,
|
|
"acknowledged_by": user_id,
|
|
"acknowledged_at": datetime.utcnow(),
|
|
})
|
|
return AlertRead.model_validate(alert)
|
|
|
|
async def get_system_health(self) -> SystemHealthResponse:
|
|
active_devices = await self.device_repo.count(filters={"status": DeviceStatus.ONLINE})
|
|
active_alerts = await self.alert_repo.count_active()
|
|
|
|
return SystemHealthResponse(
|
|
status="ok",
|
|
mariadb="connected",
|
|
mongodb="connected",
|
|
redis="connected",
|
|
mqtt="connected",
|
|
active_devices=active_devices,
|
|
active_alerts=active_alerts,
|
|
)
|