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
113 changes: 6 additions & 107 deletions ddtrace/contrib/django/__init__.py
Original file line number Diff line number Diff line change
@@ -1,109 +1,8 @@
from ..util import require_modules

required_modules = ['django']

import logging
from types import MethodType


# project
from ... import tracer
from ...ext import http, errors
from ...contrib import func_name
from .templates import patch_template
from .db import patch_db

# 3p
from django.apps import apps


log = logging.getLogger(__name__)


class TraceMiddleware(object):

def __init__(self):
# override if necessary (can't initialize though)
self.tracer = tracer
self.service = "django"

try:
patch_template(self.tracer)
except Exception:
log.exception("error patching template class")

def process_request(self, request):
try:
patch_db(self.tracer) # ensure that connections are always patched.

span = self.tracer.trace(
"django.request",
service=self.service,
resource="unknown", # will be filled by process view
span_type=http.TYPE)

span.set_tag(http.METHOD, request.method)
span.set_tag(http.URL, request.path)
_set_req_span(request, span)
except Exception:
log.exception("error tracing request")

def process_view(self, request, view_func, *args, **kwargs):
span = _get_req_span(request)
if span:
span.resource = func_name(view_func)

def process_response(self, request, response):
try:
span = _get_req_span(request)
if span:
span.set_tag(http.STATUS_CODE, response.status_code)

if apps.is_installed("django.contrib.auth"):
span = _set_auth_tags(span, request)

span.finish()

except Exception:
log.exception("error tracing request")
finally:
return response

def process_exception(self, request, exception):
try:
span = _get_req_span(request)
if span:
span.set_tag(http.STATUS_CODE, '500')
span.set_traceback() # will set the exception info
except Exception:
log.exception("error processing exception")



def _get_req_span(request):
""" Return the datadog span from the given request. """
return getattr(request, '_datadog_request_span', None)

def _set_req_span(request, span):
""" Set the datadog span on the given request. """
return setattr(request, '_datadog_request_span', span)


def _set_auth_tags(span, request):
""" Patch any available auth tags from the request onto the span. """
user = getattr(request, 'user', None)
if not user:
return

if hasattr(user, 'is_authenticated'):
span.set_tag('django.user.is_authenticated', user.is_authenticated())

uid = getattr(user, 'pk', None)
if uid:
span.set_tag('django.user.id', uid)

uname = getattr(user, 'username', None)
if uname:
span.set_tag('django.user.name', uname)

return span


with require_modules(required_modules) as missing_modules:
if not missing_modules:
from .middleware import TraceMiddleware
__all__ = ['TraceMiddleware']
4 changes: 2 additions & 2 deletions ddtrace/contrib/django/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def __exit__(self, type, value, traceback):

def _vendor_to_prefix(vendor):
if not vendor:
return "db" # should this ever happen?
return "db" # should this ever happen?
elif vendor == "sqlite":
return "sqlite3" # for consitency with the sqlite3 integration
return "sqlite3" # for consistency with the sqlite3 integration
else:
return vendor
105 changes: 105 additions & 0 deletions ddtrace/contrib/django/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import logging

# project
from ... import tracer
from ...ext import http
from ...contrib import func_name
from .templates import patch_template
from .db import patch_db

# 3p
from django.apps import apps
from django.conf import settings


log = logging.getLogger(__name__)


class TraceMiddleware(object):

def __init__(self):
# override if necessary (can't initialize though)
self.tracer = tracer
self.service = getattr(settings, 'DATADOG_SERVICE', 'django')

try:
patch_template(self.tracer)
except Exception:
log.exception("error patching template class")

def process_request(self, request):
try:
patch_db(self.tracer) # ensure that connections are always patched.

span = self.tracer.trace(
"django.request",
service=self.service,
resource="unknown", # will be filled by process view
span_type=http.TYPE,
)

span.set_tag(http.METHOD, request.method)
span.set_tag(http.URL, request.path)
_set_req_span(request, span)
except Exception:
log.exception("error tracing request")

def process_view(self, request, view_func, *args, **kwargs):
span = _get_req_span(request)
if span:
span.resource = func_name(view_func)

def process_response(self, request, response):
try:
span = _get_req_span(request)
if span:
span.set_tag(http.STATUS_CODE, response.status_code)

if apps.is_installed("django.contrib.auth"):
span = _set_auth_tags(span, request)

span.finish()

except Exception:
log.exception("error tracing request")
finally:
return response

def process_exception(self, request, exception):
try:
span = _get_req_span(request)
if span:
span.set_tag(http.STATUS_CODE, '500')
span.set_traceback() # will set the exception info
except Exception:
log.exception("error processing exception")



def _get_req_span(request):
""" Return the datadog span from the given request. """
return getattr(request, '_datadog_request_span', None)

def _set_req_span(request, span):
""" Set the datadog span on the given request. """
return setattr(request, '_datadog_request_span', span)


def _set_auth_tags(span, request):
""" Patch any available auth tags from the request onto the span. """
user = getattr(request, 'user', None)
if not user:
return

if hasattr(user, 'is_authenticated'):
span.set_tag('django.user.is_authenticated', user.is_authenticated())

uid = getattr(user, 'pk', None)
if uid:
span.set_tag('django.user.id', uid)

uname = getattr(user, 'username', None)
if uname:
span.set_tag('django.user.name', uname)

return span
7 changes: 4 additions & 3 deletions ddtrace/contrib/django/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import logging

# project
from ...ext import http, errors
from ...ext import http

# 3p
from django.template import Template
Expand Down Expand Up @@ -36,7 +36,8 @@ def traced_render(self, context):
try:
return Template._datadog_original_render(self, context)
finally:
span.set_tag('django.template_name', context.template_name or 'unknown')
template_name = self.name or context.template_name or 'unknown'
span.resource = template_name
span.set_tag('django.template_name', template_name)

Template.render = traced_render