-
Notifications
You must be signed in to change notification settings - Fork 375
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
Trace Rails controllers that short-circuit with before_action #669
base: master
Are you sure you want to change the base?
Conversation
Do we know how often people do this? Anything we can do to make inheriting from Having no additional steps is always 👍 |
Looks good! Agree with Brett that its worth considering to keep supporting |
@brettlangdon @pawelchcki I took a very hard look at this to try to come up with a way of patching Essentially we have two goals in conflict with one another; we want to push our module higher in the
The only possible way I could suggest we have our cake and eat it too is by turning the double instrumentation into distinct measurements, hence turning a "bug" into a usable feature. What I mean by this is if we patched The pros of which would mean out of the box The cons are that it's a different way of representing Rails traces altogether; the average Rails application without any controller callbacks would now see two controller spans stacked in one another, which might at a glance appear redundant even if it fact it isn't. Altering how our Rails traces look isn't something I take lightly, but also not something we should consider immune to change either. All things considered, I would probably recommend we add this additional span, since to me there are many more pros than cons. I will create a proof of concept in this PR to demonstrate this, and link a screenshot or two to demonstrate how it looks. If we like it, we can keep it, otherwise we can ditch it and go with the |
@delner what you are suggesting makes sense. How does this trace generally look? Are the two controller spans basically the exact same duration or does it show overhead from Base/API when you are using Metal? |
A basic Rails trace would become:
In the most minimal of applications, spans 2 and 3 are expected to be of comparable length. However, for applications that perform additional operations after routing and before executing the controller action (e.g. I will produce screenshots to verify this hypothesis, and show how this looks. Overall I think by adding this additional span, we would more accurately represent Rails traces, and provide some additional surface area to which we could add future instrumentation of Rails controllers. |
I really like this approach you're suggesting @delner! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the tests are still failing, also it seems the implementation is still not complete yet and I think it would be great to have tests to check all the cases mentioned in one of your comments.
@delner Feel free to ping us once all relevant changes are implemented
@@ -1,11 +1,10 @@ | |||
require 'ddtrace/contrib/rails/rails_helper' | |||
|
|||
RSpec.describe 'ActionController tracing' do | |||
let(:tracer) { ::Datadog::Tracer.new(writer: FauxWriter.new) } | |||
let(:tracer) { get_test_tracer } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@pawelchcki Yup, apologize, this is definitely not ready yet. Needs tests and additional implementation. What code we have here will fix the issue, but the tests won't reflect that yet. I'll let you know when it's ready. |
59204f3
to
96e26dd
Compare
@delner Since this is very outdated, shall we go ahead and close this PR for now? |
The Rails integration currently does not produce controller spans for Rails controllers that short-circuit themselves in a
before_action
clause e.g.head :no_content
.This is because tracing is injected at the
Metal
level, the base-most class for Rails controllers. However, whenBase
andAPI
controllers inherit fromMetal
, they also include other modules such asCallbacks
, which overlay theaction
functions we modified at theMetal
level. When these functions are overridden at the child class level (e.g.Base
,API
), the behavior inCallbacks
takes precedence over that of our own tracing module, despite the use ofprepend
.The implementation proposed in the pull request moves the patching from
Metal
toBase
andAPI
, so as to move the tracing module further up the ancestor chain. In doing so, however, controllers which inherit directly fromMetal
will no longer receive tracing out-of-the-box. They would need toinclude Datadog::Contrib::Rails::ActionControllerPatch
to receive tracing.