Skip to content

feat: Django rendering monkey patching #957

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

Merged
merged 8 commits into from
Jan 12, 2021

Conversation

Christophe31
Copy link
Contributor

@Christophe31 Christophe31 commented Dec 24, 2020

Monkey patch django.shortcuts.render and TemplateResponse to have a django.render span in the sentry performance view.
One of the features suggested in #956 that @untitaker saw as useful and not requiring any django configuration update.

@Christophe31
Copy link
Contributor Author

Christophe31 commented Dec 28, 2020

Hum, the error seems to be a pip install issue. It may have impacted the coverage detection. How to re run Travis for confirmation?

(I have two single-instruction ifs from my 70 lines which are not tested, the use of default behavior if integration is not enabled which is took from elsewhere in the same file and not tested there either.)

@Christophe31
Copy link
Contributor Author

@untitaker happy new year, I'm allowing myself to ping you so you can tell me if this is ok or how I should improve this.
Note: it only monkey patch main django rendering entries. it should work with any django template engine.
Note 2: it only provide the auto rendering span, not the template tag as I'm not sure I can do it in the current philosophy (no settings) while django discourage to add these keywords

  • here the issue where django says they don't want lib to add template tags to builtins https://code.djangoproject.com/ticket/17085
  • I see how we can monkey-patch it as loadable without being and installed django app but if we do it and a user load it from a template, this template would break if you remove sentry's Django integration at render time.

_content, status, _headers = client.get(url)
transaction = events[0]
assert(
'- op="django.render": description="user_name.html"'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do a strict equality check here. You can acquire the value by first doing assert x == '' and copying the error message

Copy link
Contributor Author

@Christophe31 Christophe31 Jan 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was my first implementation but the message is a bit heavy and have not the same indent so it would require two big strings and it would break on new automatic integrations. This implementation is more permissive which can be good or bad. I'll follow your suggestion if you confirm it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not implemented this one yet as I gave my point of view, just tell me I did not convince you and I'll comply.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return real_render(request, template_name, context, *args, **kwargs)

@property
def rendered_content(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are invocations of rendered_content and render mutually exclusive? I have concerns that we will have two django.render spans in one transaction without a way to distinguish them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes they are exclusive, one render in the view span, the template response is lazy and rendered out of the view automatic span.

if hub.get_integration(DjangoIntegration) is None:
return real_render(request, template_name, context, *args, **kwargs)

with hub.start_span(op="django.render", description=template_name) as span:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the span name is too nondescriptive, would go with django.template.render

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapping is the rendering of an HTTP response specifically, not rendering in generic context so it works with any template backend, and avoid flooding as django do recursive rendering.

I'm updating according to your suggestion.

@untitaker
Copy link
Member

@Christophe31 You raise good points about the stability of the injected tag and I think I agree

I reviewed the PR

with regard to CI, we switched to GitHub actions in master. I'm going to close and reopen the PR to trigger a fresh build

@untitaker untitaker closed this Jan 8, 2021
@untitaker untitaker reopened this Jan 8, 2021
@Christophe31
Copy link
Contributor Author

Christophe31 commented Jan 8, 2021

Should I pull master to have the best tests configurations?

Christophe Narbonne added 2 commits January 8, 2021 19:58
…emplate patch to templates file, update template rendering op
@Christophe31
Copy link
Contributor Author

@untitaker I disabled dj1.6 monkey patch on django.shortcut.render to pass the tests as I had an import error (it required loaded settings)

@untitaker untitaker changed the title [#956] django rendering monkey patching feat: Django rendering monkey patching Jan 12, 2021
@untitaker untitaker merged commit dbd7ce8 into getsentry:master Jan 12, 2021
@untitaker
Copy link
Member

Excellent, thanks!

nijel added a commit to WeblateOrg/weblate that referenced this pull request Aug 23, 2023
This avoids sentry mokey patching of it to track rendering time.

See getsentry/sentry-python#957
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants