Skip to content

Commit

Permalink
Track proper user info in sentry
Browse files Browse the repository at this point in the history
  • Loading branch information
thenav56 committed Aug 27, 2024
1 parent 47b537f commit 003a736
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 35 deletions.
62 changes: 32 additions & 30 deletions main/middlewares.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import json

from asgiref.sync import iscoroutinefunction
from django.urls import reverse
from sentry_sdk import Scope


class SentryTransactionMiddleware:
graphql_url = reverse("graphql")

def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
if request.path == self.graphql_url:
operation_type = "Query"
operation_name = "Unknown"
try:
body = request.body.decode("utf-8")
if body:
# XXX: This will be repeated by Strawberry as well.
data = json.loads(body)
operation_name = data.get("operationName", operation_name)
if data.get("query", "").startswith("mutation"):
operation_type = "Mutation"
except Exception:
...

scope = Scope.get_current_scope()
scope.set_transaction_name(f"GraphQL/{operation_type}/{operation_name}")

return self.get_response(request)
from django.utils.decorators import sync_and_async_middleware

from main.sentry import SentryTransactionMiddlewareHelper


@sync_and_async_middleware
def sentry_middleware(get_response):
from django.conf import settings

# One-time configuration and initialization goes here.
graphql_urls = set([reverse("graphql")])
if settings.DEBUG:
graphql_urls.add(reverse("graphiql"))

if iscoroutinefunction(get_response):

async def amiddleware(request):
if settings.SENTRY_ENABLED:
await SentryTransactionMiddlewareHelper.atrack_transaction(graphql_urls, request)
response = await get_response(request)
return response

return amiddleware

def middleware(request):
if settings.SENTRY_ENABLED:
SentryTransactionMiddlewareHelper.track_transaction(graphql_urls, request)
response = get_response(request)
return response

return middleware
38 changes: 38 additions & 0 deletions main/sentry.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import json

import sentry_sdk
from asgiref.sync import sync_to_async
from sentry_sdk import Scope, set_user
from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.logging import ignore_logger
Expand Down Expand Up @@ -31,3 +35,37 @@ def init_sentry(app_type, tags={}, **config):
scope.set_tag("app_type", app_type)
for tag, value in tags.items():
scope.set_tag(tag, value)


class SentryTransactionMiddlewareHelper:
@classmethod
@sync_to_async
def atrack_transaction(cls, graphql_urls: set[str], request):
return cls.track_transaction(graphql_urls, request)

@staticmethod
def track_transaction(graphql_urls: set[str], request):
if request.path in graphql_urls:
operation_type = "Query"
operation_name = "Unknown"
try:
body = request.body.decode("utf-8")
if body:
# XXX: This will be repeated by Strawberry as well.
data = json.loads(body)
operation_name = data.get("operationName", operation_name)
if data.get("query", "").startswith("mutation"):
operation_type = "Mutation"
except Exception:
...

scope = Scope.get_current_scope()
scope.set_transaction_name(f"GraphQL/{operation_type}/{operation_name}")
if (user := request.user) and user.pk:
set_user(
{
"id": user.pk,
"email": user.email,
"is_superuser": user.is_superuser,
}
)
2 changes: 1 addition & 1 deletion main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"main.middlewares.SentryTransactionMiddleware",
"main.middlewares.sentry_middleware",
]

ROOT_URLCONF = "main.urls"
Expand Down
2 changes: 1 addition & 1 deletion main/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
if settings.DEBUG:
urlpatterns.extend(
[
path("graphiql/", CustomAsyncGraphQLView.as_view(schema=graphql_schema)),
path("graphiql/", CustomAsyncGraphQLView.as_view(schema=graphql_schema), name="graphiql"),
path("dev/sign_in/", dev_sign_in, name="dev-sign-in"),
]
)
Expand Down
7 changes: 4 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 003a736

Please sign in to comment.