Skip to content

Commit

Permalink
Merge pull request #265 from camptocamp/health_stack
Browse files Browse the repository at this point in the history
Add the stack to health_check if the secret is passed
  • Loading branch information
Patrick Valsecchi authored Jan 22, 2019
2 parents af7d564 + 3bf8425 commit 334a6f8
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 28 deletions.
1 change: 0 additions & 1 deletion acceptance_tests/tests/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ app:
LOG_TYPE: 'console,logstash'
SQL_LOG_LEVEL: DEBUG
OTHER_LOG_LEVEL: DEBUG
DEVELOPMENT: 1
COVERAGE: 1
SENTRY_URL: https://14bdb65de3f247c4a89cc7ed53ddec72:[email protected]/5
C2C_REDIS_URL: redis://redis:6379
Expand Down
132 changes: 111 additions & 21 deletions acceptance_tests/tests/tests/test_health_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,22 @@ def test_ok(app_connection):
print('response=' + json.dumps(response))
assert _remove_timings(response) == {
'successes': {
'db_engine_sqlalchemy': {},
'db_engine_sqlalchemy_slave': {},
'http://localhost:8080/api/hello': {},
'fun_url': {},
'alembic_app_alembic.ini_alembic': {'result': '4a8c1bb4e775'}
'db_engine_sqlalchemy': {
'level': 1
},
'db_engine_sqlalchemy_slave': {
'level': 1
},
'http://localhost:8080/api/hello': {
'level': 1
},
'fun_url': {
'level': 1
},
'alembic_app_alembic.ini_alembic': {
'result': '4a8c1bb4e775',
'level': 1
}
},
'failures': {},
}
Expand All @@ -30,8 +41,12 @@ def test_filter(app_connection):
print('response=' + json.dumps(response))
assert _remove_timings(response) == {
'successes': {
'db_engine_sqlalchemy': {},
'fun_url': {}
'db_engine_sqlalchemy': {
'level': 1
},
'fun_url': {
'level': 1
}
},
'failures': {},
}
Expand All @@ -42,11 +57,22 @@ def test_empty_filter(app_connection):
print('response=' + json.dumps(response))
assert _remove_timings(response) == {
'successes': {
'db_engine_sqlalchemy': {},
'db_engine_sqlalchemy_slave': {},
'http://localhost:8080/api/hello': {},
'fun_url': {},
'alembic_app_alembic.ini_alembic': {'result': '4a8c1bb4e775'}
'db_engine_sqlalchemy': {
'level': 1
},
'db_engine_sqlalchemy_slave': {
'level': 1
},
'http://localhost:8080/api/hello': {
'level': 1
},
'fun_url': {
'level': 1
},
'alembic_app_alembic.ini_alembic': {
'result': '4a8c1bb4e775',
'level': 1
}
},
'failures': {},
}
Expand All @@ -57,27 +83,91 @@ def test_failure(app_connection):
print('response=' + json.dumps(response))
assert _remove_timings(response) == {
'successes': {
'db_engine_sqlalchemy': {},
'db_engine_sqlalchemy_slave': {},
'http://localhost:8080/api/hello': {},
'fun_url': {},
'alembic_app_alembic.ini_alembic': {'result': '4a8c1bb4e775'},
'redis://redis:6379': {'result': response['successes']['redis://redis:6379']['result']},
'db_engine_sqlalchemy': {
'level': 1
},
'db_engine_sqlalchemy_slave': {
'level': 1
},
'http://localhost:8080/api/hello': {
'level': 1
},
'fun_url': {
'level': 1
},
'alembic_app_alembic.ini_alembic': {
'result': '4a8c1bb4e775',
'level': 1
},
'redis://redis:6379': {
'result': response['successes']['redis://redis:6379']['result'],
'level': 2
},
'version': {
'result': response['successes']['version']['result'],
'level': 2
}
},
'failures': {
'fail': {
'message': 'failing check',
'level': 2
},
'fail_json': {
'message': 'failing check',
'result': {
'some': 'json'
},
'level': 2
},
}
}


def test_failure_with_stack(app_connection):
response = app_connection.get_json("c2c/health_check", params={'max_level': '2', 'secret': 'changeme'},
expected_status=500)
print('response=' + json.dumps(response))
assert _remove_timings(response) == {
'successes': {
'db_engine_sqlalchemy': {
'level': 1
},
'db_engine_sqlalchemy_slave': {
'level': 1
},
'http://localhost:8080/api/hello': {
'level': 1
},
'fun_url': {
'level': 1
},
'alembic_app_alembic.ini_alembic': {
'result': '4a8c1bb4e775',
'level': 1
},
'redis://redis:6379': {
'result': response['successes']['redis://redis:6379']['result'],
'level': 2
},
'version': {
'result': response['successes']['version']['result']
'result': response['successes']['version']['result'],
'level': 2
}
},
'failures': {
'fail': {
'message': 'failing check',
'stacktrace': response['failures']['fail']['stacktrace']
'stacktrace': response['failures']['fail']['stacktrace'],
'level': 2
},
'fail_json': {
'message': 'failing check',
'result': {
'some': 'json'
},
'stacktrace': response['failures']['fail_json']['stacktrace']
'stacktrace': response['failures']['fail_json']['stacktrace'],
'level': 2
},
}
}
Expand Down
11 changes: 7 additions & 4 deletions c2cwsgiutils/health_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import traceback
from typing import Optional, Callable, Mapping, List, Tuple, Any, Union, Dict # noqa

from c2cwsgiutils import stats, _utils, broadcast, version
from c2cwsgiutils import stats, _utils, broadcast, version, auth

LOG = logging.getLogger(__name__)
ALEMBIC_HEAD_RE = re.compile(r'^([a-f0-9]+) \(head\)\n$')
Expand Down Expand Up @@ -244,6 +244,7 @@ def add_custom_check(self, name: str, check_cb: Callable[[pyramid.request.Reques

def _view(self, request: pyramid.request.Request) -> Mapping[str, Any]:
max_level = int(request.params.get('max_level', '1'))
is_auth = auth.is_auth(request)
results = {
'failures': {},
'successes': {},
Expand All @@ -258,19 +259,21 @@ def _view(self, request: pyramid.request.Request) -> Mapping[str, Any]:
try:
result = check(request)
results['successes'][name] = {
'timing': time.monotonic() - start
'timing': time.monotonic() - start,
'level': level
}
if result is not None:
results['successes'][name]['result'] = result
except Exception as e:
LOG.warning("Health check %s failed", name, exc_info=True)
failure = {
'message': str(e),
'timing': time.monotonic() - start
'timing': time.monotonic() - start,
'level': level
}
if isinstance(e, JsonCheckException) and e.json_data() is not None:
failure['result'] = e.json_data()
if os.environ.get('DEVELOPMENT', '0') != '0':
if is_auth or os.environ.get('DEVELOPMENT', '0') != '0':
failure['stacktrace'] = traceback.format_exc()
results['failures'][name] = failure

Expand Down
12 changes: 10 additions & 2 deletions c2cwsgiutils/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,22 @@ def _debug(request: pyramid.request.Request, secret: str) -> str:
def _health_check(request: pyramid.request.Request) -> str:
health_check_url = _url(request, 'c2c_health_check')
if health_check_url:
return """
secret = request.params.get('secret')
result = """
<h1>Health checks</h1>
<form action="{url}" target="_blank">
max_level: <input type="text" name="max_level" value="1">
checks: <input type="text" name="checks" value="">
""".format(url=health_check_url)

if secret is not None:
result += '<input type="hidden" name="secret" value="%s">' % secret

result += """
<input type="submit" value="OK">
</form>
""".format(url=health_check_url)
"""
return result
else:
return ""

Expand Down

0 comments on commit 334a6f8

Please sign in to comment.