Commit ab676d9d by David Ormsbee

Merge pull request #952 from MITx/vik/add_instrumentation

Vik/add instrumentation
parents a5085565 dba04ab6
...@@ -39,6 +39,8 @@ from collections import namedtuple ...@@ -39,6 +39,8 @@ from collections import namedtuple
from courseware.courses import get_courses_by_university from courseware.courses import get_courses_by_university
from courseware.access import has_access from courseware.access import has_access
from statsd import statsd
log = logging.getLogger("mitx.student") log = logging.getLogger("mitx.student")
Article = namedtuple('Article', 'title url author image deck publication publish_date') Article = namedtuple('Article', 'title url author image deck publication publish_date')
...@@ -204,7 +206,13 @@ def change_enrollment(request): ...@@ -204,7 +206,13 @@ def change_enrollment(request):
return {'success': False, return {'success': False,
'error': 'enrollment in {} not allowed at this time' 'error': 'enrollment in {} not allowed at this time'
.format(course.display_name)} .format(course.display_name)}
org, course_num, run=course_id.split("/")
statsd.increment("common.student.enrollment",
tags=["org:{0}".format(org),
"course:{0}".format(course_num),
"run:{0}".format(run)])
enrollment, created = CourseEnrollment.objects.get_or_create(user=user, course_id=course.id) enrollment, created = CourseEnrollment.objects.get_or_create(user=user, course_id=course.id)
return {'success': True} return {'success': True}
...@@ -212,6 +220,13 @@ def change_enrollment(request): ...@@ -212,6 +220,13 @@ def change_enrollment(request):
try: try:
enrollment = CourseEnrollment.objects.get(user=user, course_id=course_id) enrollment = CourseEnrollment.objects.get(user=user, course_id=course_id)
enrollment.delete() enrollment.delete()
org, course_num, run=course_id.split("/")
statsd.increment("common.student.unenrollment",
tags=["org:{0}".format(org),
"course:{0}".format(course_num),
"run:{0}".format(run)])
return {'success': True} return {'success': True}
except CourseEnrollment.DoesNotExist: except CourseEnrollment.DoesNotExist:
return {'success': False, 'error': 'You are not enrolled for this course.'} return {'success': False, 'error': 'You are not enrolled for this course.'}
...@@ -260,7 +275,9 @@ def login_user(request, error=""): ...@@ -260,7 +275,9 @@ def login_user(request, error=""):
log.info("Login success - {0} ({1})".format(username, email)) log.info("Login success - {0} ({1})".format(username, email))
try_change_enrollment(request) try_change_enrollment(request)
statsd.increment("common.student.successful_login")
return HttpResponse(json.dumps({'success': True})) return HttpResponse(json.dumps({'success': True}))
log.warning("Login failed - Account not active for user {0}, resending activation".format(username)) log.warning("Login failed - Account not active for user {0}, resending activation".format(username))
...@@ -466,7 +483,9 @@ def create_account(request, post_override=None): ...@@ -466,7 +483,9 @@ def create_account(request, post_override=None):
log.debug('bypassing activation email') log.debug('bypassing activation email')
login_user.is_active = True login_user.is_active = True
login_user.save() login_user.save()
statsd.increment("common.student.account_created")
js = {'success': True} js = {'success': True}
return HttpResponse(json.dumps(js), mimetype="application/json") return HttpResponse(json.dumps(js), mimetype="application/json")
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
# #
# Used by responsetypes and capa_problem # Used by responsetypes and capa_problem
class CorrectMap(object): class CorrectMap(object):
""" """
Stores map between answer_id and response evaluation result for each question Stores map between answer_id and response evaluation result for each question
......
...@@ -28,6 +28,8 @@ from xmodule.x_module import ModuleSystem ...@@ -28,6 +28,8 @@ from xmodule.x_module import ModuleSystem
from xmodule.error_module import ErrorDescriptor, NonStaffErrorDescriptor from xmodule.error_module import ErrorDescriptor, NonStaffErrorDescriptor
from xmodule_modifiers import replace_course_urls, replace_static_urls, add_histogram, wrap_xmodule from xmodule_modifiers import replace_course_urls, replace_static_urls, add_histogram, wrap_xmodule
from statsd import statsd
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
...@@ -382,6 +384,15 @@ def xqueue_callback(request, course_id, userid, id, dispatch): ...@@ -382,6 +384,15 @@ def xqueue_callback(request, course_id, userid, id, dispatch):
if instance_module.grade != oldgrade or instance_module.state != old_instance_state: if instance_module.grade != oldgrade or instance_module.state != old_instance_state:
instance_module.save() instance_module.save()
#Bin score into range and increment stats
score_bucket=get_score_bucket(instance_module.grade, instance_module.max_grade)
org, course_num, run=course_id.split("/")
statsd.increment("lms.courseware.question_answered",
tags=["org:{0}".format(org),
"course:{0}".format(course_num),
"run:{0}".format(run),
"score_bucket:{0}".format(score_bucket),
"type:xqueue"])
return HttpResponse("") return HttpResponse("")
...@@ -466,6 +477,17 @@ def modx_dispatch(request, dispatch, location, course_id): ...@@ -466,6 +477,17 @@ def modx_dispatch(request, dispatch, location, course_id):
instance_module.max_grade != old_instance_max_grade): instance_module.max_grade != old_instance_max_grade):
instance_module.save() instance_module.save()
#Bin score into range and increment stats
score_bucket=get_score_bucket(instance_module.grade, instance_module.max_grade)
org, course_num, run=course_id.split("/")
statsd.increment("lms.courseware.question_answered",
tags=["org:{0}".format(org),
"course:{0}".format(course_num),
"run:{0}".format(run),
"score_bucket:{0}".format(score_bucket),
"type:ajax"])
if shared_module is not None: if shared_module is not None:
shared_module.state = instance.get_shared_state() shared_module.state = instance.get_shared_state()
if shared_module.state != old_shared_state: if shared_module.state != old_shared_state:
...@@ -511,4 +533,17 @@ def preview_chemcalc(request): ...@@ -511,4 +533,17 @@ def preview_chemcalc(request):
return HttpResponse(json.dumps(result)) return HttpResponse(json.dumps(result))
def get_score_bucket(grade,max_grade):
"""
Function to split arbitrary score ranges into 3 buckets.
Used with statsd tracking.
"""
score_bucket="incorrect"
if(grade>0 and grade<max_grade):
score_bucket="partial"
elif(grade==max_grade):
score_bucket="correct"
return score_bucket
...@@ -50,3 +50,4 @@ pygraphviz ...@@ -50,3 +50,4 @@ pygraphviz
-r repo-requirements.txt -r repo-requirements.txt
pil pil
nltk nltk
dogstatsd-python
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment