def test_custom_health_overridden_identifier_check_not_failing(self): plugin_dir.register(self.ServiceUpOverriddenIdentifierCustomHealthCheck) result = self.client.get('{}?format=json&checks=test_check'.format(self.url)) self.assertEqual(result.status_code, 200) self.assertEqual(result.json(), {'test_check': 'working'})
def test_custom_health_check_failing(self): plugin_dir.register(self.ServiceDownCustomHealthCheck) result = self.client.get('{}?format=json&checks=ServiceDownCustomHealthCheck'.format(self.url)) self.assertEqual(result.status_code, 500) self.assertEqual(result.json(), {'ServiceDownCustomHealthCheck': 'unavailable: Testing service not working'})
def ready(self): from health_check.db.backends import DatabaseBackend from health_check.cache.backends import CacheBackend from health_check.contrib.celery.backends import CeleryHealthCheck from health_check.contrib.s3boto_storage.backends import S3BotoStorageHealthCheck from health_check.contrib.twilio.backends import TwilioHealthCheck plugin_dir.register(type('Database', (DatabaseBackend,), { 'description': 'The database is critical for a fully operational system' })) plugin_dir.register(type('Cache', (CacheBackend,), { 'description': 'The caching service is critical for a fully operational system' })) plugin_dir.register(type('TaskProcessing', (CeleryHealthCheck,), { 'description': 'Grade calculation, emails, text messages, and other ' 'deferred tasks', 'queues': current_app.amqp.queues })) plugin_dir.register(type('Twilio', (TwilioHealthCheck,), { 'critical': False, 'description': 'Reminders and other text message notifications', 'services': ['SMS'] })) if not settings.SERVE_LOCAL: plugin_dir.register(type('AWS', (S3BotoStorageHealthCheck,), { 'critical': False, 'description': 'Attachment and other file storage' }))
def ready(self): from .backends import CeleryBeatHealthCheck cls = getattr(settings, 'HEALTH_CHECK', {}).get('CELERY_APP', None) if cls is None: raise ImproperlyConfigured( "Set HEALTH_CHECK['CELERY_APP'] to point to celery app instance in your settings to use celery " "beat health-check (example value: 'my_project.celery.app')") module_name, class_name = cls.rsplit(".", 1) app_module = importlib.import_module(module_name) # Set initial timestamp not to fail the health-check before it runs for the first time # Don't use apply_async - otherwise, the whole initialisation will fail if celery fails try: timestamp_task() getattr(app_module, class_name).add_periodic_task( TIMEOUT, timestamp_task.s(), name='Celery health check beat', ) except Exception: # This is likely issue with the cache or with celery broker connection. Handle any exception not to let the # whole app go down - depending on cache and broker backend, different exceptions can be encountered here # # Don't try to recover from this error, health-check will be failing unless the issue is resolved. # # Don't log the exception since sometimes it is expected to fail here - i.e. when running some management # command that does not expect all the infrastructure to work pass plugin_dir.register(CeleryBeatHealthCheck)
def ready(self): from .backends import PhantomJSHealthCheck, PhantomJSWithHeaderHtmlHealthCheck if hasattr(settings, 'HEALTH_CHECK') and settings.HEALTH_CHECK.get( 'PHANTOMJS_REQUIRES_HEADER_HTML', False): plugin_dir.register(PhantomJSWithHeaderHtmlHealthCheck) else: plugin_dir.register(PhantomJSHealthCheck)
def ready(self): from .backends import CeleryHealthCheck for queue in current_app.amqp.queues: celery_class_name = 'CeleryHealthCheck' + queue.title() celery_class = type(celery_class_name, (CeleryHealthCheck,), {'queue': queue}) plugin_dir.register(celery_class)
def test_success_unsupported_accept(self, client): class SuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(SuccessBackend) response = client.get(self.url, HTTP_ACCEPT='application/octet-stream') assert response['content-type'] == 'text/html; charset=utf-8'
def test_success_accept_order__reverse(self, client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = client.get(self.url, HTTP_ACCEPT='text/html; q=0.1, application/xhtml+xml; q=0.1, application/json') assert response['content-type'] == 'application/json'
def test_format_override(self, client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = client.get(self.url + '?format=json', HTTP_ACCEPT='text/html') assert response['content-type'] == 'application/json'
def ready(self): if (hasattr(settings, "HEALTH_CHECK") and ("EMAIL_ENABLED" in settings.HEALTH_CHECK) and not settings.HEALTH_CHECK["EMAIL_ENABLED"]): pass else: from .backends import EmailBackend plugin_dir.register(EmailBackend)
def ready(self): from .backends import CeleryHealthCheck for queue in current_app.amqp.queues: celery_class_name = 'CeleryHealthCheck' + queue.title() celery_class = type(celery_class_name, (CeleryHealthCheck, ), {'queue': queue}) plugin_dir.register(celery_class)
def test_custom_health_overridden_identifier_check_not_failing(self): plugin_dir.register( self.ServiceUpOverriddenIdentifierCustomHealthCheck) result = self.client.get('{}?format=json&checks=test_check'.format( self.url)) self.assertEqual(result.status_code, 200) self.assertEqual(result.json(), {'test_check': 'working'})
def test_format_no_accept_header(self, client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = client.get(self.url) assert response.status_code == 200, response.content.decode('utf-8') assert response['content-type'] == 'text/html; charset=utf-8'
def test_success_accept_json(self, api_client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = api_client.get(self.url, HTTP_ACCEPT='application/json') assert response['content-type'] == 'application/json' assert response.status_code == 200
def test_format_no_accept_header(self, api_client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = api_client.get(self.url) assert response.status_code == 200, response.content.decode('utf-8') assert response['content-type'] == 'text/html; charset=utf-8'
def test_error(self, client): class MyBackend(BaseHealthCheckBackend): def run_check(self): self.add_error('Super Fail!') plugin_dir.reset() plugin_dir.register(MyBackend) response = client.get(self.url) assert response.status_code == 503, response.content.decode('utf-8') assert b'Super Fail!' in response.content
def test_success_accept_xhtml(self, client): class SuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(SuccessBackend) response = client.get(self.url, HTTP_ACCEPT='application/xhtml+xml') assert response['content-type'] == 'text/html; charset=utf-8' assert response.status_code == 200
def test_error_json(self, client): class JSONErrorBackend(BaseHealthCheckBackend): def run_check(self): self.add_error('JSON Error') plugin_dir.reset() plugin_dir.register(JSONErrorBackend) response = client.get(self.url, HTTP_ACCEPT='application/json') assert response.status_code == 500, response.content.decode('utf-8') assert 'JSON Error' in json.loads(response.content.decode('utf-8'))[JSONErrorBackend().identifier()]
def test_success_json(self, client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = client.get(self.url, HTTP_ACCEPT='application/json') assert response.status_code == 200, response.content.decode('utf-8') assert json.loads(response.content.decode('utf-8')) == \ {JSONSuccessBackend().identifier(): JSONSuccessBackend().pretty_status()}
def test_success_unsupported_accept(self, client): class SuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(SuccessBackend) response = client.get(self.url, HTTP_ACCEPT='application/octet-stream') assert response['content-type'] == 'text/plain' assert response.status_code == 406 assert response.content == b'Not Acceptable: Supported content types: text/html, application/json'
def test_error_param_json(self, client): class JSONErrorBackend(BaseHealthCheckBackend): def run_check(self): self.add_error('JSON Error') plugin_dir.reset() plugin_dir.register(JSONErrorBackend) response = client.get(self.url, {'format': 'json'}) assert response.status_code == 500, response.content.decode('utf-8') assert response['content-type'] == 'application/json' assert 'JSON Error' in json.loads(response.content.decode('utf-8'))[JSONErrorBackend().identifier()]
def test_error(self, api_client): class MyBackend(BaseHealthCheckBackend): def check_status(self): self.add_error('Super Fail!') plugin_dir.reset() plugin_dir.register(MyBackend) response = api_client.get(self.url) assert response.status_code == 500, response.content.decode('utf-8') assert response['content-type'] == 'text/html; charset=utf-8' assert b'Super Fail!' in response.content
def test_error(self, client): class MyBackend(BaseHealthCheckBackend): def check_status(self): self.add_error('Super Fail!') plugin_dir.reset() plugin_dir.register(MyBackend) response = client.get(self.url) assert response.status_code == 500, response.content.decode('utf-8') assert response['content-type'] == 'text/html; charset=utf-8' assert b'Super Fail!' in response.content
def ready(self): from .backends import CeleryHealthCheck if hasattr(settings, "HEALTHCHECK_CELERY_TIMEOUT"): warnings.warn("HEALTHCHECK_CELERY_TIMEOUT is depricated and may be removed in the " "future. Please use HEALTHCHECK_CELERY_RESULT_TIMEOUT and " "HEALTHCHECK_CELERY_QUEUE_TIMEOUT instead.", DeprecationWarning) for queue in current_app.amqp.queues: celery_class_name = 'CeleryHealthCheck' + queue.title() celery_class = type(celery_class_name, (CeleryHealthCheck,), {'queue': queue}) plugin_dir.register(celery_class)
def test_success_unsupported_and_supported_accept(self, api_client): class SuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(SuccessBackend) response = api_client.get( self.url, HTTP_ACCEPT='application/octet-stream, application/json; q=0.9') assert response['content-type'] == 'application/json' assert response.status_code == 200
def test_error_param_json(self, api_client): class JSONErrorBackend(BaseHealthCheckBackend): def run_check(self): self.add_error('JSON Error') plugin_dir.reset() plugin_dir.register(JSONErrorBackend) response = api_client.get(self.url, {'format': 'json'}) assert response.status_code == 500, response.content.decode('utf-8') assert response['content-type'] == 'application/json' assert 'JSON Error' in json.loads( response.content.decode('utf-8'))["data"][0]["status"]
def test_success_param_json(self, client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = client.get(self.url, {'format': 'json'}) assert response.status_code == 200, response.content.decode('utf-8') assert response['content-type'] == 'application/json' assert json.loads(response.content.decode('utf-8')) == \ {JSONSuccessBackend().identifier(): JSONSuccessBackend().pretty_status()}
def test_non_critical(self, client): class MyBackend(BaseHealthCheckBackend): critical_service = False def check_status(self): self.add_error('Super Fail!') plugin_dir.reset() plugin_dir.register(MyBackend) response = client.get(self.url) assert response.status_code == 200, response.content.decode('utf-8') assert b'Super Fail!' in response.content
def test_custom_health_check_failing(self): plugin_dir.register(self.ServiceDownCustomHealthCheck) result = self.client.get( '{}?format=json&checks=ServiceDownCustomHealthCheck'.format( self.url)) self.assertEqual(result.status_code, 500) self.assertEqual( result.json(), { 'ServiceDownCustomHealthCheck': 'unavailable: Testing service not working' })
def ready(self): # noinspection PyUnresolvedReferences import common.signals if ( "health_check" in settings.INSTALLED_APPS and "django_auth_ldap.backend.LDAPBackend" in settings.AUTHENTICATION_BACKENDS ): # pragma: no cover from common.health_checks import LdapHealthCheck from health_check.plugins import plugin_dir plugin_dir.register(LdapHealthCheck)
def ready(self): from .backends import DiskUsage, MemoryUsage # Ensure checks haven't been explicitly disabled before registering if (hasattr(settings, 'HEALTH_CHECK') and ('DISK_USAGE_MAX' in settings.HEALTH_CHECK) and (settings.HEALTH_CHECK['DISK_USAGE_MAX'] is None)): pass else: plugin_dir.register(DiskUsage) if (not hasattr(settings, 'HEALTH_CHECK') or 'DISK_USAGE_MAX' not in settings.HEALTH_CHECK or settings.HEALTH_CHECK['MEMORY_MIN'] is not None): plugin_dir.register(MemoryUsage)
def test_success_accept_order(self, api_client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = api_client.get( self.url, HTTP_ACCEPT= 'text/html, application/xhtml+xml, application/json; q=0.9, */*; q=0.1' ) assert response['content-type'] == 'text/html; charset=utf-8' assert response.status_code == 200
def ready(self): super().ready() from django.conf import settings # noqa # Autodiscover various modules defined by AlekSIS autodiscover_modules("form_extensions", "model_extensions", "checks") sitepreferencemodel = self.get_model("SitePreferenceModel") personpreferencemodel = self.get_model("PersonPreferenceModel") grouppreferencemodel = self.get_model("GroupPreferenceModel") preference_models.register(sitepreferencemodel, site_preferences_registry) preference_models.register(personpreferencemodel, person_preferences_registry) preference_models.register(grouppreferencemodel, group_preferences_registry) self._load_data_checks() from .health_checks import ( BackupJobHealthCheck, DataChecksHealthCheckBackend, DbBackupAgeHealthCheck, MediaBackupAgeHealthCheck, ) plugin_dir.register(DataChecksHealthCheckBackend) plugin_dir.register(DbBackupAgeHealthCheck) plugin_dir.register(MediaBackupAgeHealthCheck) plugin_dir.register(BackupJobHealthCheck)
def ready(self): from .backends import DiskUsage, MemoryUsage # Ensure checks haven't been explicitly disabled before registering if (hasattr(settings, 'HEALTH_CHECK') and ('DISK_USAGE_MAX' in settings.HEALTH_CHECK) and (settings.HEALTH_CHECK['DISK_USAGE_MAX'] is None)): pass else: plugin_dir.register(DiskUsage) if (hasattr(settings, 'HEALTH_CHECK') and ('DISK_USAGE_MAX' in settings.HEALTH_CHECK) and (settings.HEALTH_CHECK['MEMORY_MIN'] is None)): pass else: plugin_dir.register(MemoryUsage)
def test_warning(self, client): class MyBackend(BaseHealthCheckBackend): def check_status(self): raise ServiceWarning('so so') plugin_dir.reset() plugin_dir.register(MyBackend) response = client.get(self.url) assert response.status_code == 500, response.content.decode('utf-8') assert b'so so' in response.content, response.content HEALTH_CHECK['WARNINGS_AS_ERRORS'] = False response = client.get(self.url) assert response.status_code == 200, response.content.decode('utf-8') assert b'so so' in response.content, response.content
def ready(self): from .backends import CeleryHealthCheck # To check if we want to check just for default celery queue which is # 'celery', you don't need to define anything, else # CELERY_QUEUES = [queues used in your project] queues = getattr(settings, 'CELERY_QUEUES', []) if not queues: queues = [queue for queue in current_app.amqp.queues] for queue in queues: celery_class_name = 'CeleryHealthCheck - ' + queue.title() celery_class = type(celery_class_name, (CeleryHealthCheck,), {'queue': queue}) plugin_dir.register(celery_class)
def test_success_param_json(self, api_client): class JSONSuccessBackend(BaseHealthCheckBackend): def run_check(self): pass plugin_dir.reset() plugin_dir.register(JSONSuccessBackend) response = api_client.get(self.url, {'format': 'json'}) assert response.status_code == 200, response.content.decode('utf-8') assert response['content-type'] == 'application/json' assert json.loads(response.content.decode('utf-8')) == { "data": [{ "name": JSONSuccessBackend().identifier(), "status": JSONSuccessBackend().pretty_status(), "time_taken": None }] }
def test_warning(self, client): class MyBackend(BaseHealthCheckBackend): def check_status(self): raise ServiceWarning('so so') plugin_dir.reset() plugin_dir.register(MyBackend) response = client.get(self.url) assert response.status_code == 500, response.content.decode('utf-8') assert b'so so' in response.content, response.content HEALTH_CHECK['WARNINGS_AS_ERRORS'] = False response = client.get(self.url) assert response.status_code == 200, response.content.decode('utf-8') assert response['content-type'] == 'text/html; charset=utf-8' assert b'so so' in response.content, response.content
def ready(self): super().ready() import nautobot.extras.signals # noqa from nautobot.extras.plugins.validators import wrap_model_clean_methods try: # Wrap plugin model validator registered clean methods wrap_model_clean_methods() except ProgrammingError: # The ContentType table might not exist yet (if migrations have not been run) logger.warning( "Wrapping model clean methods for custom validators failed because " "the ContentType table was not available or populated. This is normal " "during the execution of the migration command for the first time." ) # Register the DatabaseBackend health check from nautobot.extras.health_checks import DatabaseBackend plugin_dir.register(DatabaseBackend)
import logging import sys import traceback from geonode.geoserver.helpers import check_geoserver_is_up from health_check.backends.base import ( BaseHealthCheckBackend, ServiceReturnedUnexpectedResult, ServiceUnavailable ) from health_check.plugins import plugin_dir logger = logging.getLogger(__name__) class GeoServerHealthCheck(BaseHealthCheckBackend): def check_status(self): try: check_geoserver_is_up() return True except AssertionError: logger.exception("Unknown Error") raise ServiceUnavailable("Unknown error") plugin_dir.register(GeoServerHealthCheck)
def test_should_raise_exception_when_registry_a_registrated_plugin(self): with pytest.raises(AlreadyRegistered): plugin_dir.register(FakePlugin) assert len(plugin_dir._registry) == 2
#-*- coding: utf-8 -*- from health_check.plugins import plugin_dir from health_check_storage.base import StorageHealthCheck from django.conf import settings class DefaultFileStorageHealthCheck(StorageHealthCheck): def description(self): return "Checks that the default django file storage can be written to and read from." storage = settings.DEFAULT_FILE_STORAGE plugin_dir.register(DefaultFileStorageHealthCheck)
from health_check.plugins import plugin_dir from health_check.backends.base import BaseHealthCheckBackend, ServiceUnavailable from health_check_celery.tasks import add from datetime import datetime, timedelta from time import sleep class CeleryHealthCheck(BaseHealthCheckBackend): def check_status(self): try: result = add.apply_async(args=[4, 4], expires=datetime.now() + timedelta(seconds=3), connect_timeout=3) now = datetime.now() while (now + timedelta(seconds=3)) > datetime.now(): if result.result == 8: return True sleep(0.5) except IOError: pass raise ServiceUnavailable("Unknown error") plugin_dir.register(CeleryHealthCheck)
try: expected = 'itworks' cache.set('djangohealtcheck_test', expected, 1) got = cache.get("djangohealtcheck_test") if got == expected: return True else: raise ServiceUnavailable("Cache key does not match. Got %s, expected %s" % (got, expected)) except CacheKeyWarning as e: raise ServiceReturnedUnexpectedResult("Cache key warning: %s" % e) except ValueError as e: raise ServiceReturnedUnexpectedResult("ValueError: %s" % e) except Exception as e: raise ServiceUnavailable("Unknown cache exception: %s" % e) plugin_dir.register(CacheBackendCheck) class CeleryHealthCheck(BaseHealthCheckBackend): def check_status(self): try: result = add.apply_async(args=[4, 4], expires=datetime.now() + timedelta(seconds=3), connect_timeout=3) now = datetime.now() while (now + timedelta(seconds=3)) > datetime.now(): if result.result == 8: return True sleep(0.5) except IOError: pass raise ServiceUnavailable("Celery task took > 3 seconds to complete.")
def check_status(self): try: cache.set("djangohealtcheck_test", "itworks", 1) if cache.get("djangohealtcheck_test") == "itworks": return True else: raise ServiceUnavailable("Cache key does not match") except CacheKeyWarning: raise ServiceReturnedUnexpectedResult("Cache key warning") except ValueError: raise ServiceReturnedUnexpectedResult("ValueError") except Exception: raise ServiceUnavailable("Unknown exception") plugin_dir.register(CacheBackend) ########NEW FILE######## __FILENAME__ = models ########NEW FILE######## __FILENAME__ = plugin_health_check from health_check.plugins import plugin_dir from health_check.backends.base import BaseHealthCheckBackend, ServiceUnavailable from health_check_celery.tasks import add from datetime import datetime, timedelta from time import sleep class CeleryHealthCheck(BaseHealthCheckBackend): def check_status(self): try:
def ready(self): from .backends import CacheBackend plugin_dir.register(CacheBackend)
def setup(self): plugin_dir.register(FakePlugin)
@staticmethod def get_disk_space_status(total=None, used=None, free=None): if None in [total, used, free]: total, used, free = shutil.disk_usage('/') percentage_free = ((free / total) * 100) if not percentage_free > 10.0: raise ServiceUnavailable("Only {} % free space available".format(percentage_free)) if not percentage_free > 30.0: raise ServiceReturnedUnexpectedResult("Only {} % free space available".format(percentage_free)) return True def check_status(self): return self.get_disk_space_status() plugin_dir.register(DiskSpaceHealth) class ElasticSearchHealth(BaseHealthCheckBackend): def check_status(self): urls = settings.ES_URLS try: from search import get_es_client es = get_es_client() return es.indices.exists(settings.SITE_NAME) except Exception as e: raise ServiceUnavailable("Connection Error") plugin_dir.register(ElasticSearchHealth)
def test_already_registered_exception(self): with pytest.raises(AlreadyRegistered): plugin_dir.register(FakePlugin) assert len(plugin_dir._registry) == 1
def ready(self): from .backends import S3BotoStorageHealthCheck plugin_dir.register(S3BotoStorageHealthCheck)
from django.core.cache.backends.base import CacheKeyWarning from health_check.backends.base import BaseHealthCheckBackend, ServiceUnavailable, ServiceReturnedUnexpectedResult from health_check.plugins import plugin_dir from django.core.cache import cache class CacheBackend(BaseHealthCheckBackend): def check_status(self): try: cache.set('djangohealtcheck_test', 'itworks', 1) if cache.get("djangohealtcheck_test") == "itworks": return True else: raise ServiceUnavailable("Cache key does not match") except CacheKeyWarning: raise ServiceReturnedUnexpectedResult("Cache key warning") except ValueError: raise ServiceReturnedUnexpectedResult("ValueError") except Exception: raise ServiceUnavailable("Unknown exception") plugin_dir.register(CacheBackend)
def ready(self): from .backends import DatabaseBackend plugin_dir.register(DatabaseBackend)
def setup(self): plugin_dir.reset() plugin_dir.register(FakePlugin) yield plugin_dir.reset()
def ready(self): from .backends import RabbitMQHealthCheck plugin_dir.register(RabbitMQHealthCheck)
from health_check.backends.base import BaseHealthCheckBackend, ServiceUnavailable, ServiceReturnedUnexpectedResult from health_check.models import TestModel from django.db import DatabaseError, IntegrityError from health_check.plugins import plugin_dir class DjangoDatabaseBackend(BaseHealthCheckBackend): def check_status(self): try: obj = TestModel.objects.create(title="test") obj.title = "newtest" obj.save() obj.delete() return True except IntegrityError: raise ServiceReturnedUnexpectedResult("Integrity Error") except DatabaseError: raise ServiceUnavailable("Database error") plugin_dir.register(DjangoDatabaseBackend)
def ready(self): # This really is a backend thing, but as we bundle backend with the project dir can only be done here plugin_dir.register(RQWorkerHealthCheck) plugin_dir.register(RQSchedulerHealthCheck)
def inner(func): cls = type(func.__name__, (BaseHealthCheck,), {'_wrapped': staticmethod(func)}) cls.identifier = name plugin_dir.register(cls) return func