Health check and monitoring HTTP server.
Provides endpoints for health checks and status monitoring.
Classes
HealthCheckHandler
Bases: BaseHTTPRequestHandler
Source code in directory_server/src/directory_server/health.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 | class HealthCheckHandler(BaseHTTPRequestHandler):
server_instance: DirectoryServer | None = None
def log_message(self, format: str, *args: Any) -> None:
pass
def do_GET(self) -> None: # noqa: N802
if self.path == "/health":
self._handle_health()
elif self.path == "/status":
self._handle_status()
else:
self.send_error(404)
def _handle_health(self) -> None:
if not self.server_instance:
self.send_error(503)
return
try:
is_healthy = self.server_instance.is_healthy()
status_code = 200 if is_healthy else 503
self.send_response(status_code)
self.send_header("Content-Type", "application/json")
self.end_headers()
response = {"status": "healthy" if is_healthy else "unhealthy"}
self.wfile.write(json.dumps(response).encode())
except Exception as e:
logger.error(f"Health check error: {e}")
self.send_error(500)
def _handle_status(self) -> None:
if not self.server_instance:
self.send_error(503)
return
try:
stats = self.server_instance.get_detailed_stats()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(stats, default=str).encode())
except Exception as e:
logger.error(f"Status check error: {e}")
self.send_error(500)
|
Attributes
server_instance: DirectoryServer | None = None
class-attribute
instance-attribute
Functions
do_GET() -> None
Source code in directory_server/src/directory_server/health.py
| def do_GET(self) -> None: # noqa: N802
if self.path == "/health":
self._handle_health()
elif self.path == "/status":
self._handle_status()
else:
self.send_error(404)
|
log_message(format: str, *args: Any) -> None
Source code in directory_server/src/directory_server/health.py
| def log_message(self, format: str, *args: Any) -> None:
pass
|
HealthCheckServer
Source code in directory_server/src/directory_server/health.py
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 | class HealthCheckServer:
def __init__(self, host: str = "127.0.0.1", port: int = 8080):
self.host = host
self.port = port
self.httpd: HTTPServer | None = None
self.thread: Thread | None = None
def start(self, server_instance: DirectoryServer) -> None:
HealthCheckHandler.server_instance = server_instance
self.httpd = HTTPServer((self.host, self.port), HealthCheckHandler)
self.thread = Thread(target=self.httpd.serve_forever, daemon=True)
self.thread.start()
logger.info(f"Health check server started on {self.host}:{self.port}")
def stop(self) -> None:
if self.httpd:
self.httpd.shutdown()
self.httpd.server_close() # Explicitly close the socket
# Wait for thread to actually terminate to avoid race conditions
# This is important in Python 3.12+ where thread cleanup is stricter
if self.thread and self.thread.is_alive():
self.thread.join(timeout=5.0)
if self.thread.is_alive():
logger.warning("Health check server thread did not terminate in time")
# Clear class-level state to avoid leakage between test runs
HealthCheckHandler.server_instance = None
self.httpd = None
self.thread = None
logger.info("Health check server stopped")
|
Attributes
host = host
instance-attribute
httpd: HTTPServer | None = None
instance-attribute
port = port
instance-attribute
thread: Thread | None = None
instance-attribute
Functions
__init__(host: str = '127.0.0.1', port: int = 8080)
Source code in directory_server/src/directory_server/health.py
| def __init__(self, host: str = "127.0.0.1", port: int = 8080):
self.host = host
self.port = port
self.httpd: HTTPServer | None = None
self.thread: Thread | None = None
|
start(server_instance: DirectoryServer) -> None
Source code in directory_server/src/directory_server/health.py
| def start(self, server_instance: DirectoryServer) -> None:
HealthCheckHandler.server_instance = server_instance
self.httpd = HTTPServer((self.host, self.port), HealthCheckHandler)
self.thread = Thread(target=self.httpd.serve_forever, daemon=True)
self.thread.start()
logger.info(f"Health check server started on {self.host}:{self.port}")
|
stop() -> None
Source code in directory_server/src/directory_server/health.py
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 | def stop(self) -> None:
if self.httpd:
self.httpd.shutdown()
self.httpd.server_close() # Explicitly close the socket
# Wait for thread to actually terminate to avoid race conditions
# This is important in Python 3.12+ where thread cleanup is stricter
if self.thread and self.thread.is_alive():
self.thread.join(timeout=5.0)
if self.thread.is_alive():
logger.warning("Health check server thread did not terminate in time")
# Clear class-level state to avoid leakage between test runs
HealthCheckHandler.server_instance = None
self.httpd = None
self.thread = None
logger.info("Health check server stopped")
|