feat: add uptime checking script for scheduled reports
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
import urllib.request
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
|
||||||
|
def check_uptime():
|
||||||
|
try:
|
||||||
|
# Fetch status page to extract monitor IDs and names
|
||||||
|
req = urllib.request.Request(
|
||||||
|
"https://uptime.ginnoir.com/status/default",
|
||||||
|
headers={"User-Agent": "Mozilla/5.0"}
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req) as response:
|
||||||
|
html = response.read().decode('utf-8')
|
||||||
|
|
||||||
|
# Regex to find monitor mapping: {'id':29,'name':'auth.ginnoir.com','sendUrl':0,'type':'http'}
|
||||||
|
monitors = {}
|
||||||
|
matches = re.findall(r"\{'id':(\d+),'name':'([^']+)','sendUrl':\d+,'type':'[^']+'\}", html)
|
||||||
|
for mon_id, mon_name in matches:
|
||||||
|
monitors[int(mon_id)] = mon_name
|
||||||
|
|
||||||
|
if not monitors:
|
||||||
|
print("No monitors found in status page HTML.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Fetch heartbeats
|
||||||
|
req_hb = urllib.request.Request(
|
||||||
|
"https://uptime.ginnoir.com/api/status-page/heartbeat/default",
|
||||||
|
headers={"User-Agent": "Mozilla/5.0"}
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req_hb) as response:
|
||||||
|
hb_data = json.loads(response.read().decode('utf-8'))
|
||||||
|
|
||||||
|
hb_list = hb_data.get("heartbeatList", {})
|
||||||
|
|
||||||
|
up_count = 0
|
||||||
|
down_count = 0
|
||||||
|
other_count = 0
|
||||||
|
|
||||||
|
status_summary = []
|
||||||
|
down_services = []
|
||||||
|
|
||||||
|
for mon_id, name in sorted(monitors.items(), key=lambda x: x[1]):
|
||||||
|
# Get heartbeats for this monitor
|
||||||
|
beats = hb_list.get(str(mon_id), [])
|
||||||
|
if not beats:
|
||||||
|
status_summary.append(f"- {name}: NO_DATA")
|
||||||
|
other_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Get latest beat
|
||||||
|
latest = beats[-1]
|
||||||
|
status_val = latest.get("status")
|
||||||
|
ping = latest.get("ping")
|
||||||
|
msg = latest.get("msg", "")
|
||||||
|
|
||||||
|
if status_val == 1:
|
||||||
|
status_str = "UP"
|
||||||
|
up_count += 1
|
||||||
|
ping_str = f" ({ping}ms)" if ping is not None else ""
|
||||||
|
status_summary.append(f"- {name}: {status_str}{ping_str}")
|
||||||
|
elif status_val == 0:
|
||||||
|
status_str = "DOWN"
|
||||||
|
down_count += 1
|
||||||
|
err_msg = f" - {msg}" if msg else ""
|
||||||
|
status_summary.append(f"- {name}: {status_str}{err_msg}")
|
||||||
|
down_services.append(name)
|
||||||
|
else:
|
||||||
|
status_str = "DEGRADED"
|
||||||
|
other_count += 1
|
||||||
|
err_msg = f" - {msg}" if msg else ""
|
||||||
|
status_summary.append(f"- {name}: {status_str}{err_msg}")
|
||||||
|
down_services.append(name)
|
||||||
|
|
||||||
|
print("=== MONITOR STATUS REPORT ===")
|
||||||
|
if down_services:
|
||||||
|
print(f"ALERT: {len(down_services)} service(s) down or degraded!")
|
||||||
|
print(f"DOWN SERVICES: {', '.join(down_services)}")
|
||||||
|
else:
|
||||||
|
print("STATUS: OK")
|
||||||
|
print(f"STATS: UP={up_count}, DOWN={down_count}, OTHER={other_count}")
|
||||||
|
print("\nDETAILS:")
|
||||||
|
print("\n".join(status_summary))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error checking status: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_uptime()
|
||||||
Reference in New Issue
Block a user