Add status app with simple view to check celery workers
This commit is contained in:
@@ -34,6 +34,9 @@ MITX_FEATURES = {
|
||||
'STAFF_EMAIL': '', # email address for staff (eg to request course creation)
|
||||
'STUDIO_NPS_SURVEY': True,
|
||||
'SEGMENT_IO': True,
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
'ENABLE_SERVICE_STATUS': False,
|
||||
}
|
||||
ENABLE_JASMINE = False
|
||||
|
||||
|
||||
@@ -156,5 +156,8 @@ DEBUG_TOOLBAR_MONGO_STACKTRACES = True
|
||||
# disable NPS survey in dev mode
|
||||
MITX_FEATURES['STUDIO_NPS_SURVEY'] = False
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
# segment-io key for dev
|
||||
SEGMENT_IO_KEY = 'mty8edrrsg'
|
||||
|
||||
@@ -126,3 +126,5 @@ SEGMENT_IO_KEY = '***REMOVED***'
|
||||
|
||||
# disable NPS survey in test mode
|
||||
MITX_FEATURES['STUDIO_NPS_SURVEY'] = False
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
@@ -135,6 +135,12 @@ if settings.ENABLE_JASMINE:
|
||||
# # Jasmine
|
||||
urlpatterns = urlpatterns + (url(r'^_jasmine/', include('django_jasmine.urls')),)
|
||||
|
||||
|
||||
if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
|
||||
urlpatterns += (
|
||||
url(r'^status/', include('service_status.urls')),
|
||||
)
|
||||
|
||||
urlpatterns = patterns(*urlpatterns)
|
||||
|
||||
# Custom error pages
|
||||
|
||||
3
common/djangoapps/service_status/__init__.py
Normal file
3
common/djangoapps/service_status/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Stub for a Django app to report the status of various services
|
||||
"""
|
||||
25
common/djangoapps/service_status/tasks.py
Normal file
25
common/djangoapps/service_status/tasks.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Django Celery tasks for service status app
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
from dogapi import dog_stats_api
|
||||
|
||||
from djcelery import celery
|
||||
|
||||
|
||||
@celery.task
|
||||
@dog_stats_api.timed('status.service.celery.pong')
|
||||
def delayed_ping(value, delay):
|
||||
"""A simple tasks that replies to a message after a especified amount
|
||||
of seconds.
|
||||
"""
|
||||
if value == 'ping':
|
||||
result = 'pong'
|
||||
else:
|
||||
result = 'got: {0}'.format(value)
|
||||
|
||||
time.sleep(delay)
|
||||
|
||||
return result
|
||||
47
common/djangoapps/service_status/test.py
Normal file
47
common/djangoapps/service_status/test.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""Test for async task service status"""
|
||||
|
||||
from django.utils import unittest
|
||||
from django.test.client import Client
|
||||
from django.core.urlresolvers import reverse
|
||||
import json
|
||||
|
||||
|
||||
class CeleryConfigTest(unittest.TestCase):
|
||||
"""
|
||||
Test that we can get a response from Celery
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Create a django test client
|
||||
"""
|
||||
self.client = Client()
|
||||
self.ping_url = reverse('status.service.celery.ping')
|
||||
|
||||
def test_ping(self):
|
||||
"""
|
||||
Try to ping celery.
|
||||
"""
|
||||
|
||||
# Access the service status page, which starts a delayed
|
||||
# asynchronous task
|
||||
response = self.client.get(self.ping_url)
|
||||
|
||||
# HTTP response should be successful
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Expect to get a JSON-serialized dict with
|
||||
# task and time information
|
||||
result_dict = json.loads(response.content)
|
||||
|
||||
# Was it successful?
|
||||
self.assertTrue(result_dict['success'])
|
||||
|
||||
# We should get a "pong" message back
|
||||
self.assertEqual(result_dict['value'], "pong")
|
||||
|
||||
# We don't know the other dict values exactly,
|
||||
# but we can assert that they take the right form
|
||||
self.assertTrue(isinstance(result_dict['task_id'], unicode))
|
||||
self.assertTrue(isinstance(result_dict['time'], float))
|
||||
self.assertTrue(result_dict['time'] > 0.0)
|
||||
15
common/djangoapps/service_status/urls.py
Normal file
15
common/djangoapps/service_status/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Django URLs for service status app
|
||||
"""
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^$', 'service_status.views.index', name='status.service.index'),
|
||||
url(r'^celery/$', 'service_status.views.celery_status',
|
||||
name='status.service.celery.status'),
|
||||
url(r'^celery/ping/$', 'service_status.views.celery_ping',
|
||||
name='status.service.celery.ping'),
|
||||
)
|
||||
59
common/djangoapps/service_status/views.py
Normal file
59
common/djangoapps/service_status/views.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
Django Views for service status app
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
from django.http import HttpResponse
|
||||
|
||||
from dogapi import dog_stats_api
|
||||
|
||||
from service_status import tasks
|
||||
from djcelery import celery
|
||||
from celery.exceptions import TimeoutError
|
||||
|
||||
|
||||
def index(_):
|
||||
"""
|
||||
An empty view
|
||||
"""
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
@dog_stats_api.timed('status.service.celery.status')
|
||||
def celery_status(_):
|
||||
"""
|
||||
A view that returns Celery stats
|
||||
"""
|
||||
stats = celery.control.inspect().stats() or {}
|
||||
return HttpResponse(json.dumps(stats, indent=4),
|
||||
mimetype="application/json")
|
||||
|
||||
|
||||
@dog_stats_api.timed('status.service.celery.ping')
|
||||
def celery_ping(_):
|
||||
"""
|
||||
A Simple view that checks if Celery can process a simple task
|
||||
"""
|
||||
start = time.time()
|
||||
result = tasks.delayed_ping.apply_async(('ping', 0.1))
|
||||
task_id = result.id
|
||||
|
||||
# Wait until we get the result
|
||||
try:
|
||||
value = result.get(timeout=4.0)
|
||||
success = True
|
||||
except TimeoutError:
|
||||
value = None
|
||||
success = False
|
||||
|
||||
output = {
|
||||
'success': success,
|
||||
'task_id': task_id,
|
||||
'value': value,
|
||||
'time': time.time() - start,
|
||||
}
|
||||
|
||||
return HttpResponse(json.dumps(output, indent=4),
|
||||
mimetype="application/json")
|
||||
@@ -101,6 +101,9 @@ MITX_FEATURES = {
|
||||
# Turn on a page that lets staff enter Python code to be run in the
|
||||
# sandbox, for testing whether it's enabled properly.
|
||||
'ENABLE_DEBUG_RUN_PYTHON': False,
|
||||
|
||||
# Enable URL that shows information about the status of variuous services
|
||||
'ENABLE_SERVICE_STATUS': False,
|
||||
}
|
||||
|
||||
# Used for A/B testing
|
||||
|
||||
@@ -22,7 +22,7 @@ MITX_FEATURES['FORCE_UNIVERSITY_DOMAIN'] = None # show all university courses i
|
||||
MITX_FEATURES['ENABLE_MANUAL_GIT_RELOAD'] = True
|
||||
MITX_FEATURES['ENABLE_PSYCHOMETRICS'] = False # real-time psychometrics (eg item response theory analysis in instructor dashboard)
|
||||
MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
WIKI_ENABLED = True
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ MITX_FEATURES['DISABLE_START_DATES'] = True
|
||||
# Until we have discussion actually working in test mode, just turn it off
|
||||
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = False
|
||||
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
# Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
|
||||
WIKI_ENABLED = True
|
||||
|
||||
|
||||
@@ -357,6 +357,11 @@ if settings.MITX_FEATURES.get('ENABLE_SQL_TRACKING_LOGS'):
|
||||
url(r'^event_logs/(?P<args>.+)$', 'track.views.view_tracking_log'),
|
||||
)
|
||||
|
||||
if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
|
||||
urlpatterns += (
|
||||
url(r'^status/', include('service_status.urls')),
|
||||
)
|
||||
|
||||
# FoldIt views
|
||||
urlpatterns += (
|
||||
# The path is hardcoded into their app...
|
||||
|
||||
Reference in New Issue
Block a user