Skip to content

Commit

Permalink
feat: Add datadog_diagnostics plugin app
Browse files Browse the repository at this point in the history
See #692
  • Loading branch information
timmc-edx committed Jul 10, 2024
1 parent 1d4ba69 commit 1eead8d
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Change Log
Unreleased
~~~~~~~~~~

[3.4.0] - 2024-07-10
~~~~~~~~~~~~~~~~~~~~
Added
-----
* Added ``datadog_diagnostics`` plugin app

[3.3.2] - 2024-04-19
~~~~~~~~~~~~~~~~~~~~
Changed
Expand Down
2 changes: 1 addition & 1 deletion edx_arch_experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
A plugin to include applications under development by the architecture team at 2U.
"""

__version__ = '3.3.2'
__version__ = '3.4.0'
13 changes: 13 additions & 0 deletions edx_arch_experiments/datadog_diagnostics/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Datadog Diagnostics
###################

When installed in the LMS as a plugin app, the ``datadog_diagnostics`` app adds additional logging for debugging our Datadog integration.

This is intended as a temporary situation while we debug the `trace concatenation issue <https://github.com/edx/edx-arch-experiments/issues/692>`_.

Usage
*****

In LMS:

- Install ``edx-arch-experiments`` as a dependency
Empty file.
50 changes: 50 additions & 0 deletions edx_arch_experiments/datadog_diagnostics/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
App for emitting additional diagnostic information for the Datadog integration.
"""

from logging import getLogger

from django.apps import AppConfig

log = getLogger("missing_span_logger")


class MissingSpanProccessor:
"""Datadog span processor that logs unfinished spans at shutdown."""
spans_started = 0
spans_finished = 0
open_spans = {}

def on_span_start(self, span):
self.spans_started += 1
self.open_spans[span.span_id] = span

def on_span_finish(self, span):
self.spans_finished += 1
del self.open_spans[span.span_id]

def shutdown(self, _timeout):
log.info(f"Spans created = {self.spans_started}; spans finished = {self.spans_finished}")
for span in self.open_spans.values():
log.error(f"Span created but not finished: {span._pprint()}") # pylint: disable=protected-access


class DatadogDiagnostics(AppConfig):
"""
Django application to log diagnostic information for Datadog.
"""
name = 'edx_arch_experiments.datadog_diagnostics'

# Mark this as a plugin app
plugin_app = {}

def ready(self):
try:
from ddtrace import tracer # pylint: disable=import-outside-toplevel
tracer._span_processors.append(MissingSpanProccessor()) # pylint: disable=protected-access
log.info("Attached MissingSpanProccessor for Datadog diagnostics")
except ImportError:
log.warning(
"Unable to attach MissingSpanProccessor for Datadog diagnostics"
" -- ddtrace module not found."
)
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def is_requirement(line):
"arch_experiments = edx_arch_experiments.apps:EdxArchExperimentsConfig",
"config_watcher = edx_arch_experiments.config_watcher.apps:ConfigWatcher",
"codejail_service = edx_arch_experiments.codejail_service.apps:CodejailService",
"datadog_diagnostics = edx_arch_experiments.datadog_diagnostics.apps:DatadogDiagnostics",
],
"cms.djangoapp": [
"config_watcher = edx_arch_experiments.config_watcher.apps:ConfigWatcher",
Expand Down

0 comments on commit 1eead8d

Please sign in to comment.