diff --git a/q5-mithal-monitor/Dockerfile b/q5-mithal-monitor/Dockerfile
index 4e0ba83..98d4a6b 100644
--- a/q5-mithal-monitor/Dockerfile
+++ b/q5-mithal-monitor/Dockerfile
@@ -8,8 +8,6 @@ RUN pip install --no-cache-dir -r requirements.txt
COPY . .
-RUN mv dashboard.html index.html
-
EXPOSE 8080
-CMD sh -c "python3 monitor.py && python3 -m http.server 8080"
+CMD ["python3","app.py"]
diff --git a/q5-mithal-monitor/app.py b/q5-mithal-monitor/app.py
new file mode 100644
index 0000000..5d5d564
--- /dev/null
+++ b/q5-mithal-monitor/app.py
@@ -0,0 +1,51 @@
+from flask import Flask, send_file, jsonify
+import threading
+import time
+import json
+import os
+
+from monitor import collect_metrics
+
+app = Flask(__name__)
+
+
+def monitor_loop():
+ while True:
+ try:
+ collect_metrics()
+ print("Metrics updated.")
+ except Exception as e:
+ print("Monitor error:", e)
+
+ time.sleep(60)
+
+
+@app.route("/")
+def dashboard():
+ return send_file("dashboard.html")
+
+
+@app.route("/metrics.json")
+def metrics():
+ if os.path.exists("metrics.json"):
+ with open("metrics.json") as f:
+ return jsonify(json.load(f))
+
+ return jsonify({
+ "uptime": 0,
+ "last_check": {},
+ "history": [],
+ "latency_chart": []
+ })
+
+
+if __name__ == "__main__":
+ # Run one check immediately
+ collect_metrics()
+
+ # Start background monitoring
+ thread = threading.Thread(target=monitor_loop, daemon=True)
+ thread.start()
+
+ # Start Flask
+ app.run(host="0.0.0.0", port=8080)
diff --git a/q5-mithal-monitor/dashboard.html b/q5-mithal-monitor/dashboard.html
index 5882bed..05f9058 100644
--- a/q5-mithal-monitor/dashboard.html
+++ b/q5-mithal-monitor/dashboard.html
@@ -8,255 +8,195 @@
-
+
-🚀 Mithal Monitoring Dashboard
+Mithal Monitoring Dashboard
-
Uptime (24h)
-
-- %
+
Uptime
+
--
-
DNS Lookup
-
-- ms
+
DNS
+
--
-
Search Response
-
-- ms
+
Search
+
--
-
Days Remaining
+
Days Left
--
-
+
+
| Time |
Status |
Latency |
DNS |
Search |
SSL Days |
+
-
-
-
+
diff --git a/q5-mithal-monitor/metrics.json b/q5-mithal-monitor/metrics.json
deleted file mode 100644
index 92b1b69..0000000
--- a/q5-mithal-monitor/metrics.json
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "uptime": 100.0,
- "last_check": {
- "time": "2026-07-27 03:13:02",
- "status": 200,
- "latency": 78.62,
- "dns": 0.5,
- "search_latency": 80.38,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- "history": [
- {
- "time": "2026-07-27 03:04:01",
- "status": 200,
- "latency": 82.82,
- "dns": 0.33,
- "search_latency": 78.14,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:05:02",
- "status": 200,
- "latency": 89.55,
- "dns": 0.31,
- "search_latency": 76.35,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:06:01",
- "status": 200,
- "latency": 88.39,
- "dns": 0.67,
- "search_latency": 81.37,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:07:01",
- "status": 200,
- "latency": 77.25,
- "dns": 3.21,
- "search_latency": 80.14,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:08:01",
- "status": 200,
- "latency": 86.22,
- "dns": 0.29,
- "search_latency": 76.51,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:09:01",
- "status": 200,
- "latency": 81.52,
- "dns": 0.55,
- "search_latency": 74.89,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:10:01",
- "status": 200,
- "latency": 80.42,
- "dns": 0.26,
- "search_latency": 79.42,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:11:02",
- "status": 200,
- "latency": 82.46,
- "dns": 0.5,
- "search_latency": 75.56,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:12:01",
- "status": 200,
- "latency": 80.94,
- "dns": 0.26,
- "search_latency": 85.53,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- },
- {
- "time": "2026-07-27 03:13:02",
- "status": 200,
- "latency": 78.62,
- "dns": 0.5,
- "search_latency": 80.38,
- "ssl_expiry": "2026-09-15",
- "ssl_days_left": 50
- }
- ],
- "latency_chart": [
- 78.97,
- 82.82,
- 89.55,
- 88.39,
- 77.25,
- 86.22,
- 81.52,
- 80.42,
- 82.46,
- 80.94,
- 78.62
- ]
-}
\ No newline at end of file
diff --git a/q5-mithal-monitor/monitor.py b/q5-mithal-monitor/monitor.py
index e221f38..0b7d6f4 100644
--- a/q5-mithal-monitor/monitor.py
+++ b/q5-mithal-monitor/monitor.py
@@ -11,139 +11,82 @@ URL = "https://mithal.space"
OUTPUT_FILE = "metrics.json"
-def http_check():
+def collect_metrics():
+ hostname = urlparse(URL).hostname
+
+ # HTTP latency & uptime
start = time.time()
-
try:
- r = requests.get(URL, timeout=10)
+ response = requests.get(URL, timeout=10)
latency = round((time.time() - start) * 1000, 2)
- return r.status_code, latency
- except:
- latency = round((time.time() - start) * 1000, 2)
- return 0, latency
-
-
-def dns_lookup():
- host = urlparse(URL).hostname
+ status = response.status_code
+ except Exception:
+ latency = -1
+ status = 0
+ # DNS lookup
start = time.time()
-
try:
- socket.gethostbyname(host)
- except:
- pass
-
- return round((time.time() - start) * 1000, 2)
-
-
-def ssl_info():
-
- host = urlparse(URL).hostname
+ socket.gethostbyname(hostname)
+ dns = round((time.time() - start) * 1000, 2)
+ except Exception:
+ dns = -1
+ # SSL expiry
+ ssl_expiry = "Unavailable"
+ ssl_days = -1
try:
-
- ctx = ssl.create_default_context()
-
- with socket.create_connection((host,443),timeout=10) as sock:
-
- with ctx.wrap_socket(sock,server_hostname=host) as ssock:
-
+ context = ssl.create_default_context()
+ with socket.create_connection((hostname, 443), timeout=10) as sock:
+ with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
- expiry = datetime.strptime(
- cert["notAfter"],
- "%b %d %H:%M:%S %Y %Z"
- )
-
- days = (expiry-datetime.utcnow()).days
-
- return expiry.strftime("%Y-%m-%d"),days
-
- except:
-
- return "Unavailable",-1
-
-
-def search_response():
-
- start=time.time()
-
- try:
- requests.get(URL,timeout=10)
- except:
+ expiry = datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z")
+ ssl_expiry = expiry.strftime("%Y-%m-%d")
+ ssl_days = (expiry - datetime.utcnow()).days
+ except Exception:
pass
- return round((time.time()-start)*1000,2)
+ # Search response
+ start = time.time()
+ try:
+ requests.get(URL, timeout=10)
+ search_latency = round((time.time() - start) * 1000, 2)
+ except Exception:
+ search_latency = -1
+ if os.path.exists(OUTPUT_FILE):
+ with open(OUTPUT_FILE) as f:
+ data = json.load(f)
+ else:
+ data = {"history": []}
-if os.path.exists(OUTPUT_FILE):
+ history = data.get("history", [])
- with open(OUTPUT_FILE,"r") as f:
+ history.append({
+ "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "status": status,
+ "latency": latency,
+ "dns": dns,
+ "ssl_expiry": ssl_expiry,
+ "ssl_days_left": ssl_days,
+ "search_latency": search_latency
+ })
- data=json.load(f)
+ history = history[-1440:]
-else:
-
- data={
-
- "history":[]
+ uptime = round(
+ len([x for x in history if x["status"] == 200]) /
+ len(history) * 100,
+ 2
+ )
+ output = {
+ "uptime": uptime,
+ "last_check": history[-1],
+ "history": history[-10:],
+ "latency_chart": [x["latency"] for x in history[-60:]]
}
-status,latency=http_check()
-
-record={
-
-"time":datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
-
-"status":status,
-
-"latency":latency,
-
-"dns":dns_lookup(),
-
-"search_latency":search_response()
-
-}
-
-ssl_date,ssl_days=ssl_info()
-
-record["ssl_expiry"]=ssl_date
-record["ssl_days_left"]=ssl_days
-
-data["history"].append(record)
-
-if len(data["history"])>1440:
-
- data["history"]=data["history"][-1440:]
-
-success=len([x for x in data["history"] if x["status"]==200])
-
-uptime=round(success/len(data["history"])*100,2)
-
-output={
-
-"uptime":uptime,
-
-"last_check":record,
-
-"history":data["history"][-10:],
-
-"latency_chart":[x["latency"] for x in data["history"][-60:]]
-
-}
-
-with open(OUTPUT_FILE,"w") as f:
-
- json.dump(output,f,indent=4)
-
-print("="*40)
-print("Mithal Monitoring")
-print("="*40)
-print("Status :",status)
-print("Latency :",latency,"ms")
-print("DNS :",record["dns"],"ms")
-print("Search :",record["search_latency"],"ms")
-print("SSL Expiry :",ssl_date)
-print("Days Left :",ssl_days)
-print("Uptime :",uptime,"%")
+ with open(OUTPUT_FILE, "w") as f:
+ json.dump(output, f, indent=4)
diff --git a/q5-mithal-monitor/requirements.txt b/q5-mithal-monitor/requirements.txt
index f229360..e635204 100644
--- a/q5-mithal-monitor/requirements.txt
+++ b/q5-mithal-monitor/requirements.txt
@@ -1 +1,2 @@
+Flask
requests