This commit is contained in:
Matthew Stratford 2021-09-22 19:49:24 +01:00
parent b8c6f087c6
commit a172d03f0e
7 changed files with 237 additions and 221 deletions

View file

@ -2,6 +2,8 @@ from helpers.alert_manager import AlertProvider
from package import BETA from package import BETA
from baps_types.alert import WARNING, Alert from baps_types.alert import WARNING, Alert
# Dummy alert provider for testing basics like UI without needing to actually cause errors. # Dummy alert provider for testing basics like UI without needing to actually cause errors.
class DummyAlertProvider(AlertProvider): class DummyAlertProvider(AlertProvider):
def get_alerts(self): def get_alerts(self):

View file

@ -9,6 +9,7 @@ from baps_types.happytime import happytime
MODULE = "Player" # This should match the log file, so the UI will link to the logs page. MODULE = "Player" # This should match the log file, so the UI will link to the logs page.
class PlayerAlertProvider(AlertProvider): class PlayerAlertProvider(AlertProvider):
_server_state: Dict[str, Any] _server_state: Dict[str, Any]
@ -23,7 +24,8 @@ class PlayerAlertProvider(AlertProvider):
self._player_count = int(self._server_state["num_channels"]) self._player_count = int(self._server_state["num_channels"])
self._states = [None] * self._player_count self._states = [None] * self._player_count
# To simplify monitoring (and allow detection of things going super weird), we are going to read from the state file to work out the alerts. # To simplify monitoring (and allow detection of things going super
# weird), we are going to read from the state file to work out the alerts.
def get_alerts(self): def get_alerts(self):
for channel in range(self._player_count): for channel in range(self._player_count):
with open(resolve_external_file_path("state/Player{}.json".format(channel))) as file: with open(resolve_external_file_path("state/Player{}.json".format(channel))) as file:

View file

@ -9,15 +9,17 @@ from baps_types.happytime import happytime
MODULE = "BAPSicleServer" # This should match the log file, so the UI will link to the logs page. MODULE = "BAPSicleServer" # This should match the log file, so the UI will link to the logs page.
class ServerAlertProvider(AlertProvider): class ServerAlertProvider(AlertProvider):
_state: Dict[str, Any] _state: Dict[str, Any]
# To simplify monitoring (and allow detection of things going super weird), we are going to read from the state file to work out the alerts. # To simplify monitoring (and allow detection of things going super
# weird), we are going to read from the state file to work out the alerts.
def get_alerts(self): def get_alerts(self):
with open(resolve_external_file_path("state/BAPSicleServer.json")) as file: with open(resolve_external_file_path("state/BAPSicleServer.json")) as file:
self._state = json.loads(file.read()) self._state = json.loads(file.read())
funcs = [self._api_key, self._start_time] funcs = [self._api_key, self._start_time]
alerts: List[Alert] = [] alerts: List[Alert] = []

View file

@ -4,6 +4,7 @@ from datetime import datetime
CRITICAL = "Critical" CRITICAL = "Critical"
WARNING = "Warning" WARNING = "Warning"
class Alert: class Alert:
start_time: datetime start_time: datetime
last_time: datetime last_time: datetime
@ -14,7 +15,6 @@ class Alert:
module: str module: str
severity: str severity: str
@property @property
def ui_class(self) -> str: def ui_class(self) -> str:
if self.severity == CRITICAL: if self.severity == CRITICAL:
@ -32,7 +32,6 @@ class Alert:
def cleared(self): def cleared(self):
self.end_time = datetime.now() self.end_time = datetime.now()
@property @property
def __dict__(self): def __dict__(self):
attrs = ["start_time", "last_time", "end_time", "id", "title", "description", "module", "severity"] attrs = ["start_time", "last_time", "end_time", "id", "title", "description", "module", "severity"]

View file

@ -1,3 +1,5 @@
from datetime import datetime from datetime import datetime
def happytime(date: datetime): def happytime(date: datetime):
return date.strftime("%Y-%m-%d %H:%M:%S") return date.strftime("%Y-%m-%d %H:%M:%S")

View file

@ -9,6 +9,7 @@ from sys import modules
from baps_types.alert import CRITICAL, Alert from baps_types.alert import CRITICAL, Alert
import alerts import alerts
def iter_namespace(ns_pkg): def iter_namespace(ns_pkg):
# Specifying the second argument (prefix) to iter_modules makes the # Specifying the second argument (prefix) to iter_modules makes the
# returned name an absolute name instead of a relative one. This allows # returned name an absolute name instead of a relative one. This allows
@ -25,6 +26,7 @@ class AlertProvider():
def get_alerts(self): def get_alerts(self):
return [] return []
class AlertManager(): class AlertManager():
_alerts: List[Alert] _alerts: List[Alert]
_providers: List[AlertProvider] = [] _providers: List[AlertProvider] = []
@ -40,7 +42,10 @@ class AlertManager():
} }
for provider in providers: for provider in providers:
classes: List[Any] = [mem[1] for mem in getmembers(modules[provider], isclass) if mem[1].__module__ == modules[provider].__name__] classes: List[Any] = [
mem[1] for mem in getmembers(
modules[provider],
isclass) if mem[1].__module__ == modules[provider].__name__]
if (len(classes) != 1): if (len(classes) != 1):
print(classes) print(classes)
@ -48,7 +53,6 @@ class AlertManager():
self._providers.append(classes[0]()) self._providers.append(classes[0]())
print("Discovered alert providers: ", self._providers) print("Discovered alert providers: ", self._providers)
def poll_alerts(self): def poll_alerts(self):
@ -76,7 +80,7 @@ class AlertManager():
new_alerts[index] = None # We're going to merge the existing and new, so clear the new one out. new_alerts[index] = None # We're going to merge the existing and new, so clear the new one out.
found = True found = True
break break
if found == False: if not found:
# The existing alert is gone, mark it as ended. # The existing alert is gone, mark it as ended.
existing.cleared() existing.cleared()

View file

@ -99,6 +99,7 @@ def render_template(file, data, status=200):
def _filter_happytime(date): def _filter_happytime(date):
return happytime(date) return happytime(date)
env.filters["happytime"] = _filter_happytime env.filters["happytime"] = _filter_happytime
logger: LoggingManager logger: LoggingManager
@ -114,14 +115,17 @@ player_from_q: List[Queue] = []
@app.exception(NotFound) @app.exception(NotFound)
def page_not_found(request, e: Any): def page_not_found(request, e: Any):
data = {"ui_page": "404", "ui_title": "404", "code": 404, "title": "Page Not Found", "message": "Looks like you fell off the tip of the iceberg." } data = {"ui_page": "404", "ui_title": "404", "code": 404, "title": "Page Not Found",
"message": "Looks like you fell off the tip of the iceberg."}
return render_template("error.html", data=data, status=404) return render_template("error.html", data=data, status=404)
@app.exception(Exception, ServerError) # Future use.
def server_error(request, e: Exception): def error_page(code=500, ui_title="500", title="Something went very wrong!",
data = {"ui_page": "500", "ui_title": "500", "code": 500, "title": "Something went very wrong!", "message": "Looks like the server fell over. Try viewing the WebServer logs for more details." } message="Looks like the server fell over. Try viewing the WebServer logs for more details."):
data = {"ui_page": ui_title, "ui_title": ui_title, "code": code, "title": title, "message": message}
return render_template("error.html", data=data, status=500) return render_template("error.html", data=data, status=500)
@app.route("/") @app.route("/")
def ui_index(request): def ui_index(request):
config = server_state.get() config = server_state.get()
@ -148,6 +152,7 @@ def ui_status(request):
"ui_page": "status", "ui_title": "Status"} "ui_page": "status", "ui_title": "Status"}
return render_template("status.html", data=data) return render_template("status.html", data=data)
@app.route("/alerts") @app.route("/alerts")
def ui_alerts(request): def ui_alerts(request):
data = { data = {