Skip to content

Commit 9ad0d65

Browse files
authored
feat: add more light weight database check (#439)
* feat: add db_heartbeat * feat: add tests * feat: add ignore .DS_Store * fix: linting errors * fix: linting errors * fix: linting errors * feat: remove .ds_store * feat: add tests * fix: test linting * feat: fix incorrect imports * feat: add test mocking * fix: linting * fix: linting * fix: tests * fix: linting * feat: update docs
1 parent fe82b26 commit 9ad0d65

File tree

7 files changed

+70
-0
lines changed

7 files changed

+70
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,6 @@ ENV/
105105

106106
.envrc
107107
.direnv
108+
109+
# mac
108110
.DS_Store

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The following health checks are bundled with this project:
2020
- Celery ping
2121
- RabbitMQ
2222
- Migrations
23+
- Database Heartbeat (Lightweight version of `health_check.db`)
2324

2425
Writing your own custom health checks is also very quick and easy.
2526

@@ -74,6 +75,7 @@ Add the `health_check` applications to your `INSTALLED_APPS`:
7475
'health_check.contrib.s3boto3_storage', # requires boto3 and S3BotoStorage backend
7576
'health_check.contrib.rabbitmq', # requires RabbitMQ broker
7677
'health_check.contrib.redis', # requires Redis broker
78+
'health_check.contrib.db_heartbeat',
7779
]
7880
```
7981

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import django
2+
3+
if django.VERSION < (3, 2):
4+
default_app_config = "health_check.contrib.db_heartbeat.apps.HealthCheckConfig"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.apps import AppConfig
2+
3+
from health_check.plugins import plugin_dir
4+
5+
6+
class HealthCheckConfig(AppConfig):
7+
name = "health_check.contrib.db_heartbeat"
8+
9+
def ready(self):
10+
from .backends import DatabaseHeartBeatCheck
11+
12+
plugin_dir.register(DatabaseHeartBeatCheck)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from django.db import connection
2+
3+
from health_check.backends import BaseHealthCheckBackend
4+
from health_check.exceptions import ServiceUnavailable
5+
6+
7+
class DatabaseHeartBeatCheck(BaseHealthCheckBackend):
8+
"""Health check that runs a simple SELECT 1; query to test if the database connection is alive."""
9+
10+
def check_status(self):
11+
try:
12+
result = None
13+
with connection.cursor() as cursor:
14+
cursor.execute("SELECT 1;")
15+
result = cursor.fetchone()
16+
17+
if result != (1,):
18+
raise ServiceUnavailable(
19+
"Health Check query did not return the expected result."
20+
)
21+
except Exception as e:
22+
raise ServiceUnavailable(f"Database health check failed: {e}")

tests/test_db_heartbeat.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import unittest
2+
from unittest.mock import MagicMock, patch
3+
4+
from health_check.contrib.db_heartbeat.backends import DatabaseHeartBeatCheck
5+
from health_check.exceptions import ServiceUnavailable
6+
7+
8+
class TestDatabaseHeartBeatCheck(unittest.TestCase):
9+
@patch("health_check.contrib.db_heartbeat.backends.connection")
10+
def test_check_status_success(self, mock_connection):
11+
mock_cursor = MagicMock()
12+
mock_cursor.fetchone.return_value = (1,)
13+
mock_connection.cursor.return_value.__enter__.return_value = mock_cursor
14+
15+
health_check = DatabaseHeartBeatCheck()
16+
try:
17+
health_check.check_status()
18+
except Exception as e:
19+
self.fail(f"check_status() raised an exception unexpectedly: {e}")
20+
21+
@patch("health_check.contrib.db_heartbeat.backends.connection")
22+
def test_check_status_service_unavailable(self, mock_connection):
23+
mock_connection.cursor.side_effect = Exception("Database error")
24+
25+
health_check = DatabaseHeartBeatCheck()
26+
with self.assertRaises(ServiceUnavailable):
27+
health_check.check_status()

tests/testapp/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"health_check.contrib.migrations",
3131
"health_check.contrib.celery_ping",
3232
"health_check.contrib.s3boto_storage",
33+
"health_check.contrib.db_heartbeat",
3334
"tests",
3435
)
3536

0 commit comments

Comments
 (0)