"""监控接口只暴露固定白名单,不传输内部异常或连接配置。""" from datetime import datetime from typing import Annotated, Literal from pydantic import BaseModel, BeforeValidator, ConfigDict, Field from app.core.response import PageQuery Status = Literal["normal", "warning", "error", "unknown"] Hours = Annotated[ Literal[1, 24, 168], BeforeValidator(lambda value: int(value) if value in ("1", "24", "168") else value), ] class MonitorWindow(BaseModel): hours: Hours = 1 end: datetime | None = None route: str | None = Field(default=None, max_length=256) class EventQuery(PageQuery): hours: Hours = 24 end: datetime | None = None route: str | None = Field(default=None, max_length=256) kind: Literal["HEALTH", "REQUEST_ERROR", "SLOW_REQUEST", "RUNTIME_ERROR"] | None = None request_id: str | None = Field(default=None, pattern=r"^[a-f0-9]{32}$") active_only: bool = False class EventOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: int instance_id: str kind: str code: str component: str level: str message: str request_id: str | None = None method: str | None = None route: str | None = None status_code: int | None = None duration_ms: float | None = None batch_no: str | None = None first_seen: datetime last_seen: datetime occurrences: int resolved_at: datetime | None = None class DependencyOut(BaseModel): name: str status: Status message: str checked_at: datetime | None = None duration_ms: float | None = None class OverviewOut(BaseModel): status: Status environment: str version: str instance_id: str uptime_seconds: int collected_at: datetime | None last_persisted_at: datetime | None collection_status: Status collection_message: str resources: dict requests: dict dependencies: list[DependencyOut] alerts: list[EventOut] tasks: dict dropped_events: int retention_days: int = 7