Return HTTP status codes based on an arbitrary script

3 min read | by Jordi Prats

Sometimes we need a way of telling using a HTTP endpoint the readiness of the service but the service does not provide any of this: For example, a MySQL replica that we need to get in and out of the pool depending on how lagged it is, or a worker node that we want to remove from that pool depending on it's CPU usage...

If we have a command that will tell us whether the service is ready to accept connections, we can use healthcheckd to create a HTTP endpoint to publish it.

This tool is something that we can install easily on any server or container, the only dependencies are pid (for handling the creation of a PIDfile) and configparser (to read the ini config file). It uses python's http.server to handle the HTTP requests.

To configure it we just need to create a config file with the command we want to use, for example if we use the following command that will return 0 only if the last digit of the bash's RANDOM variable is greater than 5:

test ${RANDOM: -1} -ge 5 

We can configure it like so:

[healthcheckd] pidfile = demo.pid port = 9999 command = "test ${RANDOM: -1} -ge 5" 

And finally run the webserver using this config

python3 healthcheckd.py ./random_example.config 

Now we we use run curl to localhost using the configured port we will get a different result depending the value of the RANDOM variable:

$ curl -I localhost:9999 HTTP/1.0 200 OK Server: BaseHTTP/0.6 Python/3.8.10 Date: Tue, 26 Oct 2021 15:41:04 GMT Content-type: text/html $ curl -I localhost:9999 HTTP/1.0 503 Service Unavailable Server: BaseHTTP/0.6 Python/3.8.10 Date: Tue, 26 Oct 2021 15:41:05 GMT Content-type: text/html $ curl -I localhost:9999 HTTP/1.0 200 OK Server: BaseHTTP/0.6 Python/3.8.10 Date: Tue, 26 Oct 2021 15:41:06 GMT Content-type: text/html $ curl -I localhost:9999 HTTP/1.0 503 Service Unavailable Server: BaseHTTP/0.6 Python/3.8.10 Date: Tue, 26 Oct 2021 15:41:06 GMT Content-type: text/html $ curl -I localhost:9999 HTTP/1.0 503 Service Unavailable Server: BaseHTTP/0.6 Python/3.8.10 Date: Tue, 26 Oct 2021 15:41:07 GMT Content-type: text/html (...) 

To have a health endpoint we just need to change the script to run to something that returns 0 when we want to accept connections or any other return code when we don't.


Posted on 27/10/2021