Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Change Log
Unreleased
----------

8.0.1 - 2025-09-29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timmc-edx: It would also be fine to just leave this under Unreleased.

------------------
* Stop using deprecated newrelic function calls that were removed in newrelic 11.0.0 (use newer names instead)

8.0.0 - 2025-05-22
------------------
* **BREAKING CHANGE**: ``newrelic`` removed from dependencies. Users of New Relic should install the package separately in their services. `See relevant DEPR <https://github.com/openedx/public-engineering/issues/360>`_.
Expand Down
2 changes: 1 addition & 1 deletion edx_django_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
EdX utilities for Django Application development..
"""

__version__ = "8.0.0"
__version__ = "8.0.1"
9 changes: 2 additions & 7 deletions edx_django_utils/monitoring/internal/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,10 @@ def set_attribute(self, key, value):
# `add_custom_span_attribute` that would better match
# OpenTelemetry's behavior, which we could try exposing
# through a new, more specific TelemetryBackend method.
#
# TODO: Update to newer name `add_custom_attribute`
# https://docs.newrelic.com/docs/apm/agents/python-agent/python-agent-api/addcustomparameter-python-agent-api/
newrelic.agent.add_custom_parameter(key, value)
newrelic.agent.add_custom_attribute(key, value)

def record_exception(self):
# TODO: Replace with newrelic.agent.notice_error()
# https://docs.newrelic.com/docs/apm/agents/python-agent/python-agent-api/recordexception-python-agent-api/
newrelic.agent.record_exception()
newrelic.agent.notice_error()

def create_span(self, name):
if newrelic.version_info[0] >= 5:
Expand Down
12 changes: 6 additions & 6 deletions edx_django_utils/monitoring/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class TestBackendsFanOut(TestCase):
Test that certain utility functions fan out to the backends.
"""

@patch('newrelic.agent.add_custom_parameter')
@patch('newrelic.agent.add_custom_attribute')
@patch('opentelemetry.trace.span.NonRecordingSpan.set_attribute')
# Patch out the span-getter, not the set_attribute call, because
# it doesn't give us a span unless one is active. And I didn't
Expand All @@ -122,32 +122,32 @@ class TestBackendsFanOut(TestCase):
@patch('ddtrace._trace.tracer.Tracer.current_root_span')
def test_set_custom_attribute(
self, mock_dd_root_span,
mock_otel_set_attribute, mock_nr_add_custom_parameter,
mock_otel_set_attribute, mock_nr_add_custom_attribute,
):
with override_settings(OPENEDX_TELEMETRY=[
'edx_django_utils.monitoring.NewRelicBackend',
'edx_django_utils.monitoring.OpenTelemetryBackend',
'edx_django_utils.monitoring.DatadogBackend',
]):
set_custom_attribute('some_key', 'some_value')
mock_nr_add_custom_parameter.assert_called_once_with('some_key', 'some_value')
mock_nr_add_custom_attribute.assert_called_once_with('some_key', 'some_value')
mock_otel_set_attribute.assert_called_once()
mock_dd_root_span.assert_called_once()

@patch('newrelic.agent.record_exception')
@patch('newrelic.agent.notice_error')
@patch('opentelemetry.trace.span.NonRecordingSpan.record_exception')
# Record exception on current span, not root span.
@patch('ddtrace._trace.tracer.Tracer.current_span')
def test_record_exception(
self, mock_dd_span,
mock_otel_record_exception, mock_nr_record_exception,
mock_otel_record_exception, mock_nr_notice_error,
):
with override_settings(OPENEDX_TELEMETRY=[
'edx_django_utils.monitoring.NewRelicBackend',
'edx_django_utils.monitoring.OpenTelemetryBackend',
'edx_django_utils.monitoring.DatadogBackend',
]):
record_exception()
mock_nr_record_exception.assert_called_once()
mock_nr_notice_error.assert_called_once()
mock_otel_record_exception.assert_called_once()
mock_dd_span.assert_called_once()
4 changes: 2 additions & 2 deletions edx_django_utils/monitoring/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ def test_record_python_and_django_version(self, mock_newrelic_agent):
middleware = DeploymentMonitoringMiddleware(Mock())
middleware(Mock())

parameter_calls_count = mock_newrelic_agent.add_custom_parameter.call_count
parameter_calls_count = mock_newrelic_agent.add_custom_attribute.call_count
assert parameter_calls_count == 2

function_calls = mock_newrelic_agent.add_custom_parameter.call_args_list
function_calls = mock_newrelic_agent.add_custom_attribute.call_args_list
self._test_key_value_pair(function_calls[0], 'python_version')
self._test_key_value_pair(function_calls[1], 'django_version')

Expand Down
16 changes: 8 additions & 8 deletions edx_django_utils/monitoring/tests/test_monitoring_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ def test_accumulate_and_increment(
'fake response',
)

# Assert call counts to newrelic.agent.add_custom_parameter()
# Assert call counts to newrelic.agent.add_custom_attribute()
expected_call_count = len(nr_agent_calls_expected)
if is_deprecated:
expected_call_count += 1
measured_call_count = mock_newrelic_agent.add_custom_parameter.call_count
measured_call_count = mock_newrelic_agent.add_custom_attribute.call_count
self.assertEqual(expected_call_count, measured_call_count)

# Assert call args to newrelic.agent.add_custom_parameter(). Due to
# Assert call args to newrelic.agent.add_custom_attribute(). Due to
# the nature of python dicts, call order is undefined.
mock_newrelic_agent.add_custom_parameter.assert_has_calls(nr_agent_calls_expected, any_order=True)
mock_newrelic_agent.add_custom_attribute.assert_has_calls(nr_agent_calls_expected, any_order=True)

@patch('newrelic.agent')
@ddt.data(
Expand Down Expand Up @@ -110,15 +110,15 @@ def test_accumulate_with_illegal_value(
'fake response',
)

# Assert call counts to newrelic.agent.add_custom_parameter()
# Assert call counts to newrelic.agent.add_custom_attribute()
expected_call_count = len(nr_agent_calls_expected)
if is_deprecated:
expected_call_count += 1
measured_call_count = mock_newrelic_agent.add_custom_parameter.call_count
measured_call_count = mock_newrelic_agent.add_custom_attribute.call_count
self.assertEqual(expected_call_count, measured_call_count)

# Assert call args to newrelic.agent.add_custom_parameter().
mock_newrelic_agent.add_custom_parameter.assert_has_calls(nr_agent_calls_expected, any_order=True)
# Assert call args to newrelic.agent.add_custom_attribute().
mock_newrelic_agent.add_custom_attribute.assert_has_calls(nr_agent_calls_expected, any_order=True)

@contextmanager
def catch_signal(self, signal):
Expand Down