majuna/app/models/alarms.py

60 lines
2.2 KiB
Python
Raw Normal View History

2022-04-22 14:01:16 +01:00
import enum
from datetime import datetime
2022-05-16 11:44:03 +01:00
from typing import List, Any
2022-04-22 14:01:16 +01:00
2022-05-17 08:28:37 +01:00
from app.extensions import db
from app.models.activity import Activity
2022-04-22 14:01:16 +01:00
class AlarmState(enum.Enum):
UNKNOWN = 0
OK = 1
WARNING = 2
CRITICAL = 3
2022-06-27 14:58:38 +01:00
@property
def emoji(self) -> str:
if self.name == "OK":
return "😅"
if self.name == "WARNING":
return "😟"
if self.name == "CRITICAL":
return "🚨"
return ""
2022-04-22 14:01:16 +01:00
2022-05-16 11:44:03 +01:00
class Alarm(db.Model): # type: ignore
2022-04-22 14:01:16 +01:00
id = db.Column(db.Integer, primary_key=True)
target = db.Column(db.String(255), nullable=False)
aspect = db.Column(db.String(255), nullable=False)
2022-04-22 14:01:16 +01:00
alarm_state = db.Column(db.Enum(AlarmState), default=AlarmState.UNKNOWN, nullable=False)
state_changed = db.Column(db.DateTime(), nullable=False)
last_updated = db.Column(db.DateTime(), nullable=False)
text = db.Column(db.String(255), nullable=False)
2022-04-22 14:01:16 +01:00
@classmethod
2022-05-16 11:44:03 +01:00
def csv_header(cls) -> List[str]:
return ["id", "target", "alarm_type", "alarm_state", "state_changed", "last_updated", "text"]
2022-04-22 14:01:16 +01:00
2022-05-16 11:44:03 +01:00
def csv_row(self) -> List[Any]:
return [getattr(self, x) for x in self.csv_header()]
2022-04-22 14:01:16 +01:00
2022-05-16 11:44:03 +01:00
def update_state(self, state: AlarmState, text: str) -> None:
if self.alarm_state is None:
self.alarm_state = AlarmState.UNKNOWN
2022-04-22 14:01:16 +01:00
if self.alarm_state != state or self.state_changed is None:
self.state_changed = datetime.utcnow()
activity = Activity(activity_type="alarm_state",
2022-06-27 14:58:38 +01:00
text=f"[{self.aspect}] {self.state.emoji} Alarm state changed from "
f"{self.alarm_state.name} to {state.name} on {self.target}: {text}.")
if (self.alarm_state.name in ["WARNING", "CRITICAL"]
2022-06-27 14:58:38 +01:00
or state.name in ["WARNING", "CRITICAL"]):
# Notifications are only sent on recovery from warning/critical state or on entry
2022-06-27 14:58:38 +01:00
# to warning/critical states. This should reduce alert fatigue.
activity.notify()
db.session.add(activity)
2022-04-22 14:01:16 +01:00
self.alarm_state = state
self.text = text
self.last_updated = datetime.utcnow()