from dataclasses import dataclass KIND_PROBLEM = "problem" KIND_RECOVERY = "recovery" KIND_FLAPPING = "flapping" KIND_REMINDER = "reminder" KIND_SYSTEM = "system" STATE_OK = 0 STATE_CRIT = 2 STATE_NAMES = {0: "OK", 1: "WARN", 2: "CRIT", 3: "UNKNOWN"} HOST_SERVICE_NAME = "Host" HOST_STATE_NAMES = {0: "UP", 2: "DOWN", 3: "UNREACH"} # CRIT vor UNKNOWN vor WARN; passt wegen DOWN=2 und UNREACH=3 auch für Hosts. SEVERITY_RANK = {0: 0, 1: 1, 3: 2, 2: 3} SUPPRESS_DOWNTIME = "downtime" SUPPRESS_MUTE = "mute" SUPPRESS_RECOVERY_OFF = "recovery_aus" SUPPRESS_NOT_REPORTED = "nicht_gemeldet" SUPPRESS_ACK = "bestaetigt" SUPPRESS_HOST_DOWN = "host_down" SUPPRESS_SEND_LIMIT = "sendelimit" AI_PENDING = "pending" AI_DONE = "done" AI_FAILED = "failed" AI_SKIPPED = "skipped" Key = tuple[str, str] def state_name(state: int) -> str: return STATE_NAMES.get(state, "UNKNOWN") def is_host_service(service: str) -> bool: return service == HOST_SERVICE_NAME def display_state(service: str, state: int) -> str: if is_host_service(service): return HOST_STATE_NAMES.get(state, "DOWN") return state_name(state) def severity(state: int) -> int: return SEVERITY_RANK.get(state, SEVERITY_RANK[3]) def ack_holds(state: int, ack_state: int | None) -> bool: return ack_state is not None and severity(state) <= severity(ack_state) @dataclass(frozen=True) class Event: ts: int host: str service: str kind: str state: int output: str = "" suppressed: bool = False suppress_reason: str | None = None previous_state: int | None = None previous_duration: int | None = None since_ts: int | None = None problem_since_ts: int | None = None ai_enabled: bool = True ai_hint: str = "" @property def wants_ai(self) -> bool: return self.kind == KIND_PROBLEM and not self.suppressed and self.ai_enabled @dataclass(frozen=True) class StateRow: host: str service: str state: int output: str last_state_change: int in_downtime: bool flapping: bool reported_state: int flap_reported: bool problem_since: int | None = None reported_at: int = 0 reported_since: int = 0 last_reminder_ts: int = 0 ack_state: int | None = None host_held: bool = False @property def key(self) -> Key: return (self.host, self.service)