diff --git a/docs/package-lock.json b/docs/package-lock.json index 0acfce31..8622d631 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -628,32 +628,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "optional": true, - "peer": true - }, - "node_modules/@types/react": { - "version": "18.0.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.14.tgz", - "integrity": "sha512-x4gGuASSiWmo0xjDLpm5mPb52syZHJx02VKbqUKdLmKtAwIh63XClGsiTI1K6DO5q7ox4xAsQrU+Gl3+gGXF9Q==", - "optional": true, - "peer": true, - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "optional": true, - "peer": true - }, "node_modules/@typescript-eslint/parser": { "version": "5.29.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", @@ -1250,13 +1224,6 @@ "node": ">=4" } }, - "node_modules/csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", - "optional": true, - "peer": true - }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -3853,20 +3820,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -4202,8 +4155,7 @@ "@headlessui/react": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.2.tgz", - "integrity": "sha512-snLv2lxwsf2HNTOBNgHYdvoYZ3ChJE8QszPi1d/hl9js8KrFrUulTaQBfSyPbJP5BybVreWh9DxCgz9S0Z6hKQ==", - "requires": {} + "integrity": "sha512-snLv2lxwsf2HNTOBNgHYdvoYZ3ChJE8QszPi1d/hl9js8KrFrUulTaQBfSyPbJP5BybVreWh9DxCgz9S0Z6hKQ==" }, "@humanwhocodes/config-array": { "version": "0.11.7", @@ -4412,32 +4364,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "optional": true, - "peer": true - }, - "@types/react": { - "version": "18.0.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.14.tgz", - "integrity": "sha512-x4gGuASSiWmo0xjDLpm5mPb52syZHJx02VKbqUKdLmKtAwIh63XClGsiTI1K6DO5q7ox4xAsQrU+Gl3+gGXF9Q==", - "optional": true, - "peer": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "optional": true, - "peer": true - }, "@typescript-eslint/parser": { "version": "5.29.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.29.0.tgz", @@ -4501,8 +4427,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-node": { "version": "1.8.2", @@ -4830,13 +4755,6 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, - "csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", - "optional": true, - "peer": true - }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5291,8 +5209,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "7.1.1", @@ -6283,14 +6200,12 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.1.13.tgz", "integrity": "sha512-/EKQURUrxLu66CMUg4+1LwGdxnz8of7IDvrSLqEtDqhLH61SAlNNUSr90UTvZaemujgl3OH/VHg+fyGltrNixw==", - "dev": true, - "requires": {} + "dev": true }, "prism-react-renderer": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", - "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==", - "requires": {} + "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==" }, "prop-types": { "version": "15.8.1", @@ -6663,13 +6578,6 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true, - "peer": true - }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6703,8 +6611,7 @@ "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" }, "util-deprecate": { "version": "1.0.2", diff --git a/docs/src/components/Layout.jsx b/docs/src/components/Layout.jsx index 6872f130..448de30f 100644 --- a/docs/src/components/Layout.jsx +++ b/docs/src/components/Layout.jsx @@ -47,7 +47,7 @@ const navigation = [ { title: 'Advanced guides', links: [ - { title: 'Writing sustom checks', href: '/writing-your-own-checks' }, + { title: 'Writing custom checks', href: '/writing-your-own-checks' }, { title: 'Customizing the output', href: '/customize-output' }, { title: 'Management Command', href: '/management-command' }, { title: 'External Monitoring', href: '/monitoring' }, diff --git a/docs/src/pages/checks/cache.md b/docs/src/pages/checks/cache.md index e69de29b..cafbc805 100644 --- a/docs/src/pages/checks/cache.md +++ b/docs/src/pages/checks/cache.md @@ -0,0 +1,69 @@ +--- +title: Cache Health Check +pageTitle: django-health-check cache check +description: Verify that the Django application's caching system is operating seamlessly and efficiently +--- + +Caching is storing the outcome of a time-consuming calculation to avoid recomputing in the future. + +The `health_check.cache` verifies that the Django application +caching mechanism is functioning as intended. + + +## Settings + +The settings that need to be correct are the standard Django `CACHES` +settings in your `settings.py`. +To ensure that you have configured Caching properly go through this +[documentation](https://docs.djangoproject.com/en/4.2/topics/cache/) + +## What does it check? + +This check does the following: + +- Reads the cache backend's configuration +- Writes to the cache backend +- Reads from the cache backend +- Checks for timeouts +- Deletes the test data from the cache backend +- Returns status + +This ensures your app's cache backend is functioning correctly and is always available. It not only prevents [data inconsistencies](https://www.alachisoft.com/blogs/cache-database-data-inconsistency-pitfall-and-solutions/#:~:text=Data%20inconsistency%20issues%20occur%20when,the%20cache%20is%20not%20synchronized) and [race conditions](https://www.techtarget.com/searchstorage/definition/race-condition) but also helps identify and troubleshoot cache-related problems. + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.cache` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.cache', +] +``` +4.The cache healthcheck tries to write and read a specific key within the cache backend. +It can be customized by setting `HEALTHCHECK_CACHE_KEY` in the `settings.py` file to another value: + +```python +HEALTHCHECK_CACHE_KEY = "custom_health_check_key" +``` + +5.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/contrib/celery.md b/docs/src/pages/checks/contrib/celery.md index e69de29b..4cfcbac0 100644 --- a/docs/src/pages/checks/contrib/celery.md +++ b/docs/src/pages/checks/contrib/celery.md @@ -0,0 +1,71 @@ +--- +title: Celery Health Check +pageTitle: django-health-check celery check +description: Verify the Celery tasks are executed successfully. +--- + +The `health_check.contrib.celery` verifies that the Celery tasks + can be executed successfully within a specified timeout period + +Ensure that you have celery installed and configured in your application. + +Information about how to properly configure celery with django +is [here](https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html) + + +## Settings + +The settings that need to be correct are `HEALTHCHECK_CELERY_RESULT_TIMEOUT` +and `HEALTHCHECK_CELERY_QUEUE_TIMEOUT` in your `settings.py`. + +## What does it check? + +This check does the following: + +- Checks celery worker status +- Checks that the celery workers can execute tasks +- Results are returned within specified time limits + +Celery health checks helps you catch potential issues early, ensures proper configuration, +and provides insights into the real-time status of your Celery workers. + + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.celery` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.celery', +] + +# Set the timeout for waiting for Celery task results (in seconds) +HEALTHCHECK_CELERY_RESULT_TIMEOUT = 3 # this is the default time, Adjust the value as needed + +# Set the timeout for the expiration of the Celery task in the queue (in seconds) +HEALTHCHECK_CELERY_QUEUE_TIMEOUT = 3 #this is the default time, Adjust the value as needed + +#..... other celery settings..... + +``` +4.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/contrib/celery_ping.md b/docs/src/pages/checks/contrib/celery_ping.md new file mode 100644 index 00000000..92655914 --- /dev/null +++ b/docs/src/pages/checks/contrib/celery_ping.md @@ -0,0 +1,73 @@ +--- +title: Celery Ping Health Check +pageTitle: django-health-check celery ping check +description: Verify that Celery pings Celery workers and checks the responses. +--- + +The `health_check.contrib.celery_ping` verifies that the celery +task queues have active workers. + +Ensure that you have celery installed and configured in your application. + +Information about how to properly configure celery with django +is [here](https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html) + + +## Settings + +The setting that needs to be correct is the `HEALTHCHECK_CELERY_PING_TIMEOUT` in your `settings.py`. + +## What does it check? +This check does the following: + +- Pings celery workers and checks their responses +- Verify availability of the celery workers +- Check if celery task queues have active workers + +Celery ping health checks helps you to diagnose and address problems +with Celery worker availability and correctness. + + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.celery_ping` applications +to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.celery_ping', +] + +# Set the timeout for waiting for Celery ping result (in seconds) +HEALTHCHECK_CELERY_PING_TIMEOUT = 1 # this is the default time, Adjust the value as needed + + +#..... other celery settings..... + +``` +4.Run the health check +```shell +python manage.py health_check + +``` + +**Note:** +The major difference between `health_check.contrib.celery_ping` and `health_check.contrib.celery` +is that the `health_check.contrib.celery_ping` checks for worker responsiveness and readiness while +`health_check.contrib.celery`checks on task execution health diff --git a/docs/src/pages/checks/contrib/migrations.md b/docs/src/pages/checks/contrib/migrations.md index e69de29b..d7a6f9c2 100644 --- a/docs/src/pages/checks/contrib/migrations.md +++ b/docs/src/pages/checks/contrib/migrations.md @@ -0,0 +1,52 @@ +--- +title: Migrations Health Check +pageTitle: django-health-check migrations check +description: Verify the status of your application's migrations +--- + +The `health_check.contrib.migrations` verifies that the Django application's migrations are + up-to-date and applied to the database + +## What does it check? + +This check does the following: + +- Checks for applied migrations +- Checks for pending migrations +- Checks for migration version mismatch +- Checks for Stale Content Types + +This prevents data corruption by ensuring that the schema is up to date and maintains +data integrity ensuring that it is consistent with the code. + + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.migrations` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.migrations', +] +``` +4.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/contrib/psutil.md b/docs/src/pages/checks/contrib/psutil.md index e69de29b..fd1f670d 100644 --- a/docs/src/pages/checks/contrib/psutil.md +++ b/docs/src/pages/checks/contrib/psutil.md @@ -0,0 +1,72 @@ +--- +title: Disk and memory usage Health Check +pageTitle: django-health-check psutil check +description: Checks the disk usage and memory usage of the application +--- +The `health_check.contrib.psutil` uses the `psutil` library to to gather information +on the memory and disk usage of the application. + +Ensure you have [ `psutil`](https://psutil.readthedocs.io/en/latest/#id1) installed. + + +## Settings + +The disk and memory usage have a default setting: +```python +HEALTH_CHECK = { + 'DISK_USAGE_MAX': 90, # percent + 'MEMORY_MIN' = 100, # in MB +} +``` +They can be adjusted to the needs of the application. In case you want to disable the +above fields, set the value to `None` + +## What does it check? + +This check does the following: + +- Collect data on the current resource +- Compare collected data to the predefined threshold + +This check allows administrators to take proactive measures like resource allocation adjustments, +to maintain a healthy operating environment. Additionally, full disks and out-of-memory conditions are common causes of service outages. +These situations can be averted by checking disk and memory utilization via the psutil package. + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.psutil` applications +to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.psutil', +] + +HEALTH_CHECK = { + 'DISK_USAGE_MAX': 90, # percent + 'MEMORY_MIN' = 100, # in MB +} + +``` +4.Run the health check +```shell +python manage.py health_check + +``` + diff --git a/docs/src/pages/checks/contrib/rabbitmq.md b/docs/src/pages/checks/contrib/rabbitmq.md index e69de29b..11b78441 100644 --- a/docs/src/pages/checks/contrib/rabbitmq.md +++ b/docs/src/pages/checks/contrib/rabbitmq.md @@ -0,0 +1,66 @@ +--- +title: RabbitMQ Health Check +pageTitle: django-health-check rabbitmq check +description: Verifies that the RabbitMQ service is healthy and responsive +--- + +The `health_check.contrib.rabbitmq` verifies that the RabbitMQ service is healthy and responsive. + +Ensure that you have [RabbitMQ](https://pypi.org/project/rabbitmq/) installed. + + +## Settings + +The setting that needs to be correct is `BROKER_URL` in your `settings.py` to connect to your Rabbit server. + +```python +BROKER_URL = "amqp://myuser:mypassword@localhost:5672/myvhost" +``` + +## What does it check? + +This check does the following: + +- Retrieves the Broker URL +- Establish connection to the RabbitMQ broker +- Opens channel for connection and checks if new channels can be created + +Through performing this checks, potential issues with RabbitMQ are identified and corrective action taken to +maintain health and stability of the application. + + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.rabbitmq` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.rabbitmq', +', +] + +BROKER_URL = "amqp://myuser:mypassword@localhost:5672/myvhost" + +``` + +4.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/contrib/redis.md b/docs/src/pages/checks/contrib/redis.md index e69de29b..876a31c8 100644 --- a/docs/src/pages/checks/contrib/redis.md +++ b/docs/src/pages/checks/contrib/redis.md @@ -0,0 +1,64 @@ +--- +title: Redis Health Check +pageTitle: django-health-check redis check +description: Verifies that the Redis service is healthy and responsive +--- + +The `health_check.contrib.redis` verifies that the Redis service is healthy and responsive. + +Ensure that you have [Redis](https://pypi.org/project/redis/) installed. + +## Settings + +The setting that needs to be correct is `REDIS_URL` in your `settings.py` to connect to your Redis server. + +```python +REDIS_URL = "redis://localhost:6370" +``` + +## What does it check? + +This check does the following: + +- Retrieves Redis URL from the settings +- Connects to the Redis instance +- Pings the Redis instance + +Through performing this checks, potential issues with Redis are identified and corrective action taken to +maintain health and stability of the application. + + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.redis` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.redis', +] + +REDIS_URL = "redis://localhost:6370" + +``` + +4.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/contrib/s3boto3_storage.md b/docs/src/pages/checks/contrib/s3boto3_storage.md deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/src/pages/checks/contrib/s3boto_storage.md b/docs/src/pages/checks/contrib/s3boto_storage.md new file mode 100644 index 00000000..96ac9945 --- /dev/null +++ b/docs/src/pages/checks/contrib/s3boto_storage.md @@ -0,0 +1,60 @@ +--- +title: S3boto Storage Health Check +pageTitle: django-health-check S3boto3 Storage check +description: Checks to ensure the storage backend is functioning correctly +--- +The `health_check.contrib.s3boto3_storage` uses the `boto3` library to interact with AWS +S3 and perform a series of checks to ensure the storage backend is functioning correctly. + +Ensure you have installed [`boto3`](https://pypi.org/project/boto3/). + +For cloud-based static and media file storage on platforms like Amazon and Heroku, the recommended backend is +[S3BotoStorage](https://github.com/jschneier/django-storages/blob/master/storages/backends/s3boto3.py), +which is part of [`django-storages`](https://git.io/v1lGx) package. + +**Note:** +If you are using `boto 2.x.x` use `health_check.contrib.s3boto_storage` + + +## What does it check? + +This check does the following: + +- Tests the status of an Amazon S3 storage backend +- Tests the ability to delete a file from the S3 storage. + +This check ensures that the storage backend is functioning properly and that files can be removed from S3 storage +when needed. + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.contrib.s3boto3_storage` applications +to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.contrib.s3boto3_storage', +] +``` +4.Run the health check +```shell +python manage.py health_check + +``` + diff --git a/docs/src/pages/checks/db.md b/docs/src/pages/checks/db.md index c01b627c..863612f7 100644 --- a/docs/src/pages/checks/db.md +++ b/docs/src/pages/checks/db.md @@ -5,7 +5,7 @@ description: Verify your Django application is able to communicate with the data --- The `health_check.db` health check verifies that both Django and your database -server are both configured properly and functioning properly. +server are both configured and functioning properly. ## Settings @@ -14,15 +14,52 @@ settings in your `settings.py`. ## What does it check? -This check specifically does the following: +This check does the following: -- It creates a new row in a Django ORM model for this app -- It then updates that row with a new value -- It then deletes the row +- Creates a new row in a Django ORM model for this app +- Updates that row with a new value +- Deletes the row This ensures your app can communicate with the database and that it's able to write new rows. -The idea being if you can write and update a row in a specific Django model -your app can most likely read and write rows to any of it's models without -issue. \ No newline at end of file +The idea is if you can write and update a row in a specific Django model +your app can most likely read and write rows to any of it's models without an +issue. + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.db` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.db', +] +``` + +4.Run migrations +```shell + python manage.py migrate +``` + +5.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/checks/storage.md b/docs/src/pages/checks/storage.md index e69de29b..d918abbf 100644 --- a/docs/src/pages/checks/storage.md +++ b/docs/src/pages/checks/storage.md @@ -0,0 +1,59 @@ +--- +title: Storage Health Check +pageTitle: django-health-check storage check +description: Verify the health of your django application's storage +--- + +The `health_check.storage` verifies that the Django application's storage backend is working +as should. + +## Settings + +The settings that need to be correct are the standard Django `STORAGES` +settings in your `settings.py`. +The default storage settings can be found +[here](https://docs.djangoproject.com/en/4.2/ref/settings/#storages) + +## What does it check? + +This check does the following: + +- Reads the storage backend's configuration +- Writes to the storage backend +- Reads from the storage backend +- Checks for timeouts +- Deletes the test file from the storage backend +- Return status + +This ensures your app's storage backend is functioning correctly and detects any storage issues that may affect performance. + +## Steps +1.Installation + ```shell +#requirements.txt +django-health-check == x.x.x +``` + +2.Configure your health check URL endpoint: + +```python +urlpatterns = [ + # ... your existing URLs here ... + url(r'^health/', include('health_check.urls')), +] +``` + +3.Add the `health_check.storage` applications to your `INSTALLED_APPS`: + +```python +INSTALLED_APPS = [ + # ... + 'health_check', + 'health_check.storage', +] +``` +4.Run the health check +```shell +python manage.py health_check + +``` \ No newline at end of file diff --git a/docs/src/pages/customize-output.md b/docs/src/pages/customize-output.md index e69de29b..c9b9fe30 100644 --- a/docs/src/pages/customize-output.md +++ b/docs/src/pages/customize-output.md @@ -0,0 +1,46 @@ +--- +title: Custom django-health-check output +pageTitle: Writing custom django-health-check output +description: How to write your own health checks output. +--- +Customizing your output comes in handy when you need to match the needs your +application or integrate with specific frontend tools and monitoring tools + +You can customize your output (HTML or JSON) rendering by inheriting from MainView in +`health_check.views` and customize the `template_name`,` get`, `render_to_response `and + `render_to_response_json` properties: + +```python +# views.py +from health_check.views import MainView + +class HealthCheckCustomView(MainView): + template_name = 'myapp/health_check_dashboard.html' # customize the used templates + + def get(self, request, *args, **kwargs): + plugins = [] + status = 200 # needs to be filled status you need + # ... + if 'application/json' in request.META.get('HTTP_ACCEPT', ''): + return self.render_to_response_json(plugins, status) + return self.render_to_response(plugins, status) + + def render_to_response(self, plugins, status): # customize HTML output + return HttpResponse('COOL' if status == 200 else 'SWEATY', status=status) + + def render_to_response_json(self, plugins, status): # customize JSON output + return JsonResponse( + {str(p.identifier()): 'COOL' if status == 200 else 'SWEATY' for p in plugins}, + status=status + ) +``` + +```python +# urls.py +import views + +urlpatterns = [ + # ... + url(r'^ht/$', views.HealthCheckCustomView.as_view(), name='health_check_custom'), +] +``` diff --git a/docs/src/pages/how-to-contribute.md b/docs/src/pages/how-to-contribute.md index be889348..fe4c758f 100644 --- a/docs/src/pages/how-to-contribute.md +++ b/docs/src/pages/how-to-contribute.md @@ -1,35 +1,33 @@ --- -title: How to contribute to django-health-check checks -pageTitle: Contributing to django-health-check checks -description: Learn how to suggest new features, report bugs, and contribute code to the django-health-check project itself. +title: How to contribute to django-health-check +pageTitle: Contributing to django-health-check +description: How to suggest new features, report bugs, and make code contributions to the django-health-check project. --- -We welcome contributions, however you should react out in a [github issue](https://github.com/revsys/django-health-check/issues) before spending considerable time implementing a -new feature or check to ensure it's something we would be willing to accept. +We welcome contributions, however you should first react to a [github issue](https://github.com/revsys/django-health-check/issues) +or equally check in with us to ensure it's something we would be willing to accept. -We don't want anyone wasting time on something that doesn't seem to fit with -the goals of the project. +We would hate for you to waste time working on something that does not align with our project goals. ## Reporting Bugs -If you happen to find a bug in django-health-check, please give us a [detailed -report as an issue](https://github.com/revsys/django-health-check/issues). The -more information you can provide the better, but at a minimum you should include -the following information: +If you find a bug in django-health-check, please give us a [detailed +report as an issue](https://github.com/revsys/django-health-check/issues). Please provide as +much as information as possible. The following information **must** be included: - Version of Python in use - Version of Django in use - Version of django-health-check impacted - Detailed description of the problem - Any stacktraces you've collected -- Anything else you think may be useful to us in debuggin it +- Anything else you think may be useful to us in debugging it ## Reporting Security Issues -If you think you've found a security related issue that isn't appropriate to +If you find a security related issue that isn't appropriate to discuss on a Github issue, please [email us](mailto:frank@revsys.com) directly. ## Questions -Questions should also be directed to your [Github issue board](https://github.com/revsys/django-health-check/issues). \ No newline at end of file +Questions should also be directed to our [Github issue board](https://github.com/revsys/django-health-check/issues). \ No newline at end of file diff --git a/docs/src/pages/index.md b/docs/src/pages/index.md index c00b6a2b..3c03c852 100644 --- a/docs/src/pages/index.md +++ b/docs/src/pages/index.md @@ -1,7 +1,7 @@ --- title: Getting started pageTitle: django-health-check Documentation -description: Don't just check the port is open, check that it works. django-health-check tests that you can read and write to your DB, that your cache is working, Celery, or you can even write your own health checks. +description: Don't just check if the port is open, check to ensure it works. django-health-check tests that you can read and write to your DB, that your cache is working, Celery, or you can write your own health checks. --- Learn how to setup up django-health-check and write your own custom health checks {% .lead %} @@ -10,38 +10,35 @@ Learn how to setup up django-health-check and write your own custom health check {% quick-link title="Installation" icon="installation" href="/install" description="Step-by-step guides to installing the library." /%} -{% quick-link title="What are health checks?" icon="presets" href="/why" description="Learn why health checks are so important to a well run Django app." /%} +{% quick-link title="What are health checks?" icon="presets" href="/why" description="Learn why health checks are important to a well run Django app." /%} -{% quick-link title="Write your own checks" icon="plugins" href="/writing-your-own-checks" description="How to write your own health checks for Django." /%} +{% quick-link title="Write your own checks" icon="plugins" href="/writing-your-own-checks" description="How to write your own custom health checks for Django." /%} {% quick-link title="Included Health Checks" icon="theming" href="/checks" description="All of the standard and contrib checks included." /%} {% /quick-links %} -Possimus saepe veritatis sint nobis et quam eos. Architecto consequatur odit perferendis fuga eveniet possimus rerum cumque. Ea deleniti voluptatum deserunt voluptatibus ut non iste. - --- ## Quick start -Getting started with django-health-check is easy, but don't dismiss the power of writing your own health checks. +Getting started with django-health-check is simple, but don't overlook the benefits of writing your own health checks. ### Installing django-health-check -To install django-health-check you need to use pip. +To install `django-health-check` you need to use [pip](https://pypi.org/project/pip/). ```shell pip install django-health-check ``` -You should preferably pin this dependency to the specific version in your pip requirements like this: +Pin this dependency to the specific version in your `requirements.txt` file like this: ``` -# requirements.txt django-health-check==3.17.0 ``` -Once it is installed you need to add the checks you want to use to your Django settings. Find -your settings.py file and add these to your `INSTALLED_APPS`. +Once installed, add the checks you want to use to your Django settings. In +your `settings.py` file add these in your `INSTALLED_APPS`. ```python INSTALLED_APPS = [ @@ -56,11 +53,10 @@ INSTALLED_APPS = [ ## Which checks you should be using? Depending on your specific Django project, you should include other checks from -both the standard and contrib modules. Ideally, you would write custom checks +both the standard and contrib modules. Ideally, you should write custom checks for all of the services your application needs to function properly. -Does your app use Celery? Then you should use the Celery related checks. Are -you using Redis? Then you should use the Redis check. +Does your app use Celery? Use the Celery related checks. Are you using Redis? Use the Redis checks. -Using something not covered in the library like Kafka? You should [write your -own health checks](/writing-your-own-checks) that verify you can interact with Kafka the way your app needs. \ No newline at end of file +If you are using something not covered in the library like Kafka? You should [write your +own health checks](/writing-your-own-checks) to verify that you can interact with Kafka the way your app needs. \ No newline at end of file diff --git a/docs/src/pages/install.md b/docs/src/pages/install.md index 73f0661a..ad4b1347 100644 --- a/docs/src/pages/install.md +++ b/docs/src/pages/install.md @@ -4,22 +4,24 @@ pageTitle: django-health-check - Installation description: How to install and set up django-health-check --- -Installing and setting up django-health-check is relatively straight forward. +Installing and setting up django-health-check is straight forward. -First, you will need to install the library from PyPI: +First, you will need to install the library from [PyPI](https://pypi.org/project/django-health-check/): ```shell pip install django-health-check ``` -Since you are someone who takes their Django application's health seriously, -you will want to pin the version of this library in your requirements.txt to -avoid a newer version of the library accidentally breaking things when it is -released. +Pin the version of the library in your `requirements.txt` to avoid accidental breaking from a newer version of the library. + +```shell +#requirements.txt +django-health-check == x.x.x +``` ## Setup the URLs -After it is installed you need to configure your health check URL endpoint: +After installation configure your health check URL endpoint: ```python urlpatterns = [ @@ -28,15 +30,15 @@ urlpatterns = [ ] ``` -Keep in mind, you don't have to call your endpoint `/health/` you could use -`/ht/`, `/_checks/` or any name you like. +_*Note, you don't have to call your endpoint `/health/` you could use +`/ht/`, `/_checks/` or any name you prefer.*_ ## Configuring checks in Django Settings -The way you enable individual health checks is by including them in your -project's `INSTALLED_APPS` setting, so find it in your `settings.py` file. +To enable individual health checks include them in your +project's `INSTALLED_APPS` in the `settings.py` file. -To setup up a normal minimal set up of django-health-check add this to your +To setup up a normal minimal set up of `django-health-check` add this to your `INSTALLED_APPS`: ```python @@ -48,12 +50,12 @@ INSTALLED_APPS = [ ] ``` -This will include checking of both your database and cache subsystems are working -and available. +This performs checks for your database and cache subsystems to confirm they are available and working. {% callout title="NOTE!" %} -The first entry, `health_check`, is needed even if you do not plan to use any of the included -health checks and only plan to use ones you have written. This is how -the system loads and runs all other health checks. + +The first entry, `health_check`, is needed whether or not you plan to use any of the included +health checks. This is how the system loads and runs all other health checks. + {% /callout %} diff --git a/docs/src/pages/management-command.md b/docs/src/pages/management-command.md index e69de29b..c461c5b9 100644 --- a/docs/src/pages/management-command.md +++ b/docs/src/pages/management-command.md @@ -0,0 +1,20 @@ +--- +title: Management Command +pageTitle: Management command +description: How to run your health checks +--- + +You can run the Django command `health_check` to perform your health checks via the command line, +or periodically with a cron, as follow: + +```shell +python manage.py health_check +``` + +This should yield the following output: + +```shell +DatabaseHealthCheck ... working +CustomHealthCheck ... unavailable: Something went wrong! +``` +A critical error will cause the command to quit with the exit code 1. diff --git a/docs/src/pages/monitoring.md b/docs/src/pages/monitoring.md index e69de29b..760eaffb 100644 --- a/docs/src/pages/monitoring.md +++ b/docs/src/pages/monitoring.md @@ -0,0 +1,50 @@ +--- +title: External Monitoring +pageTitle: setting up monitoring +description: How to setup external monitoring +--- + +You can use tools like [Pingdom](https://www.solarwinds.com/pingdom), [StatusCake](https://www.statuscake.com/) +or other uptime robots to monitor service status. + +The `/ht/` endpoint will respond with an `HTTP 200` if all checks passed and with an `HTTP 500` +if any of the tests failed. + +## Getting machine-readable JSON reports + +If you want machine-readable status reports you can request the `/ht/ `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: + +```python +$ curl -v -X GET -H "Accept: application/json" http://www.example.com/ht/ + +> GET /ht/ 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/ht/?format=json + +> GET /ht/?format=json HTTP/1.1 +> Host: www.example.com +> +< HTTP/1.1 200 OK +< Content-Type: application/json + +{ + "CacheBackend": "working", + "DatabaseBackend": "working", + "S3BotoStorageHealthCheck": "working" +} +``` + diff --git a/docs/src/pages/production.md b/docs/src/pages/production.md index b7333f2d..69f5c498 100644 --- a/docs/src/pages/production.md +++ b/docs/src/pages/production.md @@ -4,38 +4,37 @@ pageTitle: Production Considerations for django-health-check description: Using django-health-check in production has a few small things to consider. --- -Each health check you add does some work to determine if that subsystem is up -and running. +Each health check you add determines if that subsystem is up and running. For example, `health_check.db` creates a new row in the database, -updates it's value, and then deletes it. This obviously runs three SQL queries +updates it's value, and then deletes it. This runs three SQL queries against your database. Similarly, `health_check.cache` sets a value in your -cache backend and then retrives it again, verifying the value matches. +cache backend and then retrieves it again, verifying that the value matches. While none of these checks on their own do a **LOT** of work, it is still work. The tasks take time and it's easy to have a combination of tests that take many seconds to complete. Perhaps even going over the default timeouts you -have setup for your WSGI and/or webserver. +have setup for your [WSGI](https://wsgi.readthedocs.io/en/latest/what.html) and/or [webserver](https://www.digitalocean.com/community/conceptual-articles/introduction-to-web-servers). -You can solve this easily by increasing your timeouts, but there is another +You can solve this by increasing your timeouts, but there is another issue. ## Possible Denial of Service (DoS) Attack -Your healh checks can actually be used as a potential *denial of service* attack +Your health checks can be used as a potential *denial of service* attack vector. -Imagine your health checks take say 10 seconds to complete. It is trivial for -an attacker to spawn a thousand threads and ask for a thousand health checks at -once effectively swamping your Django app with health requests. +Imagine your health checks take 10 seconds to complete. +An attacker can spawn a thousand threads and ask for a thousand health checks at +once effectively overloading your Django app with health requests. ### Non-public health checks -The easiest way around this is to just **NOT** expose the health check URL -to the public Internet. You can do this by actually restricting access with -nginx (or whichever webserver you are using in front of your Django WSGI process). +The way around this is to **NOT** expose the health check URL +to the public Internet. You can do this by restricting access with +nginx (or whichever [webserver](https://www.digitalocean.com/community/conceptual-articles/introduction-to-web-servers) you are using in front of your Django [WSGI](https://wsgi.readthedocs.io/en/latest/what.html) process). -Another option is to just make your health check endpoint unguessable. So +Another option is to make your health check endpoint unguessable. So instead of: ```python @@ -53,5 +52,5 @@ urlpatterns = [ ] ``` -This greatly reduces the chances of an attacker or even simple web spidering bots +This reduces the chances of an attacker or even a simple spidering web bot to overload your app doing health checks. diff --git a/docs/src/pages/why.md b/docs/src/pages/why.md index 6e0d914b..592cdb83 100644 --- a/docs/src/pages/why.md +++ b/docs/src/pages/why.md @@ -2,4 +2,18 @@ title: Why use django-health-check? pageTitle: Why use django-health-check? description: Why should you use django-health-check over simply checking that port 80 or 443 is open? What deeper benefits does this bring to your project? ---- \ No newline at end of file +--- + +- Proactively monitor your application components, such as caches, and identify potential issues before they affect end users. + +- To enhance security by identifying potential security vulnerabilities like outdated software or misconfigured controls, to protect the application from data breaches and cyber attacks. + +- For scalability to understand how your application scales under load to identify capacity limits and plan for future growth + +- Flexibility to create your own custom health checks to match your application requirements + +- Simplifies troubleshooting by providing detailed information about the root cause of issues. + +- Alert configuration to send alerts when specific thresholds are exceeded. + +- It helps you meet the compliance requirements of your applications, e.g., uptime, performance, and security. \ No newline at end of file diff --git a/docs/src/pages/writing-your-own-checks.md b/docs/src/pages/writing-your-own-checks.md index 887f22b9..c80050d0 100644 --- a/docs/src/pages/writing-your-own-checks.md +++ b/docs/src/pages/writing-your-own-checks.md @@ -1,5 +1,53 @@ --- -title: Writing your own custom django-health-check checks -pageTitle: Writing your own custom django-health-check checks +title: Writing custom health checks +pageTitle: Writing custom health checks description: How to write your own health checks to specifically tests aspects of your system when there isn't a standard or contrib health check already available. ---- \ No newline at end of file +--- + +Custom Django health checks is necessary for implementing application-specific checks, +monitoring external dependencies, and validating legacy system integrations. + +## Template to write custom health checks + +Start with this code + +```python + +from health_check.backends import BaseHealthCheckBackend + +class MyHealthCheckBackend(BaseHealthCheckBackend): + #: The status endpoints will respond with a 200 status code + #: even if the check errors. + critical_service = False + + def check_status(self): + # The test code goes here. + # You can use `self.add_error` or + # raise a `HealthCheckException`, + # similar to Django's form validation. + pass + + def identifier(self): + return self.__class__.__name__ # Display name on the endpoint. +``` + +After writing a custom checker, register it in your app configuration: + +```python +from django.apps import AppConfig + +from health_check.plugins import plugin_dir + +class MyAppConfig(AppConfig): + name = 'my_app' + + def ready(self): + from .backends import MyHealthCheckBackend + plugin_dir.register(MyHealthCheckBackend) + +``` + +***Note:*** +The application you write the checker into should already be registered in your `INSTALLED_APPS`. + +Remember to adapt the code based on your specific application requirements and the type of health check you want to perform. \ No newline at end of file