diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/controller_query_service.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/controller_query_service.py index 31e4962e29..c5ecc05c28 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/controller_query_service.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/controller_query_service.py @@ -1,3 +1,5 @@ +from dogapi import dog_stats_api + import logging from .grading_service_module import GradingService @@ -9,6 +11,8 @@ class ControllerQueryService(GradingService): Interface to controller query backend. """ + METRIC_NAME = 'edxapp.open_ended_grading.controller_query_service' + def __init__(self, config, system): config['system'] = system super(ControllerQueryService, self).__init__(config) @@ -25,7 +29,11 @@ class ControllerQueryService(GradingService): 'location': location, } response = self.get(self.check_eta_url, params) - return response.json() + data = response.json() + self._record_result('check_for_eta', data) + dog_stats_api.histogram(self._metric_name('check_for_eta.eta'), data.get('eta', 0)) + + return data def check_combined_notifications(self, course_id, student_id, user_is_staff, last_time_viewed): params = { @@ -36,7 +44,16 @@ class ControllerQueryService(GradingService): } log.debug(self.combined_notifications_url) response = self.get(self.combined_notifications_url, params) - return response.json() + data = response.json() + + tags = [u'course_id:{}'.format(course_id), u'user_is_staff:{}'.format(user_is_staff)] + tags.extend( + u'{}:{}'.format(key, value) + for key, value in data.items() + if key not in ('success', 'version', 'error') + ) + self._record_result('check_combined_notifications', data, tags) + return data def get_grading_status_list(self, course_id, student_id): params = { @@ -45,7 +62,16 @@ class ControllerQueryService(GradingService): } response = self.get(self.grading_status_list_url, params) - return response.json() + data = response.json() + + tags = [u'course_id:{}'.format(course_id)] + self._record_result('get_grading_status_list', data, tags) + dog_stats_api.histogram( + self._metric_name('get_grading_status_list.length'), + len(data.get('problem_list', [])), + tags=tags + ) + return data def get_flagged_problem_list(self, course_id): params = { @@ -53,7 +79,15 @@ class ControllerQueryService(GradingService): } response = self.get(self.flagged_problem_list_url, params) - return response.json() + data = response.json() + + tags = [u'course_id:{}'.format(course_id)] + self._record_result('get_flagged_problem_list', data, tags) + dog_stats_api.histogram( + self._metric_name('get_flagged_problem_list.length'), + len(data.get('flagged_submissions', [])) + ) + return data def take_action_on_flags(self, course_id, student_id, submission_id, action_type): params = { @@ -64,7 +98,11 @@ class ControllerQueryService(GradingService): } response = self.post(self.take_action_on_flags_url, params) - return response.json() + data = response.json() + + tags = [u'course_id:{}'.format(course_id), u'action_type:{}'.format(action_type)] + self._record_result('take_action_on_flags', data, tags) + return data class MockControllerQueryService(object): diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/grading_service_module.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/grading_service_module.py index 6248c63091..5d0e1b9545 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/grading_service_module.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/grading_service_module.py @@ -2,6 +2,7 @@ import json import logging import requests +from dogapi import dog_stats_api from requests.exceptions import RequestException, ConnectionError, HTTPError from .combined_open_ended_rubric import CombinedOpenEndedRubric @@ -44,6 +45,32 @@ class GradingService(object): return response.json() + def _metric_name(self, suffix): + """ + Return a metric name for datadog, using `self.METRIC_NAME` as + a prefix, and `suffix` as the suffix. + + Arguments: + suffix (str): The metric suffix to use. + """ + return '{}.{}'.format(self.METRIC_NAME, suffix) + + def _record_result(self, action, data, tags=None): + """ + Log results from an API call to an ORA service to datadog. + + Arguments: + action (str): The ORA action being recorded. + data (dict): The data returned from the ORA service. Should contain the key 'success'. + tags (list): A list of tags to attach to the logged metric. + """ + if tags is None: + tags = [] + + tags.append(u'result:{}'.format(data.get('success', False))) + tags.append(u'action:{}'.format(action)) + dog_stats_api.increment(self._metric_name('request.count'), tags=tags) + def post(self, url, data, allow_redirects=False): """ Make a post request to the grading controller