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

feat: http client integration #876

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

aldy505
Copy link
Contributor

@aldy505 aldy505 commented Aug 27, 2024

An effort to implement this: https://develop.sentry.dev/sdk/telemetry/traces/modules/requests/

Since we already have tracing without performance, this should be good to go.

Copy link

codecov bot commented Aug 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.41%. Comparing base (9b8b7be) to head (2cb97af).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #876      +/-   ##
==========================================
+ Coverage   83.21%   83.41%   +0.20%     
==========================================
  Files          55       56       +1     
  Lines        5897     5970      +73     
==========================================
+ Hits         4907     4980      +73     
  Misses        820      820              
  Partials      170      170              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

@ribice
Copy link
Collaborator

ribice commented Sep 3, 2024

@aldy505 We should document this (in _examples, and perhaps sentry-docs?), and also update changelog accordingly.


span := sentry.StartSpan(ctx, "http.client", sentry.WithTransactionName(fmt.Sprintf("%s %s", request.Method, cleanRequestURL)))

for k, v := range s.tags {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we just set the span.Tags instead of ranging through these, and setting one by one?

This is the 'right' way to do it, but it involves checking for nil map and dealing with mutex.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lol good catch. I was copying directly from this PR aldy505/sentry-integration#1

@aldy505 aldy505 requested a review from ribice September 3, 2024 14:04
Comment on lines 73 to 75
span := sentry.StartSpan(ctx, "http.client", sentry.WithTransactionName(fmt.Sprintf("%s %s", request.Method, cleanRequestURL)))
span.Tags = s.tags
defer span.Finish()
Copy link
Member

Choose a reason for hiding this comment

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

We do not want to always start transactions here. If one already exists, start a child span.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to be clear: http.client spans should only created if there is any parent span?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, Sentry does not work well with these kind of single span transactions. We can revisit this once span streaming is fully supported in the product, but this will take a few months.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah got it.

Copy link
Member

Choose a reason for hiding this comment

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

https://sentry.io/insights/http/ should also work with these spans fwiw, docs are here.

Copy link
Member

Choose a reason for hiding this comment

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

*which you already mentioned in the PR description, nvm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another question (unrelated): Does that also affects all the span op within the insights module? Meaning not only http.client, but db.sql and messaging.* also counts?

Copy link
Member

Choose a reason for hiding this comment

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

I guess technically we extract all the required fields from a transaction and store it into the span data set, though this is not how these modules where initially designed to work.

Comment on lines 70 to 74
// Only create the `http.client` span only if there is a parent span.
parentSpan := sentry.GetSpanFromContext(request.Context())
if parentSpan == nil {
return s.originalRoundTripper.RoundTrip(request)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A quick note why I prefer this instead of creating a sentry.WithOnlyIfParentExists() (a SpanOption type):

I used the JS SDK a lot at work lately, and I've been wondering the entire week, on their startSpan function, they have this as an option: https://github.com/getsentry/sentry-javascript/blob/216aaeba1ee27cce8a4876e1f9212ba374eb30b3/packages/types/src/startSpanOptions.ts#L14-L15

Should the Go SDK move forward with that, as a SpanOption or not?

We could to the SpanOption thing, but it feels really weird since the way Go SDK handles scopes/hubs with span is to add the span pointer into the scope. See

sentry-go/tracing.go

Lines 196 to 199 in a6acd05

if clientOptions.EnableTracing {
hub := hubFromContext(ctx)
hub.Scope().SetSpan(&span)
}

Although we could just not call the scope.SetSpan() function, I don't know about the behavior if this span that we're creating will ever have a child span being created manually by the user.

Comment on lines +88 to +90
// Always add `Baggage` and `Sentry-Trace` headers.
request.Header.Add("Baggage", span.ToBaggage())
request.Header.Add("Sentry-Trace", span.ToSentryTrace())
Copy link
Member

Choose a reason for hiding this comment

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

To support the recently added "Tracing without Performance" feature, we should use hub.GetTraceparent() and hub.GetBaggage()

cleanRequestURL := request.URL.Redacted()

span := parentSpan.StartChild("http.client", sentry.WithTransactionName(fmt.Sprintf("%s %s", request.Method, cleanRequestURL)))
span.Tags = s.tags
Copy link
Member

Choose a reason for hiding this comment

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

Why are we setting span tags here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it not ideal? Should I remove it?

Copy link
Member

Choose a reason for hiding this comment

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

What info is in there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Decided to just remove it.

tags map[string]string
}

func (s *SentryRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When I wrote this, the docs said trace propagation targets is only for avoiding CORS-related issue, and since the dotnet SDK does not have that option too, I don't implement it here.

But is my assumption wrong here? Should all SDK implements trace propagation targets then?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

request.Header.Add("Baggage", span.ToBaggage())
request.Header.Add("Sentry-Trace", span.ToSentryTrace())

response, err := s.originalRoundTripper.RoundTrip(request)
Copy link
Member

Choose a reason for hiding this comment

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

We also want to handle the err case

@aldy505 aldy505 requested a review from cleptric November 6, 2024 13:59
client.go Outdated
// Control with URLs trace propagation should be enabled. Does not support regex patterns.
TracePropagationTargets []string
// When set to true, the SDK will start a span for outgoing HTTP OPTIONS requests.
TraceOptionsRequests bool
Copy link
Member

Choose a reason for hiding this comment

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

Why did you add this option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Saw it on the dev docs. Should I not implement that?

Copy link
Member

Choose a reason for hiding this comment

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

Link?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

When set to true transactions should be created for HTTP OPTIONS requests.

This option does not apply to outgoing HTTP requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. Will update that later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants