Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django integration: connect Javascript SDK #1171

Closed
danielmanser opened this issue Aug 26, 2021 · 10 comments
Closed

Django integration: connect Javascript SDK #1171

danielmanser opened this issue Aug 26, 2021 · 10 comments
Labels
Component: Docs updates on getsentry/docs or docstrings Feature: Performance

Comments

@danielmanser
Copy link

danielmanser commented Aug 26, 2021

I'm completely stuck with connecting the Python SDK (I'm using Django) and the Javascript SDK. I've installed sentry-python and it sends events to my onPrem Sentry installation. Now I want to connect it with the Frontend using Sentry SDK.

I followed the docs and I think I need to add the trace_id as a <meta> tag in my template. Either I'm too dumb or the docs could be improved, but I've spent 3+hrs trying to get it done with no success.

Environment

How do you use Sentry?
Sentry onPrem, version 21.8.0, installed with the recommended Docker service using install.sh. Sentry seems to work, I can receive errors.

Which SDK and version?
Backend: Python 3.8.5, Django 3.2.6 using sentry-sdk, version 1.3.1
Frontend: Basic HTML, Bootstrap, nothing fancy

Python virtual environment:

asgiref==3.4.1
certifi==2021.5.30
Django==3.2.6
django-appconf==1.0.4
django-compressor==2.4.1
django-debug-toolbar==3.2.2
django-extensions==3.1.3
django-honeypot==1.0.1
psycopg2-binary==2.9.1
pytz==2021.1
rcssmin==1.0.6
rjsmin==1.1.0
sentry-sdk==1.3.1
six==1.16.0
sqlparse==0.4.1
urllib3==1.26.6

Steps to Reproduce

  1. Set up the Django integration following the official docs. Unhandled errors in Django are working and being sent to my Sentry instance, so I guess this part is not in question.
  2. Following Connecting Services, I decided it would be easiest to add a <meta> tag in my Django template, so I followed this:
<meta name="sentry-trace" content="{{ span.toSentryTrace() }}" />

I understand that the docs are not Django-specific and I can't call a function within a template in Django. So I've tried a lot of different things, but I don't seem to have the trace_id available in my template, nor in the Python environment.

Do I need to add it using a custom template tag? Or is there a middleware I'm not aware of? I've googled for "Django Sentry trace_id" and a lot of other things, searched Github for examples, but didn't find anything that worked.

How do I get that to work? I suspect other Django developers are struggling with that as well, and I hoped it was in the documentation, especially because Django is listed as an integration. I'm willing to contribute this to the docs if appreciated and someone can tell me a recommended way :-)

Expected Result

Docs including best-practice Instructions for connecting Django templates.

Actual Result

🙇‍♂️

@AbhiPrasad
Copy link
Member

Hey thanks for writing in. Apologies for the frustration, I agree that the documentation can be a lot better here.

You can grab the current span using span = sentry_sdk.Hub.current.scope.span: https://docs.sentry.io/platforms/python/guides/django/performance/instrumentation/custom-instrumentation/#retrieve-the-current-span

The method is called span.to_traceparent:

def to_traceparent(self):

This will get you a information to continue a Sentry trace (this format is known as traceparent with other tracing/apm providers), hence the inconsistency with naming. The format is basically traceId-parentSpanId-sampled, traceID tells you what the id of the trace is in case your frontend has to propogate it, parentSpanId allows the continued trace to have a proper parent-child relationship, and sampled will make sure that child transactions are sampled correctly.

As such:

# Some view I have
def some_view(request):
    span = sentry_sdk.Hub.current.scope.span    
    return render(request, 'template.html', {'sentry-trace': span.to_traceparent()})
<!-- template.html -->
<meta name="sentry-trace" content="{{ sentry-trace }}" />

If you want to apply the meta tag onto every page, I would use context_processors as per https://docs.djangoproject.com/en/3.2/ref/templates/api/#configuring-an-engine. See: https://docs.djangoproject.com/en/3.2/ref/templates/api/#django.template.RequestContext

@AbhiPrasad AbhiPrasad added Component: Docs updates on getsentry/docs or docstrings Feature: Performance labels Aug 26, 2021
@pickfire
Copy link

pickfire commented Oct 7, 2021

I am also confused here. Spent a day reading up on this but still confused. But with this approach, don't you need to add the sentry-trace to every view? Is there an existing context processor to get this?

@AbhiPrasad
Copy link
Member

You'll need to create your own context processor, we don't offer anything out of the box. Could be something we consider as a feature request. The context processor should just have the logic of grabbing the current span and add it to the context.

You'll also need to add the meta tag to every view, we recommend using a base html template with the meta tag, and then having your other templates extend that base template.

@tony
Copy link

tony commented Jan 22, 2022

@AbhiPrasad I think it'd valuable to have some documentation or examples with django. I'm equally curious.

Thank you for your example at #1171 (comment)

I am curious, what would be the difference between:

def some_view(request):
    with sentry_sdk.configure_scope() as scope:
        span = scope.span
        return render(request, 'template.html', {'sentry-trace': span.to_traceparent()})

and

def some_view(request):
    span = sentry_sdk.Hub.current.scope.span    
    return render(request, 'template.html', {'sentry-trace': span.to_traceparent()})

Are there any risks from grabbing it via sentry_sdk.Hub.current.scope.span? Could that potentially cause issues if it was running on a server with multiple threads/workers/etc?

@sl0thentr0py
Copy link
Member

sl0thentr0py commented Jan 27, 2022

@tony they're functionally equivalent but the first one (configure_scope) is more 'canonical' usage and is what we do internally in integrations as well. Hub.current always takes the current thread into account and is cloned per thread.

@tbrlpld
Copy link

tbrlpld commented Feb 25, 2023

@AbhiPrasad The "connecting services" section mentions that apart from the sentry-trace meta tag you also need to set a baggage meta tag.

<html>
  <head>
    <meta name="sentry-trace" content="{{ span.toTraceparent() }}" />
    <meta name="baggage" content="{{ serializeBaggage(span.getBaggage()) }}" />
    <!-- ... -->
  </head>
</html>

I just tried and it looks like sentry_sdk.Hub.current.scope.span does not have a get_baggage() method as it apparently should have. Also where would the equivalent of serializeBaggage() come from?

@sl0thentr0py
Copy link
Member

hey @tbrlpld sorry I haven't gotten around to documenting this, my bad!

but there's a new helper you can simply inject now which will generate both those meta tags for you.

Hub.current.trace_propagation_meta()

We will eventually probably auto-inject these into django/flask etc wherever possible so nobody has to think about this.

@tbrlpld
Copy link

tbrlpld commented Mar 11, 2023

@sl0thentr0py It looks like the trace_propagation_meta has not made it into the last release (1.16.0), right?

@sl0thentr0py
Copy link
Member

@tbrlpld this helper exists since quite a few versions

@tbrlpld
Copy link

tbrlpld commented Mar 14, 2023

Wow, weird. I could swear I tested this with the latest version installed. Looks like my environment must have been off. It's all there.

Thanks @sl0thentr0py.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Docs updates on getsentry/docs or docstrings Feature: Performance
Projects
None yet
Development

No branches or pull requests

6 participants