Standalone app for Q5 deployment
هذا الالتزام موجود في:
84
monitor.py
Executable file
84
monitor.py
Executable file
@@ -0,0 +1,84 @@
|
||||
import requests
|
||||
import socket
|
||||
import ssl
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from urllib.parse import urlparse
|
||||
|
||||
TARGET_URL = "https://mithal.space"
|
||||
SEARCH_URL = "https://mithal.space/search?q=test"
|
||||
LOG_FILE = "mithal_monitor_log.json"
|
||||
CHECK_INTERVAL = 60
|
||||
|
||||
|
||||
def check_latency_and_uptime(url):
|
||||
try:
|
||||
start = time.time()
|
||||
response = requests.get(url, timeout=10)
|
||||
latency_ms = round((time.time() - start) * 1000, 2)
|
||||
return {
|
||||
"up": response.status_code < 500,
|
||||
"status_code": response.status_code,
|
||||
"latency_ms": latency_ms
|
||||
}
|
||||
except requests.exceptions.RequestException as e:
|
||||
return {"up": False, "status_code": None, "latency_ms": None, "error": str(e)}
|
||||
|
||||
|
||||
def check_ssl(hostname):
|
||||
try:
|
||||
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_str = cert['notAfter']
|
||||
expiry_date = datetime.strptime(expiry_str, '%b %d %H:%M:%S %Y %Z')
|
||||
days_left = (expiry_date - datetime.utcnow()).days
|
||||
return {"valid": True, "days_until_expiry": days_left}
|
||||
except Exception as e:
|
||||
return {"valid": False, "error": str(e)}
|
||||
|
||||
|
||||
def check_dns(hostname):
|
||||
try:
|
||||
start = time.time()
|
||||
socket.gethostbyname(hostname)
|
||||
dns_time_ms = round((time.time() - start) * 1000, 2)
|
||||
return {"resolved": True, "dns_time_ms": dns_time_ms}
|
||||
except Exception as e:
|
||||
return {"resolved": False, "error": str(e)}
|
||||
|
||||
|
||||
def check_search_response(url):
|
||||
try:
|
||||
start = time.time()
|
||||
response = requests.get(url, timeout=10)
|
||||
latency_ms = round((time.time() - start) * 1000, 2)
|
||||
return {"success": response.status_code == 200, "latency_ms": latency_ms}
|
||||
except requests.exceptions.RequestException as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
|
||||
def run_check():
|
||||
hostname = urlparse(TARGET_URL).hostname
|
||||
|
||||
result = {
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"uptime": check_latency_and_uptime(TARGET_URL),
|
||||
"ssl": check_ssl(hostname),
|
||||
"dns": check_dns(hostname),
|
||||
"search": check_search_response(SEARCH_URL)
|
||||
}
|
||||
|
||||
with open(LOG_FILE, "a") as f:
|
||||
f.write(json.dumps(result) + "\n")
|
||||
|
||||
print(f"[{result['timestamp']}] Check complete — up: {result['uptime']['up']}")
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
while True:
|
||||
run_check()
|
||||
time.sleep(CHECK_INTERVAL)
|
||||
المرجع في مشكلة جديدة
حظر مستخدم