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

Set Sinatra resource setting at beginning of request and delay setting fallback resource #1628

Merged

Conversation

ivoanjo
Copy link
Member

@ivoanjo ivoanjo commented Aug 3, 2021

As of #1623, the profiler records the resource of the root span, on top of the span id and trace id during sampling.

Also, as discusssed in the description of #1623 (in the "Getting the correct resource" section) integrations where the
resource is only set at the end pose an extra challenge, as the request may not be finished in time for the resource to be included in the profiler payload.

This means that the profiler may miss the resource for some of the requests, depending on timing of when the sampling happens and when the request finishes.

(Note that in this case, the trace id and span id will still be propagated, so the samples will always be able to be tied back to the trace that originated them; it's just the resource that will not be included in the profiler data).

To avoid this issue for many of our customers, let's set the Sinatra resource setting at the beginning of the request, thus avoiding the issue altogether for Sinatra.

Note: I did not touch the existing code to set the resource at the end, which had a quite scary TODO (lines 47-64) and seemed like something I shouldn't touch.

Note 2: This is similar to what we did in #1626 for the Rails integration.

Finally, I also tweaked TracerMiddleware to only set the fallback resource (the request method) at the end of the request (if needed at all), instead keeping a nil until the resource gets resolved. This way, the profiler can tell that no resource is
yet available, and thus will not gather/display the fallback resource.

As of #1623, the profiler records the `resource` of the root span,
on top of the span id and trace id during sampling.

Also, as discusssed in the description of #1623 (in the
"Getting the correct `resource`" section) integrations where the
`resource` is only set at the end pose an extra challenge, as the
request may not be finished in time for the `resource` to be included
in the profiler payload.
This means that the profiler may miss the `resource` for some of the
requests, depending on timing of when the sampling happens and when the
request finishes.
(Note that in this case, the trace id and span id will still be
propagated, so the samples will always be able to be tied back to the
trace that originated them; it's just the `resource` that will not be
included in the profiler data).

To avoid this issue for many of our customers, let's set the Sinatra
`resource` setting to the beginning of the request, thus avoiding
the issue altogether for Sinatra.

Note that I did not touch the existing code to set the resource at the
end, which had a quite scary TODO (lines 47-64) and seemed like
something I shouldn't touch.

Note 2: This is similar to what we did in #1626 for the Rails
integration.
By using a `nil` resource, the profiler can tell that no resource is
yet available, and thus will not gather/display the fallback resource.
@ivoanjo ivoanjo requested a review from a team August 3, 2021 13:27
else
Sinatra::Env.datadog_span(env, self.class)
end
if sinatra_request_span # DEV: Is it possible for sinatra_request_span to ever be nil here?
Copy link
Member

Choose a reason for hiding this comment

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

Unlikely, but something we can track with self-telemetry in the future to build confidence. (no action now)

@ivoanjo ivoanjo merged commit 4b4d9ca into master Aug 4, 2021
@ivoanjo ivoanjo deleted the ivoanjo/sinatra-set-resource-at-beginning-of-request branch August 4, 2021 07:48
@github-actions github-actions bot added this to the 0.52.0 milestone Aug 4, 2021
ivoanjo added a commit that referenced this pull request Aug 4, 2021
As of #1623, the profiler records the `resource` of the root span,
on top of the span id and trace id during sampling.

Also, as discusssed in the description of #1623 (in the
"Getting the correct `resource`" section) integrations where the
`resource` is only set at the end pose an extra challenge, as the
request may not be finished in time for the `resource` to be included
in the profiler payload.
This means that the profiler may miss the `resource` for some of the
requests, depending on timing of when the sampling happens and when the
request finishes.
(Note that in this case, the trace id and span id will still be
propagated, so the samples will always be able to be tied back to the
trace that originated them; it's just the `resource` that will not be
included in the profiler data).

To avoid this issue for many of our customers, let's move the Grape
`resource` setting to the beginning of the request, thus avoiding
the issue altogether for this integration.

(Note: This is similar to what we did for Rails in #1626 and Sinatra
in #1628)
ivoanjo added a commit that referenced this pull request Aug 4, 2021
As of #1623, the profiler records the `resource` of the root span,
on top of the span id and trace id during sampling.

Also, as discusssed in the description of #1623 (in the
"Getting the correct `resource`" section) integrations where the
`resource` is only set at the end pose an extra challenge, as the
request may not be finished in time for the `resource` to be included
in the profiler payload.
This means that the profiler may miss the `resource` for some of the
requests, depending on timing of when the sampling happens and when the
request finishes.
(Note that in this case, the trace id and span id will still be
propagated, so the samples will always be able to be tied back to the
trace that originated them; it's just the `resource` that will not be
included in the profiler data).

To avoid this issue for many of our customers, let's move the Grape
`resource` setting to the beginning of the request, thus avoiding
the issue altogether for this integration.

(Note: This is similar to what we did for Rails in #1626 and Sinatra
in #1628)
ivoanjo added a commit that referenced this pull request Aug 11, 2021
…ssing

This fixes a regression introduced in version 0.52.0 by #1628.

When a Sinatra modular application being traced is missing the
`Datadog::Contrib::Sinatra::Tracer` middleware
(as documented in
<https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#sinatra>),
no Sinatra request span is ever created (only a route span).

Because we didn't properly account for this in `#datadog_span`, the
following `NoMethodError` was triggered:

```
NoMethodError: undefined method `[]' for nil:NilClass
  dd-trace-rb/lib/ddtrace/contrib/sinatra/env.rb:13:in `datadog_span'
  dd-trace-rb/lib/ddtrace/contrib/sinatra/tracer.rb:122:in `block in route_eval'
  dd-trace-rb/lib/ddtrace/tracer.rb:283:in `trace'
  dd-trace-rb/lib/ddtrace/contrib/sinatra/tracer.rb:105:in `route_eval'
  ruby-2.7.4/gems/sinatra-2.1.0/lib/sinatra/base.rb:1013:in `block (2 levels) in route!'
```

I suspect this is the same issue as was reported in #1643.

Because this configuration is actually not desirable -- spans reported
will be missing crucial request information, as discussed in #1643 --
I've also added a warning to hopefully steer users in the right
direction.
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.

None yet

2 participants