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
DATA_FILE = "monitoring-data.json"
MAX_ENTRIES = 1440 # 24 hours * 60 minutes
TIMEOUT = 10
def check_ssl_certificate(hostname, port=443): OUTPUT = "monitoring-data.json"
"""Check SSL certificate expiry date."""
try:
context = ssl.create_default_context()
with socket.create_connection((hostname, port), timeout=TIMEOUT) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
expiry_date = datetime.datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
days_remaining = (expiry_date - datetime.datetime.utcnow()).days
return {
"expiry_date": expiry_date.isoformat(),
"days_remaining": days_remaining,
"valid": days_remaining > 0
}
except Exception as e:
return {
"expiry_date": None,
"days_remaining": None,
"valid": False,
"error": str(e)
}
def resolve_dns(hostname):
"""Measure DNS resolution time.""" def latency():
try:
start = time.time() start = time.time()
socket.gethostbyname(hostname)
dns_time = round((time.time() - start) * 1000, 2) try:
return dns_time r = requests.get(URL, timeout=10)
except Exception:
return (
round((time.time() - start) * 1000, 2),
r.status_code,
True,
)
except:
return None, None, False
def dns():
start = time.time()
try:
socket.gethostbyname("mithal.space")
return round((time.time() - start) * 1000, 2)
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) except:
ssl_info = check_ssl_certificate(hostname)
health = check_latency_and_uptime(TARGET_URL)
search = check_search_response(TARGET_URL, SEARCH_QUERY)
metrics = { return None
"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):
"""Save metrics to JSON file with size limit.""" lat, code, up = latency()
try:
if os.path.exists(filename): entry = {
with open(filename, 'r') as f: "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) data = json.load(f)
else:
except:
data = [] data = []
data.append(metrics)
if len(data) > max_entries: data.append(entry)
data = data[-max_entries:]
with open(filename, 'w') as f: data = data[-60:]
with open(OUTPUT, "w") as f:
json.dump(data, f, indent=2) json.dump(data, f, indent=2)
return True
except Exception as e:
print(f"Error saving data: {e}")
return False
def run_monitor():
"""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()

عرض الملف

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