Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Hi everyone! I recently upgraded from sentry-sdk version 1.4.3 to 2.17.0 for my Django project and noticed a curious behavior. When I use capture_exception with certain exceptions, it seems to kick off extra database queries, especially when Django model instances are involved. It’s almost like it’s adding a bit of an N+1 query pattern, which I hadn’t seen in the older version.

Here’s a little example of what I’m seeing:

from sentry_sdk import capture_exception

def process_document(instance_a, keyname):
    try:
        document = instance_a.documents.get(keyname=keyname)
        # more processing
    except DocumentInfo.DoesNotExist:
        LOGGER.error("No DocumentInfo found.")
        return None
    except DocumentInfo.MultipleObjectsReturned as e:
        LOGGER.exception("Multiple DocumentInfo entries found.")
        capture_exception(e)  # This seems to trigger extra queries
        return None

This is a legacy codebase we’re slowly refactoring, but I found it interesting because this issue wasn’t happening before the upgrade. We actually have an assert_num_queries test to keep an eye on performance, and thanks to that test, we caught the increase: the function jumped from 10 queries to 23 after the upgrade! Our current fix was to keep only the logger.exception with the data we think is critical to know about the issue.

Has anyone else noticed this, or maybe found a workaround? It would be great to hear any thoughts! Thanks!

You must be logged in to vote

Replies: 1 comment · 10 replies

Comment options

Strange, I would need more info to help you.

and thanks to that test, we caught the increase: the function jumped from 10 queries to 23 after the upgrade

Can you dig a bit more into what kind of query it is that increased? And also make sure that that does not happen if you disable Sentry?

You must be logged in to vote
10 replies
@sl0thentr0py
Comment options

we actually have a test covering this branch, so I'd need more details from you for reproduction

def test_queryset_repr(sentry_init, capture_events):
sentry_init(integrations=[DjangoIntegration()])
events = capture_events()
User.objects.create_user("john", "lennon@thebeatles.com", "johnpassword")
try:
my_queryset = User.objects.all() # noqa
1 / 0
except Exception:
capture_exception()
(event,) = events
(exception,) = event["exception"]["values"]
assert exception["type"] == "ZeroDivisionError"
(frame,) = exception["stacktrace"]["frames"]
assert frame["vars"]["my_queryset"].startswith(
"<QuerySet from django.db.models.query at"
)

  • python version
  • django version
  • anything else that's potentially different about your setup, especially regarding database models and if you have custom behaviour implemented around QuerySets
@gabicavalcante
Comment options

  • python version: 3.9
  • django version: 4.2.16
  • anything else that's potentially different about your setup, especially regarding database models and if you have custom behavior implemented around QuerySets: I don't think we have any other diff that could impact on it; it's a really simple model (models.Model), without any custom queryset behavior

I'm going to debug a little more to see exactly where this queryset is evaluated.

@gabicavalcante
Comment options

I still couldn't find the root cause of those queries :( I made a simpler test and got 12 queries 👀

        with django_assert_num_queries(1):
            try:
                document =instance_a.documents.get()
            except Exception as e:
                from sentry_sdk import capture_exception
                capture_exception(e)

It's not the _django_queryset_repr because when I tried to use only this method in the test, no more queries were executed.

@sl0thentr0py
Comment options

the problem is that it should use _django_queryset_repr but it's instead using the normal repr in your case.

@sl0thentr0py
Comment options

can you give me

  • the whole model class, or a simpler copy
  • django_assert_num_queries

so that I can try to reproduce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.