diff --git a/watchman/templates/watchman/dashboard.html b/watchman/templates/watchman/dashboard.html
new file mode 100644
index 0000000..e6a81a2
--- /dev/null
+++ b/watchman/templates/watchman/dashboard.html
@@ -0,0 +1,61 @@
+{% extends "base.html" %}
+
+{% load i18n %}
+
+{% block content %}
+
System Status{% if overall_status == 'OK' %} All systems up and running!{% endif %}
+
+
+
+
+ {% trans 'Type' %} |
+ {% trans 'Name' %} |
+ {% trans 'Status' %} |
+
+
+
+ {% for type in checks %}
+ {% for thing in type.statuses %}
+
+ {{ type.type|title }} |
+ {{ thing.name|title }} |
+
+ {% if thing.status == 'OK' %}
+ {{ thing.status }} |
+
+ {% else %}
+
+
+
+
+
+
+
+
+ {{ thing.error }}
+ {{ thing.traceback }}
+
+
+
+
+
+ |
+ {% endif %}{# thing.status == 'OK' #}
+
+
+ {% endfor %}{# for thing in type.statuses #}
+ {% empty %}
+
+ No checks indicated |
+
+ {% endfor %}{# for type in checks #}
+
+
+
+Click an error button to see the full traceback
+{% endblock %}{# status_content #}
diff --git a/watchman/urls.py b/watchman/urls.py
index fdb1f57..01ec8b0 100644
--- a/watchman/urls.py
+++ b/watchman/urls.py
@@ -5,4 +5,5 @@
urlpatterns = patterns(
'',
url(r'^$', 'watchman.views.status', name="status"),
+ url(r'^dashboard/$', 'watchman.views.dashboard', name="dashboard"),
)
diff --git a/watchman/views.py b/watchman/views.py
index d2363d3..3e4ba73 100644
--- a/watchman/views.py
+++ b/watchman/views.py
@@ -3,6 +3,7 @@
from __future__ import unicode_literals
from django.http import Http404
+from django.shortcuts import render
from jsonview.decorators import json_view
from watchman.decorators import token_required
@@ -31,3 +32,47 @@ def status(request):
raise Http404('No checks found')
return response
+
+
+@token_required
+def dashboard(request):
+ check_types = []
+ checks = {}
+
+ for check in get_checks(None, None):
+ if callable(check):
+ _check = check()
+
+ for _type in _check:
+ # _check[_type] is a list of dictionaries:
+ # Example: [{'default': {'ok': True}}]
+ statuses = []
+
+ for a in _check[_type]:
+ status = {}
+
+ # Systems like storage don't have names
+ if a == 'ok':
+ status['name'] = ''
+ status['status'] = 'OK'
+ status['error'] = ''
+ status['stacktrace'] = ''
+ else:
+ for name in a:
+ status['name'] = name
+ status['status'] = 'OK' if a[name]['ok'] else 'ERROR'
+ status['error'] = a[name]['error'] if not a[name]['ok'] else ''
+ status['stacktrace'] = a[name]['stacktrace'] if not a[name]['ok'] else ''
+
+ statuses.append(status)
+
+ type_overall_status = 'OK' if all([status['status'] == 'OK' for status in statuses]) else 'ERROR'
+
+ check_types.append({
+ 'type': _type,
+ 'overall_status': type_overall_status,
+ 'statuses': statuses})
+
+ overall_status = 'OK' if all([type_status['overall_status'] == 'OK' for type_status in check_types]) else 'ERROR'
+
+ return render(request, 'watchman/dashboard.html', {'checks': check_types, 'overall_status': overall_status})