Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Redis Sentinel backend #404

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions health_check/contrib/redis_sentinel/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import django

if django.VERSION < (3, 2):
default_app_config = "health_check.contrib.redis_sentinel.apps.HealthCheckConfig"
12 changes: 12 additions & 0 deletions health_check/contrib/redis_sentinel/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.apps import AppConfig

from health_check.plugins import plugin_dir


class HealthCheckConfig(AppConfig):
name = "health_check.contrib.redis_sentinel"

def ready(self):
from .backends import RedisSentinelHealthCheck

plugin_dir.register(RedisSentinelHealthCheck)
62 changes: 62 additions & 0 deletions health_check/contrib/redis_sentinel/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import logging

from django.conf import settings
from redis import exceptions, Sentinel

from health_check.backends import BaseHealthCheckBackend
from health_check.exceptions import ServiceUnavailable

logger = logging.getLogger(__name__)


class RedisSentinelHealthCheck(BaseHealthCheckBackend):
"""Health check for Redis Sentinel."""

redis_sentinels = getattr(settings, 'REDIS_SENTINELS', ())
redis_master_name = getattr(settings, 'REDIS_MASTER_NAME', 'mymaster')
redis_sentinels_healthcheck_socket_timeout = getattr(
settings, 'REDIS_SENTINELS_HEALTHCHECK_SOCKET_TIMEOUT', 1000
)

def check_status(self, subset=None):
"""Check Redis service by pinging the redis instance with a redis connection."""
logger.debug(
'Got %s as the redis_sentinels. Connecting to redis...',
self.redis_sentinels,
)

logger.debug('Attempting to connect to redis...')
try:
client = self._get_redis_client(
sentinels=self.redis_sentinels,
master_name=self.redis_master_name,
timeout=self.redis_sentinels_healthcheck_socket_timeout,
)
client.ping()
except ConnectionRefusedError as e:
self.add_error(
ServiceUnavailable(
'Unable to connect to Redis: Connection was refused.'
),
e,
)
except exceptions.TimeoutError as e:
self.add_error(
ServiceUnavailable('Unable to connect to Redis: Timeout.'), e
)
except exceptions.ConnectionError as e:
self.add_error(
ServiceUnavailable(
'Unable to connect to Redis: Connection Error'
),
e,
)
except BaseException as e:
self.add_error(ServiceUnavailable('Unknown error'), e)
else:
logger.debug('Connection established. Redis is healthy.')

@staticmethod
def _get_redis_client(sentinels, master_name, timeout):
sentinel = Sentinel(sentinels, socket_timeout=timeout)
return sentinel.master_for(master_name, socket_timeout=timeout)