Merge pull request #19420 from edx/diana/remove-datadog

Remove all references to datadog from our code.
This commit is contained in:
Diana Huang
2019-01-09 09:07:22 -05:00
committed by GitHub
44 changed files with 114 additions and 614 deletions

View File

@@ -22,7 +22,6 @@ import inspect
from importlib import import_module
from django.conf import settings
from dogapi import dog_stats_api
from track.backends import BaseBackend
@@ -81,17 +80,14 @@ def _instantiate_backend_from_name(name, options):
return backend
@dog_stats_api.timed('track.send')
def send(event):
"""
Send an event object to all the initialized backends.
"""
dog_stats_api.increment('track.send.count')
for name, backend in backends.iteritems():
with dog_stats_api.timer('track.send.backend.{0}'.format(name)):
backend.send(event)
backend.send(event)
_initialize_backends_from_django_settings()

View File

@@ -53,7 +53,6 @@ def fake_support_backend_values(name, default=None): # pylint: disable=unused-a
ZENDESK_API_KEY="dummy",
ZENDESK_CUSTOM_FIELDS={},
)
@mock.patch("util.views.dog_stats_api")
@mock.patch("util.views._ZendeskApi", autospec=True)
class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
"""
@@ -105,7 +104,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
req.user = user
return views.submit_feedback(req)
def _assert_bad_request(self, response, field, zendesk_mock_class, datadog_mock):
def _assert_bad_request(self, response, field, zendesk_mock_class):
"""
Assert that the given `response` contains correct failure data.
@@ -119,9 +118,8 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self.assertIn("error", resp_json)
# There should be absolutely no interaction with Zendesk
self.assertFalse(zendesk_mock_class.return_value.mock_calls)
self.assertFalse(datadog_mock.mock_calls)
def _test_bad_request_omit_field(self, user, fields, omit_field, zendesk_mock_class, datadog_mock):
def _test_bad_request_omit_field(self, user, fields, omit_field, zendesk_mock_class):
"""
Invoke the view with a request missing a field and assert correctness.
@@ -133,9 +131,9 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
"""
filtered_fields = {k: v for (k, v) in fields.items() if k != omit_field}
resp = self._build_and_run_request(user, filtered_fields)
self._assert_bad_request(resp, omit_field, zendesk_mock_class, datadog_mock)
self._assert_bad_request(resp, omit_field, zendesk_mock_class)
def _test_bad_request_empty_field(self, user, fields, empty_field, zendesk_mock_class, datadog_mock):
def _test_bad_request_empty_field(self, user, fields, empty_field, zendesk_mock_class):
"""
Invoke the view with an empty field and assert correctness.
@@ -148,7 +146,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
altered_fields = fields.copy()
altered_fields[empty_field] = ""
resp = self._build_and_run_request(user, altered_fields)
self._assert_bad_request(resp, empty_field, zendesk_mock_class, datadog_mock)
self._assert_bad_request(resp, empty_field, zendesk_mock_class)
def _test_success(self, user, fields):
"""
@@ -210,39 +208,34 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
expected_zendesk_calls = [mock.call.create_ticket(ticket), mock.call.update_ticket(ticket_id, ticket_update)]
self.assertEqual(zendesk_mock.mock_calls, expected_zendesk_calls)
def _assert_datadog_called(self, datadog_mock, tags):
"""Assert that datadog was called with the correct tags."""
expected_datadog_calls = [mock.call.increment(views.DATADOG_FEEDBACK_METRIC, tags=tags)]
self.assertEqual(datadog_mock.mock_calls, expected_datadog_calls)
def test_bad_request_anon_user_no_name(self, zendesk_mock_class, datadog_mock):
def test_bad_request_anon_user_no_name(self, zendesk_mock_class):
"""Test a request from an anonymous user not specifying `name`."""
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "name", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "name", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "name", zendesk_mock_class)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "name", zendesk_mock_class)
def test_bad_request_anon_user_no_email(self, zendesk_mock_class, datadog_mock):
def test_bad_request_anon_user_no_email(self, zendesk_mock_class):
"""Test a request from an anonymous user not specifying `email`."""
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "email", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "email", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "email", zendesk_mock_class)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "email", zendesk_mock_class)
def test_bad_request_anon_user_invalid_email(self, zendesk_mock_class, datadog_mock):
def test_bad_request_anon_user_invalid_email(self, zendesk_mock_class):
"""Test a request from an anonymous user specifying an invalid `email`."""
fields = self._anon_fields.copy()
fields["email"] = "This is not a valid email address!"
resp = self._build_and_run_request(self._anon_user, fields)
self._assert_bad_request(resp, "email", zendesk_mock_class, datadog_mock)
self._assert_bad_request(resp, "email", zendesk_mock_class)
def test_bad_request_anon_user_no_subject(self, zendesk_mock_class, datadog_mock):
def test_bad_request_anon_user_no_subject(self, zendesk_mock_class):
"""Test a request from an anonymous user not specifying `subject`."""
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "subject", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "subject", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "subject", zendesk_mock_class)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "subject", zendesk_mock_class)
def test_bad_request_anon_user_no_details(self, zendesk_mock_class, datadog_mock):
def test_bad_request_anon_user_no_details(self, zendesk_mock_class):
"""Test a request from an anonymous user not specifying `details`."""
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "details", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "details", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._anon_user, self._anon_fields, "details", zendesk_mock_class)
self._test_bad_request_empty_field(self._anon_user, self._anon_fields, "details", zendesk_mock_class)
def test_valid_request_anon_user(self, zendesk_mock_class, datadog_mock):
def test_valid_request_anon_user(self, zendesk_mock_class):
"""
Test a valid request from an anonymous user.
@@ -269,10 +262,9 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, ["issue_type:{}".format(fields["issue_type"])])
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
def test_valid_request_anon_user_configuration_override(self, zendesk_mock_class, datadog_mock):
def test_valid_request_anon_user_configuration_override(self, zendesk_mock_class):
"""
Test a valid request from an anonymous user to a mocked out site with configuration override
@@ -300,11 +292,10 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, ["issue_type:{}".format(fields["issue_type"])])
@data("course-v1:testOrg+testCourseNumber+testCourseRun", "", None)
@override_settings(ZENDESK_CUSTOM_FIELDS=TEST_ZENDESK_CUSTOM_FIELD_CONFIG)
def test_valid_request_anon_user_with_custom_fields(self, course_id, zendesk_mock_class, datadog_mock):
def test_valid_request_anon_user_with_custom_fields(self, course_id, zendesk_mock_class):
"""
Test a valid request from an anonymous user when configured to use Zendesk Custom Fields.
@@ -324,13 +315,11 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance.create_ticket.return_value = ticket_id
zendesk_tags = [fields["issue_type"], "LMS"]
datadog_tags = ["issue_type:{}".format(fields["issue_type"])]
zendesk_custom_fields = None
if course_id:
# FIXME the tests rely on the tags being in this specific order, which doesn't seem
# reliable given that the view builds the list by iterating over a dictionary.
zendesk_tags.insert(0, course_id)
datadog_tags.insert(0, "course_id:{}".format(course_id))
zendesk_custom_fields = [
{"id": TEST_ZENDESK_CUSTOM_FIELD_CONFIG["course_id"], "value": course_id}
]
@@ -349,19 +338,18 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, datadog_tags)
def test_bad_request_auth_user_no_subject(self, zendesk_mock_class, datadog_mock):
def test_bad_request_auth_user_no_subject(self, zendesk_mock_class):
"""Test a request from an authenticated user not specifying `subject`."""
self._test_bad_request_omit_field(self._auth_user, self._auth_fields, "subject", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._auth_user, self._auth_fields, "subject", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._auth_user, self._auth_fields, "subject", zendesk_mock_class)
self._test_bad_request_empty_field(self._auth_user, self._auth_fields, "subject", zendesk_mock_class)
def test_bad_request_auth_user_no_details(self, zendesk_mock_class, datadog_mock):
def test_bad_request_auth_user_no_details(self, zendesk_mock_class):
"""Test a request from an authenticated user not specifying `details`."""
self._test_bad_request_omit_field(self._auth_user, self._auth_fields, "details", zendesk_mock_class, datadog_mock)
self._test_bad_request_empty_field(self._auth_user, self._auth_fields, "details", zendesk_mock_class, datadog_mock)
self._test_bad_request_omit_field(self._auth_user, self._auth_fields, "details", zendesk_mock_class)
self._test_bad_request_empty_field(self._auth_user, self._auth_fields, "details", zendesk_mock_class)
def test_valid_request_auth_user(self, zendesk_mock_class, datadog_mock):
def test_valid_request_auth_user(self, zendesk_mock_class):
"""
Test a valid request from an authenticated user.
@@ -388,7 +376,6 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, [])
@data(
("course-v1:testOrg+testCourseNumber+testCourseRun", True),
@@ -398,7 +385,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
)
@unpack
@override_settings(ZENDESK_CUSTOM_FIELDS=TEST_ZENDESK_CUSTOM_FIELD_CONFIG)
def test_valid_request_auth_user_with_custom_fields(self, course_id, enrolled, zendesk_mock_class, datadog_mock):
def test_valid_request_auth_user_with_custom_fields(self, course_id, enrolled, zendesk_mock_class):
"""
Test a valid request from an authenticated user when configured to use Zendesk Custom Fields.
@@ -419,13 +406,11 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance.create_ticket.return_value = ticket_id
zendesk_tags = ["LMS"]
datadog_tags = []
zendesk_custom_fields = None
if course_id:
# FIXME the tests rely on the tags being in this specific order, which doesn't seem
# reliable given that the view builds the list by iterating over a dictionary.
zendesk_tags.insert(0, course_id)
datadog_tags.insert(0, "course_id:{}".format(course_id))
zendesk_custom_fields = [
{"id": TEST_ZENDESK_CUSTOM_FIELD_CONFIG["course_id"], "value": course_id}
]
@@ -454,7 +439,6 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, datadog_tags)
@httpretty.activate
@data(
@@ -464,7 +448,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
@unpack
@override_settings(ZENDESK_CUSTOM_FIELDS=TEST_ZENDESK_CUSTOM_FIELD_CONFIG)
@mock.patch.dict("django.conf.settings.FEATURES", dict(ENABLE_ENTERPRISE_INTEGRATION=True))
def test_valid_request_auth_user_with_enterprise_info(self, course_id, enrolled, zendesk_mock_class, datadog_mock):
def test_valid_request_auth_user_with_enterprise_info(self, course_id, enrolled, zendesk_mock_class):
"""
Test a valid request from an authenticated user with enterprise tags.
"""
@@ -480,12 +464,10 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance.create_ticket.return_value = ticket_id
zendesk_tags = ["enterprise_learner", "LMS"]
datadog_tags = ['learner_type:enterprise_learner']
zendesk_custom_fields = []
if course_id:
zendesk_tags.insert(0, course_id)
datadog_tags.insert(0, "course_id:{}".format(course_id))
zendesk_custom_fields.append({"id": TEST_ZENDESK_CUSTOM_FIELD_CONFIG["course_id"], "value": course_id})
if enrolled is not None:
enrollment = CourseEnrollmentFactory.create(
@@ -518,12 +500,11 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
ticket_update = self._build_zendesk_ticket_update(TEST_REQUEST_HEADERS, user.username)
self._test_success(user, fields)
self._assert_zendesk_called(zendesk_mock_instance, ticket_id, ticket, ticket_update)
self._assert_datadog_called(datadog_mock, datadog_tags)
@httpretty.activate
@override_settings(ZENDESK_CUSTOM_FIELDS=TEST_ZENDESK_CUSTOM_FIELD_CONFIG)
@mock.patch.dict("django.conf.settings.FEATURES", dict(ENABLE_ENTERPRISE_INTEGRATION=True))
def test_request_with_anonymous_user_without_enterprise_info(self, zendesk_mock_class, datadog_mock):
def test_request_with_anonymous_user_without_enterprise_info(self, zendesk_mock_class):
"""
Test tags related to enterprise should not be there in case an unauthenticated user.
"""
@@ -533,22 +514,13 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance = zendesk_mock_class.return_value
zendesk_mock_instance.create_ticket.return_value = ticket_id
datadog_valid_tags = ["issue_type:{}".format(self._anon_fields["issue_type"])]
datadog_invalid_tags = ['learner_type:enterprise_learner']
resp = self._build_and_run_request(user, self._anon_fields)
self.assertEqual(resp.status_code, 200)
expected_datadog_calls = [mock.call.increment(views.DATADOG_FEEDBACK_METRIC, tags=datadog_valid_tags)]
self.assertEqual(datadog_mock.mock_calls, expected_datadog_calls)
not_expected_datadog_calls = [mock.call.increment(views.DATADOG_FEEDBACK_METRIC, tags=datadog_invalid_tags)]
self.assertNotEqual(datadog_mock.mock_calls, not_expected_datadog_calls)
@httpretty.activate
@override_settings(ZENDESK_CUSTOM_FIELDS=TEST_ZENDESK_CUSTOM_FIELD_CONFIG)
@mock.patch.dict("django.conf.settings.FEATURES", dict(ENABLE_ENTERPRISE_INTEGRATION=True))
def test_tags_in_request_with_auth_user_with_enterprise_info(self, zendesk_mock_class, datadog_mock):
def test_tags_in_request_with_auth_user_with_enterprise_info(self, zendesk_mock_class):
"""
Test tags related to enterprise should be there in case the request is generated by an authenticated user.
"""
@@ -558,13 +530,11 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance = zendesk_mock_class.return_value
zendesk_mock_instance.create_ticket.return_value = ticket_id
datadog_valid_tags = ['learner_type:enterprise_learner']
resp = self._build_and_run_request(user, self._auth_fields)
self.assertEqual(resp.status_code, 200)
self._assert_datadog_called(datadog_mock, datadog_valid_tags)
def test_get_request(self, zendesk_mock_class, datadog_mock):
def test_get_request(self, zendesk_mock_class):
"""Test that a GET results in a 405 even with all required fields"""
req = self._request_factory.get("/submit_feedback", data=self._anon_fields)
req.user = self._anon_user
@@ -574,9 +544,8 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self.assertEqual(resp["Allow"], "POST")
# There should be absolutely no interaction with Zendesk
self.assertFalse(zendesk_mock_class.mock_calls)
self.assertFalse(datadog_mock.mock_calls)
def test_zendesk_error_on_create(self, zendesk_mock_class, datadog_mock):
def test_zendesk_error_on_create(self, zendesk_mock_class):
"""
Test Zendesk returning an error on ticket creation.
@@ -588,9 +557,8 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
resp = self._build_and_run_request(self._anon_user, self._anon_fields)
self.assertEqual(resp.status_code, 500)
self.assertFalse(resp.content)
self._assert_datadog_called(datadog_mock, ["issue_type:{}".format(self._anon_fields["issue_type"])])
def test_zendesk_error_on_update(self, zendesk_mock_class, datadog_mock):
def test_zendesk_error_on_update(self, zendesk_mock_class):
"""
Test for Zendesk returning an error on ticket update.
@@ -603,10 +571,9 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
zendesk_mock_instance.update_ticket.side_effect = err
resp = self._build_and_run_request(self._anon_user, self._anon_fields)
self.assertEqual(resp.status_code, 200)
self._assert_datadog_called(datadog_mock, ["issue_type:{}".format(self._anon_fields["issue_type"])])
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_FEEDBACK_SUBMISSION": False})
def test_not_enabled(self, zendesk_mock_class, datadog_mock):
def test_not_enabled(self, zendesk_mock_class):
"""
Test for Zendesk submission not enabled in `settings`.
@@ -615,7 +582,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
with self.assertRaises(Http404):
self._build_and_run_request(self._anon_user, self._anon_fields)
def test_zendesk_not_configured(self, zendesk_mock_class, datadog_mock):
def test_zendesk_not_configured(self, zendesk_mock_class):
"""
Test for Zendesk not fully configured in `settings`.
@@ -632,7 +599,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
test_case("django.conf.settings.ZENDESK_API_KEY")
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_support_backend_values)
def test_valid_request_over_email(self, zendesk_mock_class, datadog_mock): # pylint: disable=unused-argument
def test_valid_request_over_email(self, zendesk_mock_class): # pylint: disable=unused-argument
with mock.patch("util.views.send_mail") as patched_send_email:
resp = self._build_and_run_request(self._anon_user, self._anon_fields)
self.assertEqual(patched_send_email.call_count, 1)
@@ -640,7 +607,7 @@ class SubmitFeedbackTest(EnterpriseServiceMockMixin, TestCase):
self.assertEqual(resp.status_code, 200)
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_support_backend_values)
def test_exception_request_over_email(self, zendesk_mock_class, datadog_mock): # pylint: disable=unused-argument
def test_exception_request_over_email(self, zendesk_mock_class): # pylint: disable=unused-argument
with mock.patch("util.views.send_mail", side_effect=SMTPException) as patched_send_email:
resp = self._build_and_run_request(self._anon_user, self._anon_fields)
self.assertEqual(patched_send_email.call_count, 1)

View File

@@ -18,7 +18,6 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
import calc
import dogstats_wrapper as dog_stats_api
import track.views
from edxmako.shortcuts import render_to_response, render_to_string
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -368,11 +367,6 @@ def _record_feedback_in_zendesk(
return True
def _record_feedback_in_datadog(tags):
datadog_tags = [u"{k}:{v}".format(k=k, v=v) for k, v in tags.items()]
dog_stats_api.increment(DATADOG_FEEDBACK_METRIC, tags=datadog_tags)
def get_feedback_form_context(request):
"""
Extract the submitted form fields to be used as a context for
@@ -495,8 +489,6 @@ def submit_feedback(request):
custom_fields=custom_fields
)
_record_feedback_in_datadog(context["tags"])
return HttpResponse(status=(200 if success else 500))

View File

@@ -38,7 +38,6 @@ from six import text_type
import capa.safe_exec as safe_exec
import capa.xqueue_interface as xqueue_interface
import dogstats_wrapper as dog_stats_api
# specific library imports
from calc import UndefinedVariable, UnmatchedParenthesis, evaluator
from cmath import isnan
@@ -182,14 +181,14 @@ class LoncapaResponse(object):
msg = "%s: cannot have input field %s" % (
unicode(self), abox.tag)
msg += "\nSee XML source line %s" % getattr(
xml, 'sourceline', '<unavailable>')
xml, 'sourceline', '[unavailable]')
raise LoncapaProblemError(msg)
if self.max_inputfields and len(inputfields) > self.max_inputfields:
msg = "%s: cannot have more than %s input fields" % (
unicode(self), self.max_inputfields)
msg += "\nSee XML source line %s" % getattr(
xml, 'sourceline', '<unavailable>')
xml, 'sourceline', '[unavailable]')
raise LoncapaProblemError(msg)
for prop in self.required_attributes:
@@ -197,7 +196,7 @@ class LoncapaResponse(object):
msg = "Error in problem specification: %s missing required attribute %s" % (
unicode(self), prop)
msg += "\nSee XML source line %s" % getattr(
xml, 'sourceline', '<unavailable>')
xml, 'sourceline', '[unavailable]')
raise LoncapaProblemError(msg)
# ordered list of answer_id values for this response
@@ -583,7 +582,7 @@ class LoncapaResponse(object):
# First try wrapping the text in a <div> and parsing
# it as an XHTML tree
try:
response_msg_div = etree.XML('<div>%s</div>' % str(response_msg))
response_msg_div = etree.XML(HTML('<div>{}</div>').format(HTML(str(response_msg))))
# If we can't do that, create the <div> and set the message
# as the text of the <div>
@@ -2068,7 +2067,7 @@ class StringResponse(LoncapaResponse):
_ = self.capa_system.i18n.ugettext
# Translators: Separator used in StringResponse to display multiple answers.
# Example: "Answer: Answer_1 or Answer_2 or Answer_3".
separator = u' <b>{}</b> '.format(_('or'))
separator = HTML(' <b>{}</b> ').format(_('or'))
return {self.answer_id: separator.join(self.correct_answer)}
#-----------------------------------------------------------------------------
@@ -2207,7 +2206,7 @@ class CustomResponse(LoncapaResponse):
# default to no error message on empty answer (to be consistent with other
# responsetypes) but allow author to still have the old behavior by setting
# empty_answer_err attribute
msg = (u'<span class="inline-error">{0}</span>'.format(_(u'No answer entered!'))
msg = (HTML(u'<span class="inline-error">{0}</span>').format(_(u'No answer entered!'))
if self.xml.get('empty_answer_err') else '')
return CorrectMap(idset[0], 'incorrect', msg=msg)
@@ -2462,7 +2461,7 @@ class CustomResponse(LoncapaResponse):
# When we parse *msg* using etree, there needs to be a root
# element, so we wrap the *msg* text in <html> tags
msg = '<html>' + msg + '</html>'
msg = HTML('<html>{msg}</html>').format(msg=HTML(msg))
# Replace < characters
msg = msg.replace('&#60;', '&lt;')
@@ -2752,13 +2751,6 @@ class CodeResponse(LoncapaResponse):
_ = self.capa_system.i18n.ugettext
dog_stats_api.increment(xqueue_interface.XQUEUE_METRIC_NAME, tags=[
'action:update_score',
'correct:{}'.format(correct)
])
dog_stats_api.histogram(xqueue_interface.XQUEUE_METRIC_NAME + '.update_score.points_earned', points)
if not valid_score_msg:
# Translators: 'grader' refers to the edX automatic code grader.
error_msg = _('Invalid grader reply. Please contact the course staff.')
@@ -2791,7 +2783,7 @@ class CodeResponse(LoncapaResponse):
return oldcmap
def get_answers(self):
anshtml = '<span class="code-answer"><pre><code>%s</code></pre></span>' % self.answer
anshtml = HTML('<span class="code-answer"><pre><code>{}</code></pre></span>').format(self.answer)
return {self.answer_id: anshtml}
def get_initial_display(self):
@@ -2908,7 +2900,7 @@ class ExternalResponse(LoncapaResponse):
msg = '%s: Missing answer script code for externalresponse' % unicode(
self)
msg += "\nSee XML source line %s" % getattr(
self.xml, 'sourceline', '<unavailable>')
self.xml, 'sourceline', '[unavailable]')
raise LoncapaProblemError(msg)
self.tests = xml.get('tests')
@@ -2984,7 +2976,8 @@ class ExternalResponse(LoncapaResponse):
self.answer_ids), ['incorrect'] * len(idset))))
cmap.set_property(
self.answer_ids[0], 'msg',
'<span class="inline-error">%s</span>' % str(err).replace('<', '&lt;'))
Text('<span class="inline-error">{}</span>').format(str(err))
)
return cmap
awd = rxml.find('awarddetail').text
@@ -3012,8 +3005,7 @@ class ExternalResponse(LoncapaResponse):
except Exception as err: # pylint: disable=broad-except
log.error('Error %s', err)
if self.capa_system.DEBUG:
msg = '<span class="inline-error">%s</span>' % str(
err).replace('<', '&lt;')
msg = HTML('<span class="inline-error">{}</span>').format(err)
exans = [''] * len(self.answer_ids)
exans[0] = msg

View File

@@ -4,7 +4,6 @@ from codejail.safe_exec import safe_exec as codejail_safe_exec
from codejail.safe_exec import not_safe_exec as codejail_not_safe_exec
from codejail.safe_exec import json_safe, SafeExecException
from . import lazymod
from dogapi import dog_stats_api
from six import text_type
import hashlib
@@ -74,7 +73,6 @@ def update_hash(hasher, obj):
hasher.update(repr(obj))
@dog_stats_api.timed('capa.safe_exec.time')
def safe_exec(
code,
globals_dict,

View File

@@ -7,7 +7,6 @@ import logging
import requests
import dogstats_wrapper as dog_stats_api
log = logging.getLogger(__name__)
dateformat = '%Y%m%d%H%M%S'
@@ -93,10 +92,6 @@ class XQueueInterface(object):
# log the send to xqueue
header_info = json.loads(header)
queue_name = header_info.get('queue_name', u'')
dog_stats_api.increment(XQUEUE_METRIC_NAME, tags=[
u'action:send_to_queue',
u'queue:{}'.format(queue_name)
])
# Attempt to send to queue
(error, msg) = self._send_to_queue(header, body, files_to_upload)

View File

@@ -1 +0,0 @@
from .wrapper import increment, histogram, timer

View File

@@ -1,47 +0,0 @@
"""
Wrapper for dog_stats_api, ensuring tags are valid.
See: http://help.datadoghq.com/customer/portal/questions/908720-api-guidelines
"""
from dogapi import dog_stats_api
def _clean_tags(tags):
"""
Helper method that does the actual cleaning of tags for sending to statsd.
1. Handles any type of tag - a plain string, UTF-8 binary, or a unicode
string, and converts it to UTF-8 encoded bytestring needed by statsd.
2. Escape pipe character - used by statsd as a field separator.
3. Trim to 200 characters (DataDog API limitation)
"""
def clean(tagstr):
if isinstance(tagstr, str):
return tagstr.replace('|', '_')[:200]
return unicode(tagstr).replace('|', '_')[:200].encode("utf-8")
return [clean(t) for t in tags]
def increment(metric_name, *args, **kwargs):
"""
Wrapper around dog_stats_api.increment that cleans any tags used.
"""
if "tags" in kwargs:
kwargs["tags"] = _clean_tags(kwargs["tags"])
dog_stats_api.increment(metric_name, *args, **kwargs)
def histogram(metric_name, *args, **kwargs):
"""
Wrapper around dog_stats_api.histogram that cleans any tags used.
"""
if "tags" in kwargs:
kwargs["tags"] = _clean_tags(kwargs["tags"])
dog_stats_api.histogram(metric_name, *args, **kwargs)
def timer(metric_name, *args, **kwargs):
"""
Wrapper around dog_stats_api.timer that cleans any tags used.
"""
if "tags" in kwargs:
kwargs["tags"] = _clean_tags(kwargs["tags"])
return dog_stats_api.timer(metric_name, *args, **kwargs)

View File

@@ -1,10 +0,0 @@
from setuptools import setup
setup(
name="dogstats_wrapper",
version="0.1",
packages=["dogstats_wrapper"],
install_requires=[
"dogapi",
],
)

View File

@@ -1,5 +1,4 @@
"""Implements basics of Capa, including class CapaModule."""
import cgi
import copy
import datetime
import hashlib
@@ -12,11 +11,6 @@ import sys
import traceback
from django.conf import settings
# We don't want to force a dependency on datadog, so make the import conditional
try:
import dogstats_wrapper as dog_stats_api
except ImportError:
dog_stats_api = None
from pytz import utc
from django.utils.encoding import smart_text
from six import text_type
@@ -273,20 +267,18 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
# TODO (vshnayder): This logic should be general, not here--and may
# want to preserve the data instead of replacing it.
# e.g. in the CMS
msg = u'<p>{msg}</p>'.format(msg=cgi.escape(msg))
msg += u'<p><pre>{tb}</pre></p>'.format(
msg = HTML(u'<p>{msg}</p>').format(msg=msg)
msg += HTML(u'<p><pre>{tb}</pre></p>').format(
# just the traceback, no message - it is already present above
tb=cgi.escape(
u''.join(
['Traceback (most recent call last):\n'] +
traceback.format_tb(sys.exc_info()[2])
)
tb=u''.join(
['Traceback (most recent call last):\n'] +
traceback.format_tb(sys.exc_info()[2])
)
)
# create a dummy problem with error message instead of failing
problem_text = (
u'<problem><text><span class="inline-error">'
u'Problem {url} has an error:</span>{msg}</text></problem>'.format(
HTML(u'<problem><text><span class="inline-error">'
u'Problem {url} has an error:</span>{msg}</text></problem>').format(
url=text_type(self.location),
msg=msg,
)
@@ -548,13 +540,14 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
# TODO (vshnayder): another switch on DEBUG.
if self.runtime.DEBUG:
msg = (
msg = HTML(
u'[courseware.capa.capa_module] <font size="+1" color="red">'
u'Failed to generate HTML for problem {url}</font>'.format(
url=cgi.escape(text_type(self.location)))
u'Failed to generate HTML for problem {url}</font>'
).format(
url=text_type(self.location)
)
msg += u'<p>Error:</p><p><pre>{msg}</pre></p>'.format(msg=cgi.escape(text_type(err)))
msg += u'<p><pre>{tb}</pre></p>'.format(tb=traceback.format_exc())
msg += HTML(u'<p>Error:</p><p><pre>{msg}</pre></p>').format(msg=text_type(err))
msg += HTML(u'<p><pre>{tb}</pre></p>').format(tb=traceback.format_exc())
html = msg
else:
@@ -581,19 +574,19 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
self.set_score(self.score_from_lcp())
# Prepend a scary warning to the student
_ = self.runtime.service(self, "i18n").ugettext
warning_msg = _("Warning: The problem has been reset to its initial state!")
warning = '<div class="capa_reset"> <h2> ' + warning_msg + '</h2>'
warning_msg = Text(_("Warning: The problem has been reset to its initial state!"))
warning = HTML('<div class="capa_reset"> <h2>{}</h2>').format(warning_msg)
# Translators: Following this message, there will be a bulleted list of items.
warning_msg = _("The problem's state was corrupted by an invalid submission. The submission consisted of:")
warning += warning_msg + '<ul>'
warning += HTML('{}<ul>').format(warning_msg)
for student_answer in student_answers.values():
if student_answer != '':
warning += '<li>' + cgi.escape(student_answer) + '</li>'
warning += HTML('<li>{}</li>').format(student_answer)
warning_msg = _('If this error persists, please contact the course staff.')
warning += '</ul>' + warning_msg + '</div>'
warning += HTML('</ul>{}</div>').format(warning_msg)
html = warning
try:
@@ -745,9 +738,9 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
html = self.runtime.render_template('problem.html', context)
if encapsulate:
html = u'<div id="problem_{id}" class="problem" data-url="{ajax_url}">'.format(
id=self.location.html_id(), ajax_url=self.runtime.ajax_url
) + html + "</div>"
html = HTML(u'<div id="problem_{id}" class="problem" data-url="{ajax_url}">{html}</div>').format(
id=self.location.html_id(), ajax_url=self.runtime.ajax_url, html=HTML(html)
)
# Now do all the substitutions which the LMS module_render normally does, but
# we need to do here explicitly since we can get called for our HTML via AJAX
@@ -834,7 +827,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
'correcthint', 'regexphint', 'additional_answer', 'stringequalhint', 'compoundhint',
'stringequalhint']
for tag in tags:
html = re.sub(r'<%s.*?>.*?</%s>' % (tag, tag), '', html, flags=re.DOTALL)
html = re.sub(r'<%s.*?>.*?</%s>' % (tag, tag), '', html, flags=re.DOTALL) # xss-lint: disable=python-interpolate-html
# Some of these tags span multiple lines
# Note: could probably speed this up by calling sub() once with a big regex
# vs. simply calling sub() many times as we have here.
@@ -1179,16 +1172,12 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
if self.closed():
event_info['failure'] = 'closed'
self.track_function_unmask('problem_check_fail', event_info)
if dog_stats_api:
dog_stats_api.increment(metric_name('checks'), tags=[u'result:failed', u'failure:closed'])
raise NotFoundError(_("Problem is closed."))
# Problem submitted. Student should reset before checking again
if self.done and self.rerandomize == RANDOMIZATION.ALWAYS:
event_info['failure'] = 'unreset'
self.track_function_unmask('problem_check_fail', event_info)
if dog_stats_api:
dog_stats_api.increment(metric_name('checks'), tags=[u'result:failed', u'failure:unreset'])
raise NotFoundError(_("Problem must be reset before it can be submitted again."))
# Problem queued. Students must wait a specified waittime before they are allowed to submit
@@ -1285,18 +1274,6 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
event_info['submission'] = self.get_submission_metadata_safe(answers_without_files, correct_map)
self.track_function_unmask('problem_check', event_info)
if dog_stats_api:
dog_stats_api.increment(metric_name('checks'), tags=[u'result:success'])
if published_grade['max_grade'] != 0:
dog_stats_api.histogram(
metric_name('correct_pct'),
float(published_grade['grade']) / published_grade['max_grade'],
)
dog_stats_api.histogram(
metric_name('attempts'),
self.attempts,
)
# render problem into HTML
html = self.get_problem_html(encapsulate=False, submit_notification=True)

View File

@@ -7,7 +7,6 @@ import sys
from lxml import etree
from pkg_resources import resource_string
import dogstats_wrapper as dog_stats_api
from capa import responsetypes
from xmodule.exceptions import NotFoundError, ProcessingError
from xmodule.raw_module import RawDescriptor
@@ -194,10 +193,6 @@ class CapaDescriptor(CapaFields, RawDescriptor):
# edited in the cms
@classmethod
def backcompat_paths(cls, path):
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:capa_descriptor_backcompat_paths"]
)
return [
'problems/' + path[8:],
path[8:],

View File

@@ -15,7 +15,6 @@ from web_fragments.fragment import Fragment
from xblock.core import XBlock
from xblock.fields import Boolean, List, Scope, String
import dogstats_wrapper as dog_stats_api
from xmodule.contentstore.content import StaticContent
from xmodule.editing_module import EditingDescriptor
from xmodule.edxnotes_utils import edxnotes
@@ -155,12 +154,6 @@ class HtmlDescriptor(HtmlBlock, XmlDescriptor, EditingDescriptor): # pylint: di
"""
Get paths for html and xml files.
"""
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:html_descriptor_backcompat_paths"]
)
if filepath.endswith('.html.xml'):
filepath = filepath[:-9] + '.html' # backcompat--look for html instead of xml
if filepath.endswith('.html.html'):
@@ -251,11 +244,6 @@ class HtmlDescriptor(HtmlBlock, XmlDescriptor, EditingDescriptor): # pylint: di
# online and has imported all current (fall 2012) courses from xml
if not system.resources_fs.exists(filepath):
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:html_descriptor_load_definition"]
)
candidates = cls.backcompat_paths(filepath)
# log.debug("candidates = {0}".format(candidates))
for candidate in candidates:

View File

@@ -20,7 +20,6 @@ try:
except ImportError:
DJANGO_AVAILABLE = False
import dogstats_wrapper as dog_stats_api
import logging
from contracts import check, new_contract
@@ -137,27 +136,6 @@ class QueryTimer(object):
end = time()
tags = tagger.tags
tags.append('course:{}'.format(course_context))
for name, size in tagger.measures:
dog_stats_api.histogram(
'{}.{}'.format(metric_name, name),
size,
timestamp=end,
tags=[tag for tag in tags if not tag.startswith('{}:'.format(metric_name))],
sample_rate=tagger.sample_rate,
)
dog_stats_api.histogram(
'{}.duration'.format(metric_name),
end - start,
timestamp=end,
tags=tags,
sample_rate=tagger.sample_rate,
)
dog_stats_api.increment(
metric_name,
timestamp=end,
tags=tags,
sample_rate=tagger.sample_rate,
)
TIMER = QueryTimer(__name__, 0.01)

View File

@@ -15,7 +15,6 @@ from uuid import uuid4
from factory import Factory, Sequence, lazy_attribute_sequence, lazy_attribute
from factory.errors import CyclicDefinitionError
from mock import patch
import dogstats_wrapper as dog_stats_api
from opaque_keys.edx.locator import BlockUsageLocator
from opaque_keys.edx.keys import UsageKey
@@ -392,14 +391,6 @@ class ItemFactory(XModuleFactory):
# if we add one then we need to also add it to the policy information (i.e. metadata)
# we should remove this once we can break this reference from the course to static tabs
if category == 'static_tab':
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:itemfactory_create_static_tab",
u"block:{}".format(location.block_type),
)
)
course = store.get_course(location.course_key)
course.tabs.append(
CourseTab.load('static_tab', name='Static Tab', url_slug=location.block_id)

View File

@@ -33,8 +33,6 @@ from xblock.field_data import DictFieldData
from xblock.runtime import DictKeyValueStore
from xblock.fields import ScopeIds
import dogstats_wrapper as dog_stats_api
from .exceptions import ItemNotFoundError
from .inheritance import compute_inherited_metadata, inheriting_field_data, InheritanceKeyValueStore
@@ -54,11 +52,6 @@ def clean_out_mako_templating(xml_string):
orig_xml = xml_string
xml_string = xml_string.replace('%include', 'include')
xml_string = re.sub(r"(?m)^\s*%.*$", '', xml_string)
if orig_xml != xml_string:
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:xml_clean_out_mako_templating"]
)
return xml_string
@@ -125,14 +118,6 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
def fallback_name(orig_name=None):
"""Return the fallback name for this module. This is a function instead of a variable
because we want it to be lazy."""
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:import_system_fallback_name",
u"name:{}".format(orig_name),
)
)
if looks_like_fallback(orig_name):
# We're about to re-hash, in case something changed, so get rid of the tag_ and hash
orig_name = orig_name[len(tag) + 1:-12]
@@ -423,7 +408,7 @@ class XMLModuleStore(ModuleStoreReadBase):
'''
String representation - for debugging
'''
return '<%s data_dir=%r, %d courselikes, %d modules>' % (
return '<%s data_dir=%r, %d courselikes, %d modules>' % ( # xss-lint: disable=python-interpolate-html
self.__class__.__name__, self.data_dir, len(self.courses), len(self.modules)
)
@@ -506,32 +491,12 @@ class XMLModuleStore(ModuleStoreReadBase):
# VS[compat]: remove once courses use the policy dirs.
if policy == {}:
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:xml_load_course_policy_dir",
u"course:{}".format(course),
)
)
old_policy_path = self.data_dir / course_dir / 'policies' / '{0}.json'.format(url_name)
policy = self.load_policy(old_policy_path, tracker)
else:
policy = {}
# VS[compat] : 'name' is deprecated, but support it for now...
if course_data.get('name'):
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:xml_load_course_course_data_name",
u"course:{}".format(course_data.get('course')),
u"org:{}".format(course_data.get('org')),
u"name:{}".format(course_data.get('name')),
)
)
url_name = BlockUsageLocator.clean(course_data.get('name'))
tracker("'name' is deprecated for module xml. Please use "
"display_name and url_name.")
@@ -719,14 +684,6 @@ class XMLModuleStore(ModuleStoreReadBase):
# Hack because we need to pull in the 'display_name' for static tabs (because we need to edit them)
# from the course policy
if category == "static_tab":
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:xml_load_extra_content_static_tab",
u"course_dir:{}".format(course_dir),
)
)
tab = CourseTabList.get_tab_by_slug(tab_list=course_descriptor.tabs, url_slug=slug)
if tab:
module.display_name = tab.name

View File

@@ -4,7 +4,6 @@ Template module
from lxml import etree
from mako.template import Template
import dogstats_wrapper as dog_stats_api
from xmodule.raw_module import RawDescriptor
from xmodule.x_module import DEPRECATION_VSCOMPAT_EVENT, XModule
@@ -48,11 +47,6 @@ class CustomTagDescriptor(RawDescriptor):
template_name = xmltree.attrib['impl']
else:
# VS[compat] backwards compatibility with old nested customtag structure
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:customtag_descriptor_render_template"]
)
child_impl = xmltree.find('impl')
if child_impl is not None:
template_name = child_impl.text

View File

@@ -37,7 +37,6 @@ from xmodule.util.xmodule_django import add_webpack_to_fragment
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.asides import AsideUsageKeyV2, AsideDefinitionKeyV2
from xmodule.exceptions import UndefinedContext
import dogstats_wrapper as dog_stats_api
from openedx.core.djangolib.markup import HTML
@@ -516,14 +515,6 @@ class XModuleMixin(XModuleFields, XBlock):
child = super(XModuleMixin, self).get_child(usage_id)
except ItemNotFoundError:
log.warning(u'Unable to load item %s, skipping', usage_id)
dog_stats_api.increment(
"xmodule.item_not_found_error",
tags=[
u"course_id:{}".format(usage_id.course_key),
u"block_type:{}".format(usage_id.block_type),
u"parent_block_type:{}".format(self.location.block_type),
]
)
return None
if child is None:
@@ -1090,12 +1081,6 @@ class XModuleDescriptor(HTMLSnippet, ResourceTemplates, XModuleMixin):
@classmethod
def _translate(cls, key):
'VS[compat]'
if key in cls.metadata_translations:
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:xmodule_descriptor_translate"]
)
return cls.metadata_translations.get(key, key)
# ================================= XML PARSING ============================
@@ -1351,13 +1336,6 @@ class MetricsMixin(object):
u'block_type:{}'.format(block.scope_ids.block_type),
u'block_family:{}'.format(block.entry_point),
]
dog_stats_api.increment(XMODULE_METRIC_NAME, tags=tags, sample_rate=XMODULE_METRIC_SAMPLE_RATE)
dog_stats_api.histogram(
XMODULE_DURATION_METRIC_NAME,
duration,
tags=tags,
sample_rate=XMODULE_METRIC_SAMPLE_RATE,
)
log.debug(
"%.3fs - render %s.%s (%s)",
duration,
@@ -1388,13 +1366,6 @@ class MetricsMixin(object):
u'block_type:{}'.format(block.scope_ids.block_type),
u'block_family:{}'.format(block.entry_point),
]
dog_stats_api.increment(XMODULE_METRIC_NAME, tags=tags, sample_rate=XMODULE_METRIC_SAMPLE_RATE)
dog_stats_api.histogram(
XMODULE_DURATION_METRIC_NAME,
duration,
tags=tags,
sample_rate=XMODULE_METRIC_SAMPLE_RATE
)
log.debug(
"%.3fs - handle %s.%s (%s)",
duration,

View File

@@ -10,7 +10,6 @@ from xblock.core import XML_NAMESPACES
from xblock.fields import Dict, Scope, ScopeIds
from xblock.runtime import KvsFieldData
import dogstats_wrapper as dog_stats_api
from xmodule.modulestore import EdxJSONEncoder
from xmodule.modulestore.inheritance import InheritanceKeyValueStore, own_metadata
from xmodule.x_module import DEPRECATION_VSCOMPAT_EVENT, XModuleDescriptor
@@ -233,11 +232,6 @@ class XmlParserMixin(object):
filepath = ''
aside_children = []
else:
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:xmlparser_util_mixin_load_definition_filename"]
)
filepath = cls._format_filepath(xml_object.tag, filename)
# VS[compat]
@@ -246,11 +240,6 @@ class XmlParserMixin(object):
# again in the correct format. This should go away once the CMS is
# online and has imported all current (fall 2012) courses from xml
if not system.resources_fs.exists(filepath) and hasattr(cls, 'backcompat_paths'):
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:xmlparser_util_mixin_load_definition_backcompat"]
)
candidates = cls.backcompat_paths(filepath)
for candidate in candidates:
if system.resources_fs.exists(candidate):
@@ -289,14 +278,6 @@ class XmlParserMixin(object):
attr = cls._translate(attr)
if attr in cls.metadata_to_strip:
if attr in ('course', 'org', 'url_name', 'filename'):
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=(
"location:xmlparser_util_mixin_load_metadata",
"metadata:{}".format(attr),
)
)
# don't load these
continue
@@ -356,10 +337,6 @@ class XmlParserMixin(object):
else:
filepath = None
definition_xml = node
dog_stats_api.increment(
DEPRECATION_VSCOMPAT_EVENT,
tags=["location:xmlparser_util_mixin_parse_xml"]
)
# Note: removes metadata.
definition, children = cls.load_definition(definition_xml, runtime, def_id, id_generator)