Skip to content

Commit e9bc1fb

Browse files
committed
Basic django integration
1 parent 1b635d1 commit e9bc1fb

File tree

17 files changed

+395
-12
lines changed

17 files changed

+395
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ pip-log.txt
1616
.eggs
1717
venv
1818
.vscode/tags
19+
.pytest_cache

dev-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pytest
2+
pytest-django

pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
DJANGO_SETTINGS_MODULE = tests.django.myapp.settings

sentry_minimal.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,32 @@ def get_current_hub():
5454

5555

5656
try:
57-
from sentry_sdk import Hub, Scope
57+
from sentry_sdk.hub import Hub
58+
from sentry_sdk.scope import Scope
5859
except ImportError:
5960
class Hub(object):
6061
current = main = None
62+
63+
class Scope(object):
64+
fingerprint = transaction = user = None
65+
66+
def set_tag(self, key, value):
67+
pass
68+
69+
def remove_tag(self, key):
70+
pass
71+
72+
def set_context(self, key, value):
73+
pass
74+
75+
def remove_context(self, key):
76+
pass
77+
78+
def set_extra(self, key, value):
79+
pass
80+
81+
def remove_extra(self, key):
82+
pass
83+
84+
def clear(self):
85+
pass

sentry_sdk/api.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
from contextlib import contextmanager
22

3-
import sentry_minimal
4-
53
from .hub import Hub
64
from .scope import Scope
75
from .client import Client
86

97

10-
__all__ = ['Hub', 'Client', 'init'] + sentry_minimal.__all__
11-
12-
13-
for _key in sentry_minimal.__all__:
14-
globals()[_key] = getattr(sentry_minimal, _key)
15-
globals()[_key].__module__ = __name__
16-
del _key
17-
188

199
class _InitGuard(object):
2010

@@ -35,3 +25,14 @@ def init(*args, **kwargs):
3525
if client.dsn is not None:
3626
Hub.main.bind_client(client)
3727
return _InitGuard(client)
28+
29+
30+
import sentry_minimal
31+
32+
__all__ = ['Hub', 'Scope', 'Client', 'init'] + sentry_minimal.__all__
33+
34+
35+
for _key in sentry_minimal.__all__:
36+
globals()[_key] = getattr(sentry_minimal, _key)
37+
globals()[_key].__module__ = __name__
38+
del _key

sentry_sdk/hub.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ class _ScopeManager(object):
4343
def __init__(self, hub):
4444
self._hub = hub
4545

46+
def __enter__(self):
47+
return self
48+
4649
def __exit__(self, exc_type, exc_value, tb):
47-
self._hub.stack.pop()
50+
self._hub._stack.pop()
4851

4952

5053
class Hub(with_metaclass(HubMeta)):

sentry_sdk/integrations/__init__.py

Whitespace-only changes.

sentry_sdk/integrations/django.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from threading import Lock, local
2+
3+
from django.apps import AppConfig
4+
from django.core import signals
5+
from django.conf import settings
6+
from django.urls import resolve
7+
8+
from .. import get_current_hub, configure_scope, capture_exception
9+
10+
try:
11+
# Django >= 1.10
12+
from django.utils.deprecation import MiddlewareMixin
13+
except ImportError:
14+
# Not required for Django <= 1.9, see:
15+
# https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
16+
MiddlewareMixin = object
17+
18+
19+
def _get_transaction_from_request(request):
20+
return resolve(request.path).func
21+
22+
_request_scope = local()
23+
24+
25+
class SentryMiddleware(MiddlewareMixin):
26+
def process_view(self, request, func, args, kwargs):
27+
try:
28+
with configure_scope() as scope:
29+
scope.transaction = _get_transaction_from_request(request)
30+
except Exception:
31+
capture_exception()
32+
33+
34+
def _request_started(*args, **kwargs):
35+
assert getattr(_request_scope, 'manager', None) is None, 'race condition'
36+
_request_scope.manager = get_current_hub().push_scope().__enter__()
37+
38+
39+
def _request_finished(*args, **kwargs):
40+
assert getattr(_request_scope, 'manager', None) is not None, 'race condition'
41+
_request_scope.manager.__exit__(None, None, None)
42+
_request_scope.manager = None
43+
44+
45+
def _got_request_exception(request=None, **kwargs):
46+
capture_exception()
47+
48+
49+
MIDDLEWARE_NAME = 'sentry_sdk.integrations.django.SentryMiddleware'
50+
51+
CONFLICTING_MIDDLEWARE = (
52+
'raven.contrib.django.middleware.SentryMiddleware',
53+
'raven.contrib.django.middleware.SentryLogMiddleware'
54+
) + (MIDDLEWARE_NAME,)
55+
56+
_installer_lock = Lock()
57+
_installed = False
58+
59+
60+
def initialize():
61+
global _installed
62+
with _installer_lock:
63+
if _installed:
64+
return
65+
_initialize_impl()
66+
_installed = True
67+
68+
69+
def _initialize_impl():
70+
# default settings.MIDDLEWARE is None
71+
if getattr(settings, 'MIDDLEWARE', None):
72+
middleware_attr = 'MIDDLEWARE'
73+
else:
74+
middleware_attr = 'MIDDLEWARE_CLASSES'
75+
76+
# make sure to get an empty tuple when attr is None
77+
middleware = getattr(settings, middleware_attr, ()) or ()
78+
conflicts = set(CONFLICTING_MIDDLEWARE).intersection(set(middleware))
79+
if conflicts:
80+
raise RuntimeError('Other sentry-middleware already registered: %s' %
81+
conflicts)
82+
83+
setattr(settings,
84+
middleware_attr,
85+
[MIDDLEWARE_NAME] + list(middleware))
86+
87+
signals.request_started.connect(_request_started)
88+
signals.request_finished.connect(_request_finished)
89+
signals.got_request_exception.connect(_got_request_exception)
90+
91+
92+
default_app_config = 'sentry_sdk.integrations.django.SentryConfig'
93+
94+
95+
class SentryConfig(AppConfig):
96+
name = 'sentry_sdk.integrations.django'
97+
label = 'sentry_sdk_integrations_django'
98+
verbose_name = 'Sentry'
99+
100+
def ready(self):
101+
initialize()

setup.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env python
2+
3+
from setuptools import setup, find_packages
4+
5+
setup(
6+
name='sentry-sdk',
7+
version='0.1.0',
8+
author='Sentry',
9+
author_email='hello@getsentry.com',
10+
url='https://github.com/getsentry/sentry-sdk',
11+
description='Python client for Sentry (https://getsentry.com)',
12+
long_description=__doc__,
13+
packages=find_packages(exclude=("tests", "tests.*",)),
14+
zip_safe=False,
15+
license='BSD',
16+
install_requires=['urllib3', 'certifi']
17+
)

tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)