Deploy applications to Ghaymah cloud

This commit is contained in:
2026-07-27 19:53:28 +03:00
parent 5390625e08
commit cda1391126
4 changed files with 116 additions and 159 deletions
+13
View File
@@ -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
View 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)
+66 -156
View File
@@ -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()
+3 -1
View File
@@ -1 +1,3 @@
requests==2.31.0 Flask==3.1.0
requests==2.32.3
gunicorn==23.0.0