moved
This commit is contained in:
85
email-worker/health_server.py
Normal file
85
email-worker/health_server.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
HTTP health check server
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import threading
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from datetime import datetime
|
||||
|
||||
from logger import log
|
||||
from config import config
|
||||
|
||||
|
||||
class SilentHTTPServer(HTTPServer):
|
||||
"""HTTP Server that ignores connection reset errors from scanners"""
|
||||
|
||||
def handle_error(self, request, client_address):
|
||||
exc_type = sys.exc_info()[0]
|
||||
if exc_type in (ConnectionResetError, BrokenPipeError, ConnectionAbortedError):
|
||||
pass # Silently ignore - these are just scanners/health checks disconnecting
|
||||
else:
|
||||
log(f"Health server error from {client_address[0]}: {sys.exc_info()[1]}", 'WARNING')
|
||||
|
||||
|
||||
class HealthHandler(BaseHTTPRequestHandler):
|
||||
"""Health check request handler"""
|
||||
|
||||
worker = None # Will be set by start_health_server()
|
||||
dynamodb_available = False
|
||||
|
||||
def do_GET(self):
|
||||
if self.path == '/health' or self.path == '/':
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
|
||||
status = {
|
||||
'status': 'healthy',
|
||||
'domains': len(self.worker.queue_urls) if self.worker else 0,
|
||||
'domain_list': list(self.worker.queue_urls.keys()) if self.worker else [],
|
||||
'dynamodb': self.dynamodb_available,
|
||||
'features': {
|
||||
'bounce_rewriting': True,
|
||||
'auto_reply': self.dynamodb_available,
|
||||
'forwarding': self.dynamodb_available,
|
||||
'blocklist': self.dynamodb_available,
|
||||
'lmtp': config.lmtp_enabled
|
||||
},
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}
|
||||
self.wfile.write(json.dumps(status, indent=2).encode())
|
||||
|
||||
elif self.path == '/domains':
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
domain_list = list(self.worker.queue_urls.keys()) if self.worker else []
|
||||
self.wfile.write(json.dumps(domain_list).encode())
|
||||
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def log_message(self, format, *args):
|
||||
pass # Suppress HTTP access logs
|
||||
|
||||
|
||||
def start_health_server(worker, dynamodb_available: bool):
|
||||
"""
|
||||
Start HTTP health check server
|
||||
|
||||
Args:
|
||||
worker: UnifiedWorker instance
|
||||
dynamodb_available: Whether DynamoDB is available
|
||||
"""
|
||||
# Set class attributes for handler
|
||||
HealthHandler.worker = worker
|
||||
HealthHandler.dynamodb_available = dynamodb_available
|
||||
|
||||
server = SilentHTTPServer(('0.0.0.0', config.health_port), HealthHandler)
|
||||
thread = threading.Thread(target=server.serve_forever, daemon=True, name='health-server')
|
||||
thread.start()
|
||||
log(f"Health server on port {config.health_port}")
|
||||
Reference in New Issue
Block a user