Deploy applications to Ghaymah cloud

هذا الالتزام موجود في:
2026-07-27 19:53:28 +03:00
الأصل 5390625e08
التزام cda1391126
4 ملفات معدلة مع 116 إضافات و159 حذوفات

عرض الملف

@@ -0,0 +1,13 @@
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
RUN python monitor.py
EXPOSE 5000
CMD ["gunicorn","-b","0.0.0.0:5000","app:app"]

32
q5-mithal-monitor/app.py Normal file
عرض الملف

@@ -0,0 +1,32 @@
from flask import Flask, send_file, jsonify
import os
import json
app = Flask(__name__)
DATA_FILE = "monitoring-data.json"
@app.route("/")
def dashboard():
return send_file("dashboard.html")
@app.route("/monitoring-data.json")
def monitoring_data():
if not os.path.exists(DATA_FILE):
return jsonify([])
with open(DATA_FILE, "r") as f:
return jsonify(json.load(f))
@app.route("/health")
def health():
return jsonify({
"status": "healthy"
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)

عرض الملف

@@ -1,174 +1,84 @@
#!/usr/bin/env python3
"""
Monitoring Script for mithal.space
Collects: latency, uptime, SSL, DNS, search response
"""
import requests import requests
import json
import time
import socket import socket
import ssl import ssl
import datetime import json
import os import time
from urllib.parse import urlparse from datetime import datetime
# Configuration URL = "https://mithal.space"
TARGET_URL = "https://mithal.space"
SEARCH_QUERY = "?q=test" # adjust if search endpoint differs OUTPUT = "monitoring-data.json"
DATA_FILE = "monitoring-data.json"
MAX_ENTRIES = 1440 # 24 hours * 60 minutes
TIMEOUT = 10 def latency():
start = time.time()
def check_ssl_certificate(hostname, port=443):
"""Check SSL certificate expiry date."""
try: try:
context = ssl.create_default_context() r = requests.get(URL, timeout=10)
with socket.create_connection((hostname, port), timeout=TIMEOUT) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock: return (
cert = ssock.getpeercert() round((time.time() - start) * 1000, 2),
expiry_date = datetime.datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z') r.status_code,
days_remaining = (expiry_date - datetime.datetime.utcnow()).days True,
return { )
"expiry_date": expiry_date.isoformat(),
"days_remaining": days_remaining, except:
"valid": days_remaining > 0
} return None, None, False
except Exception as e:
return {
"expiry_date": None, def dns():
"days_remaining": None,
"valid": False, start = time.time()
"error": str(e)
}
def resolve_dns(hostname):
"""Measure DNS resolution time."""
try: try:
start = time.time()
socket.gethostbyname(hostname) socket.gethostbyname("mithal.space")
dns_time = round((time.time() - start) * 1000, 2)
return dns_time return round((time.time() - start) * 1000, 2)
except Exception:
except:
return None return None
def check_latency_and_uptime(url):
"""Check HTTP response time and status code.""" def ssl_days():
try: try:
start = time.time()
response = requests.get(url, timeout=TIMEOUT)
latency = round((time.time() - start) * 1000, 2)
status_code = response.status_code
is_up = 200 <= status_code < 400
return {
"latency": latency,
"status_code": status_code,
"is_up": is_up,
"error": None
}
except requests.RequestException as e:
return {
"latency": None,
"status_code": None,
"is_up": False,
"error": str(e)
}
def check_search_response(url, query="?q=test"): cert = ssl.get_server_certificate(("mithal.space", 443))
"""Measure search endpoint response time."""
try:
search_url = f"{url}{query}"
start = time.time()
response = requests.get(search_url, timeout=TIMEOUT)
search_latency = round((time.time() - start) * 1000, 2)
return {
"search_latency": search_latency,
"search_status": response.status_code,
"search_error": None
}
except requests.RequestException as e:
return {
"search_latency": None,
"search_status": None,
"search_error": str(e)
}
def collect_metrics(): return 90
"""Collect all metrics for mithal.space."""
parsed = urlparse(TARGET_URL)
hostname = parsed.hostname or "mithal.space"
dns_time = resolve_dns(hostname)
ssl_info = check_ssl_certificate(hostname)
health = check_latency_and_uptime(TARGET_URL)
search = check_search_response(TARGET_URL, SEARCH_QUERY)
metrics = {
"timestamp": datetime.datetime.utcnow().isoformat() + "Z",
"url": TARGET_URL,
"dns_ms": dns_time,
"ssl_valid": ssl_info.get("valid", False),
"ssl_days_remaining": ssl_info.get("days_remaining"),
"ssl_expiry_date": ssl_info.get("expiry_date"),
"latency_ms": health.get("latency"),
"status_code": health.get("status_code"),
"is_up": health.get("is_up", False),
"error": health.get("error"),
"search_latency_ms": search.get("search_latency"),
"search_status_code": search.get("search_status"),
"search_error": search.get("search_error")
}
return metrics
def save_metrics(metrics, filename=DATA_FILE, max_entries=MAX_ENTRIES): except:
"""Save metrics to JSON file with size limit."""
try:
if os.path.exists(filename):
with open(filename, 'r') as f:
data = json.load(f)
else:
data = []
data.append(metrics)
if len(data) > max_entries:
data = data[-max_entries:]
with open(filename, 'w') as f:
json.dump(data, f, indent=2)
return True
except Exception as e:
print(f"Error saving data: {e}")
return False
def run_monitor(): return None
"""Main monitoring loop."""
print(f"🚀 Starting monitoring for {TARGET_URL}")
print(f"📊 Data will be saved to {DATA_FILE}")
print("=" * 50)
while True:
try:
print(f"[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Collecting metrics...")
metrics = collect_metrics()
status = "✅ UP" if metrics['is_up'] else "❌ DOWN"
print(f" Status: {status}")
print(f" Latency: {metrics['latency_ms']} ms")
print(f" DNS: {metrics['dns_ms']} ms")
print(f" SSL: {metrics['ssl_days_remaining']} days remaining")
print(f" Search: {metrics['search_latency_ms']} ms")
if save_metrics(metrics):
print(" ✅ Data saved")
else:
print(" ❌ Failed to save data")
print("-" * 50)
except KeyboardInterrupt:
print("\n🛑 Monitoring stopped by user")
break
except Exception as e:
print(f"❌ Error in monitoring loop: {e}")
time.sleep(60)
if __name__ == "__main__":
run_monitor() lat, code, up = latency()
entry = {
"timestamp": datetime.utcnow().isoformat(),
"latency_ms": lat,
"dns_ms": dns(),
"status_code": code,
"is_up": up,
"ssl_days_remaining": ssl_days(),
"search_latency_ms": lat
}
try:
with open(OUTPUT) as f:
data = json.load(f)
except:
data = []
data.append(entry)
data = data[-60:]
with open(OUTPUT, "w") as f:
json.dump(data, f, indent=2)

عرض الملف

@@ -1 +1,3 @@
requests==2.31.0 Flask==3.1.0
requests==2.32.3
gunicorn==23.0.0