Files
aitbc/.windsurf/skills/deploy-production/health-check.py
oib 9b9c5beb23 ```
chore: enhance .gitignore and remove obsolete documentation files

- Reorganize .gitignore with categorized sections for better maintainability
- Add comprehensive ignore patterns for Python, Node.js, databases, logs, and build artifacts
- Add project-specific ignore rules for coordinator, explorer, and deployment files
- Remove outdated documentation: BITCOIN-WALLET-SETUP.md, LOCAL_ASSETS_SUMMARY.md, README-CONTAINER-DEPLOYMENT.md, README-DOMAIN-DEPLOYMENT.md
```
2026-01-24 14:44:51 +01:00

239 lines
7.4 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
AITBC Production Health Check Script
Verifies the health of all AITBC services after deployment
"""
import requests
import json
import sys
import time
from datetime import datetime
from typing import Dict, List, Tuple
# Configuration
SERVICES = {
"coordinator": {
"url": "http://localhost:8080/health",
"expected_status": 200,
"timeout": 10
},
"blockchain-node": {
"url": "http://localhost:8545",
"method": "POST",
"payload": {
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
"id": 1
},
"expected_status": 200,
"timeout": 10
},
"dashboard": {
"url": "https://aitbc.io/health",
"expected_status": 200,
"timeout": 10
},
"api": {
"url": "https://api.aitbc.io/v1/status",
"expected_status": 200,
"timeout": 10
},
"miner": {
"url": "http://localhost:8081/api/status",
"expected_status": 200,
"timeout": 10
}
}
# Colors for output
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
ENDC = '\033[0m'
def print_status(message: str, status: str = "INFO"):
"""Print colored status message"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if status == "SUCCESS":
print(f"{Colors.GREEN}[✓]{Colors.ENDC} {timestamp} - {message}")
elif status == "ERROR":
print(f"{Colors.RED}[✗]{Colors.ENDC} {timestamp} - {message}")
elif status == "WARNING":
print(f"{Colors.YELLOW}[⚠]{Colors.ENDC} {timestamp} - {message}")
else:
print(f"{Colors.BLUE}[]{Colors.ENDC} {timestamp} - {message}")
def check_service(name: str, config: Dict) -> Tuple[bool, str]:
"""Check individual service health"""
try:
method = config.get('method', 'GET')
timeout = config.get('timeout', 10)
expected_status = config.get('expected_status', 200)
if method == 'POST':
response = requests.post(
config['url'],
json=config.get('payload', {}),
timeout=timeout,
headers={'Content-Type': 'application/json'}
)
else:
response = requests.get(config['url'], timeout=timeout)
if response.status_code == expected_status:
# Additional checks for specific services
if name == "blockchain-node":
data = response.json()
if 'result' in data:
block_number = int(data['result'], 16)
return True, f"Block number: {block_number}"
return False, "Invalid response format"
elif name == "coordinator":
data = response.json()
if data.get('status') == 'healthy':
return True, f"Version: {data.get('version', 'unknown')}"
return False, f"Status: {data.get('status')}"
return True, f"Status: {response.status_code}"
else:
return False, f"HTTP {response.status_code}"
except requests.exceptions.Timeout:
return False, "Timeout"
except requests.exceptions.ConnectionError:
return False, "Connection refused"
except Exception as e:
return False, str(e)
def check_database() -> Tuple[bool, str]:
"""Check database connectivity"""
try:
# This would use your actual database connection
import psycopg2
conn = psycopg2.connect(
host="localhost",
database="aitbc_prod",
user="postgres",
password="your_password"
)
cursor = conn.cursor()
cursor.execute("SELECT 1")
cursor.close()
conn.close()
return True, "Database connected"
except Exception as e:
return False, str(e)
def check_redis() -> Tuple[bool, str]:
"""Check Redis connectivity"""
try:
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.ping()
return True, "Redis connected"
except Exception as e:
return False, str(e)
def check_disk_space() -> Tuple[bool, str]:
"""Check disk space usage"""
import shutil
total, used, free = shutil.disk_usage("/")
percent_used = (used / total) * 100
if percent_used < 80:
return True, f"Disk usage: {percent_used:.1f}%"
else:
return False, f"Disk usage critical: {percent_used:.1f}%"
def check_ssl_certificates() -> Tuple[bool, str]:
"""Check SSL certificate validity"""
import ssl
import socket
from datetime import datetime
try:
context = ssl.create_default_context()
with socket.create_connection(("aitbc.io", 443)) as sock:
with context.wrap_socket(sock, server_hostname="aitbc.io") as ssock:
cert = ssock.getpeercert()
expiry_date = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
days_until_expiry = (expiry_date - datetime.now()).days
if days_until_expiry > 7:
return True, f"SSL valid for {days_until_expiry} days"
else:
return False, f"SSL expires in {days_until_expiry} days"
except Exception as e:
return False, str(e)
def main():
"""Main health check function"""
print_status("Starting AITBC Production Health Check", "INFO")
print("=" * 60)
all_passed = True
failed_services = []
# Check all services
print_status("\n=== Service Health Checks ===")
for name, config in SERVICES.items():
success, message = check_service(name, config)
if success:
print_status(f"{name}: {message}", "SUCCESS")
else:
print_status(f"{name}: {message}", "ERROR")
all_passed = False
failed_services.append(name)
# Check infrastructure components
print_status("\n=== Infrastructure Checks ===")
# Database
db_success, db_message = check_database()
if db_success:
print_status(f"Database: {db_message}", "SUCCESS")
else:
print_status(f"Database: {db_message}", "ERROR")
all_passed = False
# Redis
redis_success, redis_message = check_redis()
if redis_success:
print_status(f"Redis: {redis_message}", "SUCCESS")
else:
print_status(f"Redis: {redis_message}", "ERROR")
all_passed = False
# Disk space
disk_success, disk_message = check_disk_space()
if disk_success:
print_status(f"Disk: {disk_message}", "SUCCESS")
else:
print_status(f"Disk: {disk_message}", "ERROR")
all_passed = False
# SSL certificates
ssl_success, ssl_message = check_ssl_certificates()
if ssl_success:
print_status(f"SSL: {ssl_message}", "SUCCESS")
else:
print_status(f"SSL: {ssl_message}", "ERROR")
all_passed = False
# Summary
print("\n" + "=" * 60)
if all_passed:
print_status("All checks passed! System is healthy.", "SUCCESS")
sys.exit(0)
else:
print_status(f"Health check failed! Failed services: {', '.join(failed_services)}", "ERROR")
print_status("Please check the logs and investigate the issues.", "WARNING")
sys.exit(1)
if __name__ == "__main__":
main()