From 9c826a26ef2dd8494397be2c9e4079ad118815b0 Mon Sep 17 00:00:00 2001 From: Tom Elliff-O'Shea Date: Tue, 30 Apr 2024 22:28:35 +0100 Subject: [PATCH] Add /healthcheck endpoint that doesn't collect PDU data When the exporter is deployed in a system that healthchecks running processes, such as Kubernetes, it's useful to have a healthcheck endpoint that can return quickly which still catching errors where eg the web server is hanging. This basic /healthcheck endpoint returns a 200 and a short message, avoiding the call to `collect` which would normally gather all of the PDU data and can be slow to return. All other endpoints will still return the PDU data in Prometheus format. Closes https://github.com/psyinfra/prometheus-raritan-pdu-exporter/issues/5. --- prometheus_raritan_pdu_exporter/main.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/prometheus_raritan_pdu_exporter/main.py b/prometheus_raritan_pdu_exporter/main.py index 88ff638..4574c71 100644 --- a/prometheus_raritan_pdu_exporter/main.py +++ b/prometheus_raritan_pdu_exporter/main.py @@ -4,8 +4,9 @@ import logging import time import urllib.parse +from wsgiref.simple_server import make_server -from prometheus_client import start_http_server, REGISTRY +from prometheus_client import MetricsHandler, make_wsgi_app, REGISTRY from . import DEFAULT_PORT from .exporter import RaritanExporter @@ -90,6 +91,17 @@ def read_config(config: str) -> List[RaritanAuth]: return config_data +class HealthcheckHandler(MetricsHandler): + def do_GET(self): + logging.debug(self.path) + if self.path == '/healthcheck': + self.send_response(200) + self.end_headers() + self.wfile.write(b'Server is running') + else: + super().do_GET() + + def main(): args = parse_args() @@ -109,9 +121,11 @@ def main(): listen_addr = urllib.parse.urlsplit(f'//{args.listen_address}') addr = listen_addr.hostname if listen_addr.hostname else '0.0.0.0' port = listen_addr.port if listen_addr.port else DEFAULT_PORT - REGISTRY.register(RaritanExporter(config=config)) - start_http_server(port, addr=addr) logger.info('listening on %s' % listen_addr.netloc) + REGISTRY.register(RaritanExporter(config=config)) + prometheus_application = make_wsgi_app() + httpd = make_server(addr, port, prometheus_application, handler_class=HealthcheckHandler) + httpd.serve_forever() except KeyboardInterrupt: logger.info('Interrupted by user') exit(0)