mirror of
https://forgejo.altau.su/lego/lego-monitoring.git
synced 2026-03-10 04:41:10 +00:00
move existing stuff to archive dir (for now)
This commit is contained in:
parent
ae1204449c
commit
4fc491f61a
32 changed files with 0 additions and 0 deletions
73
archive-arch/alerting/alerts.py
Normal file
73
archive-arch/alerting/alerts.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
import nio
|
||||
|
||||
from alerting.enum import AlertType, Severity
|
||||
from misc import cvars
|
||||
from misc.config import get_config
|
||||
|
||||
|
||||
@dataclass
|
||||
class Alert:
|
||||
alert_type: AlertType
|
||||
message: str
|
||||
severity: Severity
|
||||
html_message: Optional[str] = None
|
||||
|
||||
|
||||
async def get_client() -> nio.AsyncClient:
|
||||
"""
|
||||
Returns a Matrix client.
|
||||
It is better to call get_client once and use it for multiple send_alert calls
|
||||
"""
|
||||
matrix_cfg = cvars.config.get().matrix
|
||||
client = nio.AsyncClient(matrix_cfg.homeserver)
|
||||
client.access_token = matrix_cfg.access_token
|
||||
client.user_id = matrix_cfg.user_id
|
||||
client.device_id = matrix_cfg.device_id
|
||||
return client
|
||||
|
||||
|
||||
def format_message(alert: Alert) -> str:
|
||||
match alert.severity:
|
||||
case Severity.INFO:
|
||||
severity_emoji = "ℹ️"
|
||||
case Severity.WARNING:
|
||||
severity_emoji = "⚠️"
|
||||
case Severity.CRITICAL:
|
||||
severity_emoji = "🆘"
|
||||
message = f"{severity_emoji} {alert.alert_type} Alert\n{alert.message}"
|
||||
if alert.html_message:
|
||||
html_message = f"{severity_emoji} {alert.alert_type} Alert<br>{alert.html_message}"
|
||||
return message, html_message
|
||||
else:
|
||||
return message, None
|
||||
|
||||
|
||||
async def send_alert(alert: Alert) -> None:
|
||||
try:
|
||||
client = cvars.matrix_client.get()
|
||||
except LookupError: # being called standalone
|
||||
cvars.config.set(get_config())
|
||||
temp_client = True
|
||||
client = await get_client()
|
||||
cvars.matrix_client.set(client)
|
||||
else:
|
||||
temp_client = False
|
||||
room_id = cvars.config.get().matrix.room_id
|
||||
message, html_message = format_message(alert)
|
||||
content = {
|
||||
"msgtype": "m.text",
|
||||
"body": message,
|
||||
}
|
||||
if html_message:
|
||||
content["format"] = "org.matrix.custom.html"
|
||||
content["formatted_body"] = html_message
|
||||
await client.room_send(
|
||||
room_id=room_id,
|
||||
message_type="m.room.message",
|
||||
content=content,
|
||||
)
|
||||
if temp_client:
|
||||
await client.close()
|
||||
53
archive-arch/alerting/delayed.py
Normal file
53
archive-arch/alerting/delayed.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import tempfile
|
||||
from dataclasses import asdict
|
||||
|
||||
from alerting.alerts import Alert, send_alert
|
||||
from misc.common import TMP_DIR
|
||||
|
||||
handler_lock = asyncio.Lock()
|
||||
|
||||
|
||||
async def handler():
|
||||
"""
|
||||
Is executed when SIGUSR1 is received.
|
||||
Checks for new alerts, sends them in 10 seconds
|
||||
"""
|
||||
alert_counts: list[list] = []
|
||||
async with handler_lock:
|
||||
await asyncio.sleep(10)
|
||||
alert_files = [f for f in os.listdir(str(TMP_DIR)) if f.startswith("alert-")]
|
||||
for fname in alert_files:
|
||||
fpath = str(TMP_DIR / fname)
|
||||
with open(fpath) as f:
|
||||
alert = Alert(**json.load(f))
|
||||
for pair in alert_counts:
|
||||
if alert == pair[0]:
|
||||
pair[1] += 1
|
||||
break
|
||||
else:
|
||||
alert_counts.append([alert, 1])
|
||||
os.unlink(fpath)
|
||||
for pair in alert_counts:
|
||||
if pair[1] > 1:
|
||||
pair[0].message += f" ({pair[1]} times)"
|
||||
pair[0].html_message += f" ({pair[1]} times)"
|
||||
logging.info(f"Sending delayed alert of type {pair[0].alert_type}")
|
||||
await send_alert(pair[0])
|
||||
|
||||
|
||||
def send_alert_delayed(alert: Alert) -> None:
|
||||
"""
|
||||
Put alert into a temporary file to be sent later.
|
||||
Intended as an IPC mechanism
|
||||
"""
|
||||
alert_json = json.dumps(asdict(alert))
|
||||
with tempfile.NamedTemporaryFile(prefix="alert-", dir=str(TMP_DIR), delete=False) as af:
|
||||
af.write(alert_json.encode())
|
||||
with open(str(TMP_DIR / "pid")) as pf:
|
||||
pid = int(pf.read().strip())
|
||||
os.kill(pid, signal.SIGUSR1)
|
||||
22
archive-arch/alerting/enum.py
Normal file
22
archive-arch/alerting/enum.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from enum import StrEnum
|
||||
|
||||
|
||||
class AlertType(StrEnum):
|
||||
TEST = "TEST"
|
||||
ERROR = "ERROR"
|
||||
RAM = "RAM"
|
||||
CPU = "CPU"
|
||||
TEMP = "TEMP"
|
||||
VULN = "VULN"
|
||||
LOGIN = "LOGIN"
|
||||
SMART = "SMART" # TODO
|
||||
RAID = "RAID"
|
||||
DISKS = "DISKS"
|
||||
UPS = "UPS"
|
||||
UPDATE = "UPDATE"
|
||||
|
||||
|
||||
class Severity(StrEnum):
|
||||
INFO = "INFO"
|
||||
WARNING = "WARNING"
|
||||
CRITICAL = "CRITICAL"
|
||||
46
archive-arch/alerting/login.py
Executable file
46
archive-arch/alerting/login.py
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import getpass
|
||||
import json
|
||||
import os
|
||||
|
||||
from nio import AsyncClient, LoginResponse
|
||||
|
||||
from misc.common import CONFIG_FILE
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
try:
|
||||
with open(CONFIG_FILE) as f:
|
||||
cfg = json.load(f)
|
||||
if "matrix" in cfg:
|
||||
print(f"Creds already configured in {CONFIG_FILE}")
|
||||
raise SystemExit
|
||||
cfg["matrix"] = {}
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
open(CONFIG_FILE, "w").close()
|
||||
os.chmod(CONFIG_FILE, 0o600)
|
||||
cfg = {"matrix": {}}
|
||||
|
||||
homeserver = input("Homeserver: ")
|
||||
user_id = input("User ID: ")
|
||||
device_name = input("Device name: ")
|
||||
room_id = input("Room ID: ")
|
||||
password = getpass.getpass()
|
||||
|
||||
client = AsyncClient(homeserver, user_id)
|
||||
resp = await client.login(password, device_name=device_name)
|
||||
await client.close()
|
||||
|
||||
if isinstance(resp, LoginResponse):
|
||||
cfg["matrix"]["homeserver"] = homeserver
|
||||
cfg["matrix"]["user_id"] = resp.user_id
|
||||
cfg["matrix"]["device_id"] = resp.device_id
|
||||
cfg["matrix"]["access_token"] = resp.access_token
|
||||
cfg["matrix"]["room_id"] = room_id
|
||||
|
||||
with open(CONFIG_FILE, "w") as f:
|
||||
json.dump(cfg, f, indent=2)
|
||||
print(f"Logged in as {resp.user_id}. Credentials saved to {CONFIG_FILE}")
|
||||
else:
|
||||
raise Exception(f"Failed to log in: {resp}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue