Skip to content

Commit

Permalink
feat: Create manual spans for monitoring backends.
Browse files Browse the repository at this point in the history
  • Loading branch information
dianakhuang committed Jul 29, 2024
1 parent 0833182 commit 9fd0c60
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.
[5.15.0] - 2024-07-29
---------------------
Added
~~~~~
* Added ``start_trace`` to ``monitoring.utils`` so that manual spans in our monitoring backends can be created.

[5.14.2] - 2024-05-31
---------------------
Fixed
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,7 +2,7 @@
EdX utilities for Django Application development..
"""

__version__ = "5.14.2"
__version__ = "5.15.0"

default_app_config = (
"edx_django_utils.apps.EdxDjangoUtilsConfig"
Expand Down
3 changes: 2 additions & 1 deletion edx_django_utils/monitoring/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
increment,
record_exception,
set_custom_attribute,
set_custom_attributes_for_course_key
set_custom_attributes_for_course_key,
start_trace
)
# "set_custom_metric*" methods are deprecated
from .utils import set_custom_metric, set_custom_metrics_for_course_key
24 changes: 24 additions & 0 deletions edx_django_utils/monitoring/internal/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ def record_exception(self):
Record the exception that is currently being handled.
"""

@abstractmethod
def trace(self, name, params=None):
"""
Create a manual trace with the given name. The underlying implementation is generally
assumed to be a contextmanager, and the level above calls it as such.
"""


class NewRelicBackend(TelemetryBackend):
"""
Expand Down Expand Up @@ -77,6 +84,10 @@ def record_exception(self):
# https://docs.newrelic.com/docs/apm/agents/python-agent/python-agent-api/recordexception-python-agent-api/
newrelic.agent.record_exception()

def trace(self, name, params=None):
# To pass along parameters to New Relic, we can add functionality here. Currently, this is not implemented.
return newrelic.agent.function_trace(name)

Check warning on line 89 in edx_django_utils/monitoring/internal/backends.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/backends.py#L89

Added line #L89 was not covered by tests


class OpenTelemetryBackend(TelemetryBackend):
"""
Expand All @@ -98,6 +109,10 @@ def set_attribute(self, key, value):
def record_exception(self):
self.otel_trace.get_current_span().record_exception(sys.exc_info()[1])

def trace(self, name, params=None):
# To pass along parameters to OpenTelemetry, we can add functionality here. Currently, this is not implemented.
return self.otel_trace.start_as_current_span(name)

Check warning on line 114 in edx_django_utils/monitoring/internal/backends.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/backends.py#L114

Added line #L114 was not covered by tests


class DatadogBackend(TelemetryBackend):
"""
Expand All @@ -119,6 +134,15 @@ def record_exception(self):
if span := self.dd_tracer.current_span():
span.set_traceback()

def trace(self, name, params=None):
resource = None
service = None

Check warning on line 139 in edx_django_utils/monitoring/internal/backends.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/backends.py#L138-L139

Added lines #L138 - L139 were not covered by tests
if params is not None:
resource = params.get('dd-resource')
service = params.get('dd-service')

Check warning on line 142 in edx_django_utils/monitoring/internal/backends.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/backends.py#L141-L142

Added lines #L141 - L142 were not covered by tests

return self.dd_tracer.start_span(name, resource=resource, service=service, activate=True)

Check warning on line 144 in edx_django_utils/monitoring/internal/backends.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/backends.py#L144

Added line #L144 was not covered by tests


# We're using an lru_cache instead of assigning the result to a variable on
# module load. With the default settings (pointing to a TelemetryBackend
Expand Down
14 changes: 14 additions & 0 deletions edx_django_utils/monitoring/internal/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
At this time, the custom monitoring will only be reported to New Relic.
"""
from contextlib import contextmanager, ExitStack

from .backends import configured_backends
from .middleware import CachedCustomMonitoringMiddleware

Expand Down Expand Up @@ -92,6 +94,18 @@ def record_exception():
backend.record_exception()


@contextmanager
def start_trace(name, params=None):
"""
A context manager that starts spans for all configured backends.
"""

# ExitStack handles the underlying context managers.
with ExitStack() as stack:
for backend in configured_backends():
yield stack.enter_context(backend.trace(name, params=params))

Check warning on line 106 in edx_django_utils/monitoring/internal/utils.py

View check run for this annotation

Codecov / codecov/patch

edx_django_utils/monitoring/internal/utils.py#L106

Added line #L106 was not covered by tests


def background_task(*args, **kwargs):
"""
Handles monitoring for background tasks that are not passed in through the web server like
Expand Down

0 comments on commit 9fd0c60

Please sign in to comment.