Skip to content

Usage

Setting up monitoring

You can use tools like Pingdom, StatusCake or other uptime robots to monitor service status. The /health/ endpoint will respond with an HTTP 200 if all checks passed and with an HTTP 500 if any of the tests failed.

For concrete, step-by-step examples of multi-tier endpoint setups including uptime monitoring, container probes, reverse-proxy configuration, and RSS/Atom integration into Slack or Matrix, see the Cookbook.

Getting machine-readable reports

Plain text

For simple monitoring and scripting, you can request plain text output with the Accept HTTP header set to text/plain or pass format=text as a query parameter.

The endpoint will return a plain text response with HTTP 200 if all checks passed and HTTP 500 if any check failed:

$ curl -v -X GET -H "Accept: text/plain" http://www.example.com/health/

> GET /health/ HTTP/1.1
> Host: www.example.com
> Accept: text/plain
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8

CacheBackend: OK
DatabaseBackend: OK
S3BotoStorageHealthCheck: OK

$ curl -v -X GET http://www.example.com/health/?format=text

> GET /health/?format=text HTTP/1.1
> Host: www.example.com
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8

CacheBackend: OK
DatabaseBackend: OK
S3BotoStorageHealthCheck: OK

This format is particularly useful for command-line tools and simple monitoring scripts that don't need the overhead of JSON parsing.

JSON

If you want machine-readable status reports you can request the /health/ endpoint with the Accept HTTP header set to application/json or pass format=json as a query parameter.

The backend will return a JSON response:

$ curl -v -X GET -H "Accept: application/json" http://www.example.com/health/

> GET /health/ HTTP/1.1
> Host: www.example.com
> Accept: application/json
>
< HTTP/1.1 200 OK
< Content-Type: application/json

{
    "CacheBackend": "working",
    "DatabaseBackend": "working",
    "S3BotoStorageHealthCheck": "working"
}

$ curl -v -X GET http://www.example.com/health/?format=json

> GET /health/?format=json HTTP/1.1
> Host: www.example.com
>
< HTTP/1.1 200 OK
< Content-Type: application/json

{
    "CacheBackend": "working",
    "DatabaseBackend": "working",
    "S3BotoStorageHealthCheck": "working"
}

OpenMetrics for Prometheus

For Prometheus monitoring, you can request OpenMetrics format:

$ curl http://www.example.com/health/?format=openmetrics

This will return metrics in the OpenMetrics exposition format, which can be scraped by Prometheus.

RSS and Atom feeds

For RSS feed readers and monitoring tools, you can request RSS or Atom format:

$ curl http://www.example.com/health/?format=rss
$ curl http://www.example.com/health/?format=atom

You can also use the Accept header:

$ curl -H "Accept: application/rss+xml" http://www.example.com/health/
$ curl -H "Accept: application/atom+xml" http://www.example.com/health/

These endpoints always return a 200 status code with health check results in the feed content. Failed checks are indicated by categories and item descriptions.

Writing a custom health check

You can write your own health checks by inheriting from HealthCheck and implementing the run method.

health_check.HealthCheck dataclass

Bases: ABC

Base class for defining health checks.

Subclasses should implement the run method to perform the actual health check logic. The run method can be either synchronous or asynchronous.

Examples:

>>> import dataclasses
>>> from health_check.base import HealthCheck
>>>
>>> @dataclasses.dataclass
>>> class MyHealthCheck(HealthCheck):
...
...    async def run(self):
...        # Implement health check logic here

Subclasses should be dataclasses or implement their own __repr__ method to provide meaningful representations in health check reports.

Warning

The __repr__ method is used in health check reports. Consider setting repr=False for sensitive dataclass fields to avoid leaking sensitive information or credentials.

Source code in health_check/base.py
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
@dataclasses.dataclass
class HealthCheck(abc.ABC):
    """
    Base class for defining health checks.

    Subclasses should implement the `run` method to perform the actual health check logic.
    The `run` method can be either synchronous or asynchronous.

    Examples:
        >>> import dataclasses
        >>> from health_check.base import HealthCheck
        >>>
        >>> @dataclasses.dataclass
        >>> class MyHealthCheck(HealthCheck):
        ...
        ...    async def run(self):
        ...        # Implement health check logic here

    Subclasses should be [dataclasses][dataclasses.dataclass] or implement their own `__repr__` method
    to provide meaningful representations in health check reports.

    Warning:
        The `__repr__` method is used in health check reports.
        Consider setting `repr=False` for sensitive dataclass fields
        to avoid leaking sensitive information or credentials.

    """

    @abc.abstractmethod
    async def run(self) -> None:
        """
        Run the health check logic and raise human-readable exceptions as needed.

        Exception must be reraised to indicate the health status and provide context.
        Any unexpected exceptions will be caught and logged for security purposes
        while returning a generic error message.

        Warning:
            Exception messages must not contain sensitive information.

        Raises:
            ServiceWarning: If the service is at a critical state but still operational.
            ServiceUnavailable: If the service is not operational.
            ServiceReturnedUnexpectedResult: If the check performs a computation that returns an unexpected result.

        """
        ...

    def pretty_status(self) -> str:
        """Return human-readable status string, always 'OK' for the check itself."""
        return "OK"

    async def get_result(self: HealthCheck) -> HealthCheckResult:
        start = timeit.default_timer()
        try:
            await self.run() if inspect.iscoroutinefunction(
                self.run
            ) else await asyncio.to_thread(self.run)
        except HealthCheckException as e:
            error = e
        except BaseException:
            logger.exception("Unexpected exception during health check")
            error = HealthCheckException("unknown error")
        else:
            error = None
        return HealthCheckResult(
            check=self,
            error=error,
            time_taken=timeit.default_timer() - start,
        )

pretty_status()

Return human-readable status string, always 'OK' for the check itself.

Source code in health_check/base.py
72
73
74
def pretty_status(self) -> str:
    """Return human-readable status string, always 'OK' for the check itself."""
    return "OK"

run() abstractmethod async

Run the health check logic and raise human-readable exceptions as needed.

Exception must be reraised to indicate the health status and provide context. Any unexpected exceptions will be caught and logged for security purposes while returning a generic error message.

Warning

Exception messages must not contain sensitive information.

Raises:

Type Description
ServiceWarning

If the service is at a critical state but still operational.

ServiceUnavailable

If the service is not operational.

ServiceReturnedUnexpectedResult

If the check performs a computation that returns an unexpected result.

Source code in health_check/base.py
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@abc.abstractmethod
async def run(self) -> None:
    """
    Run the health check logic and raise human-readable exceptions as needed.

    Exception must be reraised to indicate the health status and provide context.
    Any unexpected exceptions will be caught and logged for security purposes
    while returning a generic error message.

    Warning:
        Exception messages must not contain sensitive information.

    Raises:
        ServiceWarning: If the service is at a critical state but still operational.
        ServiceUnavailable: If the service is not operational.
        ServiceReturnedUnexpectedResult: If the check performs a computation that returns an unexpected result.

    """
    ...

Django command

You can run the Django command health_check to perform your health checks via the command line, or periodically with a cron, as follows:

django-admin health_check --help

This should yield the following output:

Database                 ... OK
CustomHealthCheck        ... Unavailable: Something went wrong!

Similar to the http version, a critical error will cause the command to quit with the exit code 1.