-
Notifications
You must be signed in to change notification settings - Fork 242
feat: http client integration #876
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
6b48923
fd66575
439e98b
5f4c5ae
5214ea5
ed105c1
4e55daa
15aa59a
099dad4
7d9555d
f018dde
d6f2663
6af10bf
c5ad7e4
081fc0b
a3a6367
2cb97af
ce3d4ea
1075de4
ae861f3
a5eb96f
791feb5
c912fe9
3e9a23b
912797f
0e21a00
b31001c
389ca62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -67,10 +67,15 @@ type SentryRoundTripper struct { | |||||||||
| } | ||||||||||
|
|
||||||||||
| func (s *SentryRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { | ||||||||||
| ctx := request.Context() | ||||||||||
| // 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) | ||||||||||
| } | ||||||||||
|
Comment on lines
95
to
104
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A quick note why I prefer this instead of creating a I used the JS SDK a lot at work lately, and I've been wondering the entire week, on their Should the Go SDK move forward with that, as a We could to the Lines 196 to 199 in a6acd05
Although we could just not call the |
||||||||||
|
|
||||||||||
| cleanRequestURL := request.URL.Redacted() | ||||||||||
|
|
||||||||||
| span := sentry.StartSpan(ctx, "http.client", sentry.WithTransactionName(fmt.Sprintf("%s %s", request.Method, cleanRequestURL))) | ||||||||||
| span := parentSpan.StartChild("http.client", sentry.WithTransactionName(fmt.Sprintf("%s %s", request.Method, cleanRequestURL))) | ||||||||||
aldy505 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| span.Tags = s.tags | ||||||||||
|
||||||||||
| defer span.Finish() | ||||||||||
|
|
||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import ( | |
| "io" | ||
| "net/http" | ||
| "strconv" | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/getsentry/sentry-go" | ||
|
|
@@ -52,15 +53,15 @@ func TestIntegration(t *testing.T) { | |
| TracerOptions []sentryhttpclient.SentryRoundTripTracerOption | ||
| WantStatus int | ||
| WantResponseLength int | ||
| WantTransaction *sentry.Event | ||
| WantSpan *sentry.Span | ||
| }{ | ||
| { | ||
| RequestMethod: "GET", | ||
| RequestURL: "https://example.com/foo", | ||
| WantStatus: 200, | ||
| WantResponseLength: 0, | ||
| WantTransaction: &sentry.Event{ | ||
| Extra: map[string]interface{}{ | ||
| WantSpan: &sentry.Span{ | ||
| Data: map[string]interface{}{ | ||
| "http.fragment": string(""), | ||
| "http.query": string(""), | ||
| "http.request.method": string("GET"), | ||
|
|
@@ -69,11 +70,12 @@ func TestIntegration(t *testing.T) { | |
| "server.address": string("example.com"), | ||
| "server.port": string(""), | ||
| }, | ||
| Level: sentry.LevelInfo, | ||
| Transaction: "GET https://example.com/foo", | ||
| Type: "transaction", | ||
| TransactionInfo: &sentry.TransactionInfo{Source: "custom"}, | ||
| Tags: map[string]string{}, | ||
| Name: "GET https://example.com/foo", | ||
| Op: "http.client", | ||
| Tags: map[string]string{}, | ||
| Origin: "manual", | ||
| Sampled: sentry.SampledTrue, | ||
| Status: sentry.SpanStatusOK, | ||
| }, | ||
| }, | ||
| { | ||
|
|
@@ -82,8 +84,8 @@ func TestIntegration(t *testing.T) { | |
| TracerOptions: []sentryhttpclient.SentryRoundTripTracerOption{nil, nil, nil}, | ||
| WantStatus: 200, | ||
| WantResponseLength: 0, | ||
| WantTransaction: &sentry.Event{ | ||
| Extra: map[string]interface{}{ | ||
| WantSpan: &sentry.Span{ | ||
| Data: map[string]interface{}{ | ||
| "http.fragment": string("readme"), | ||
| "http.query": string("baz=123"), | ||
| "http.request.method": string("GET"), | ||
|
|
@@ -92,11 +94,12 @@ func TestIntegration(t *testing.T) { | |
| "server.address": string("example.com"), | ||
| "server.port": string("443"), | ||
| }, | ||
| Level: sentry.LevelInfo, | ||
| Transaction: "GET https://example.com:443/foo/bar?baz=123#readme", | ||
| Type: "transaction", | ||
| TransactionInfo: &sentry.TransactionInfo{Source: "custom"}, | ||
| Tags: map[string]string{}, | ||
| Name: "GET https://example.com:443/foo/bar?baz=123#readme", | ||
| Op: "http.client", | ||
| Tags: map[string]string{}, | ||
| Origin: "manual", | ||
| Sampled: sentry.SampledTrue, | ||
| Status: sentry.SpanStatusOK, | ||
| }, | ||
| }, | ||
| { | ||
|
|
@@ -105,8 +108,8 @@ func TestIntegration(t *testing.T) { | |
| TracerOptions: []sentryhttpclient.SentryRoundTripTracerOption{sentryhttpclient.WithTag("user", "def"), sentryhttpclient.WithTags(map[string]string{"domain": "example.com"})}, | ||
| WantStatus: 400, | ||
| WantResponseLength: 0, | ||
| WantTransaction: &sentry.Event{ | ||
| Extra: map[string]interface{}{ | ||
| WantSpan: &sentry.Span{ | ||
| Data: map[string]interface{}{ | ||
| "http.fragment": string(""), | ||
| "http.query": string("abc=def&bar=123"), | ||
| "http.request.method": string("HEAD"), | ||
|
|
@@ -119,19 +122,20 @@ func TestIntegration(t *testing.T) { | |
| "user": "def", | ||
| "domain": "example.com", | ||
| }, | ||
| Level: sentry.LevelInfo, | ||
| Transaction: "HEAD https://example.com:8443/foo?bar=123&abc=def", | ||
| Type: "transaction", | ||
| TransactionInfo: &sentry.TransactionInfo{Source: "custom"}, | ||
| Name: "HEAD https://example.com:8443/foo?bar=123&abc=def", | ||
| Op: "http.client", | ||
| Origin: "manual", | ||
| Sampled: sentry.SampledTrue, | ||
| Status: sentry.SpanStatusInvalidArgument, | ||
| }, | ||
| }, | ||
| { | ||
| RequestMethod: "POST", | ||
| RequestURL: "https://john:[email protected]:4321/secret", | ||
| WantStatus: 200, | ||
| WantResponseLength: 1024, | ||
| WantTransaction: &sentry.Event{ | ||
| Extra: map[string]interface{}{ | ||
| WantSpan: &sentry.Span{ | ||
| Data: map[string]interface{}{ | ||
| "http.fragment": string(""), | ||
| "http.query": string(""), | ||
| "http.request.method": string("POST"), | ||
|
|
@@ -140,33 +144,35 @@ func TestIntegration(t *testing.T) { | |
| "server.address": string("example.com"), | ||
| "server.port": string("4321"), | ||
| }, | ||
| Level: sentry.LevelInfo, | ||
| Transaction: "POST https://john:[email protected]:4321/secret", | ||
| Type: "transaction", | ||
| TransactionInfo: &sentry.TransactionInfo{Source: "custom"}, | ||
| Tags: map[string]string{}, | ||
| Name: "POST https://john:[email protected]:4321/secret", | ||
| Op: "http.client", | ||
| Tags: map[string]string{}, | ||
| Origin: "manual", | ||
| Sampled: sentry.SampledTrue, | ||
| Status: sentry.SpanStatusOK, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| transactionsCh := make(chan *sentry.Event, len(tests)) | ||
| spansCh := make(chan []*sentry.Span, len(tests)) | ||
|
|
||
| sentryClient, err := sentry.NewClient(sentry.ClientOptions{ | ||
| EnableTracing: true, | ||
| TracesSampleRate: 1.0, | ||
| BeforeSendTransaction: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event { | ||
| transactionsCh <- event | ||
| spansCh <- event.Spans | ||
| return event | ||
| }, | ||
| }) | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| var want []*sentry.Event | ||
| for _, tt := range tests { | ||
| hub := sentry.NewHub(sentryClient, sentry.NewScope()) | ||
| ctx := sentry.SetHubOnContext(context.Background(), hub) | ||
| span := sentry.StartSpan(ctx, "fake_parent", sentry.WithTransactionName("Fake Parent")) | ||
| ctx = span.Context() | ||
|
|
||
| request, err := http.NewRequestWithContext(ctx, tt.RequestMethod, tt.RequestURL, nil) | ||
| if err != nil { | ||
|
|
@@ -188,32 +194,45 @@ func TestIntegration(t *testing.T) { | |
| } | ||
|
|
||
| response.Body.Close() | ||
| want = append(want, tt.WantTransaction) | ||
| span.Finish() | ||
| } | ||
|
|
||
| if ok := sentryClient.Flush(testutils.FlushTimeout()); !ok { | ||
| t.Fatal("sentry.Flush timed out") | ||
| } | ||
| close(transactionsCh) | ||
| var got []*sentry.Event | ||
| for e := range transactionsCh { | ||
| close(spansCh) | ||
|
|
||
| var got [][]*sentry.Span | ||
| for e := range spansCh { | ||
| got = append(got, e) | ||
| } | ||
|
|
||
| optstrans := cmp.Options{ | ||
| cmpopts.IgnoreFields( | ||
| sentry.Event{}, | ||
| "Contexts", "EventID", "Platform", "Modules", | ||
| "Release", "Sdk", "ServerName", "Timestamp", | ||
| "sdkMetaData", "StartTime", "Spans", | ||
| ), | ||
| cmpopts.IgnoreFields( | ||
| sentry.Request{}, | ||
| "Env", | ||
| sentry.Span{}, | ||
| "TraceID", "SpanID", "ParentSpanID", "StartTime", "EndTime", | ||
| "mu", "parent", "sampleRate", "ctx", "dynamicSamplingContext", "recorder", "finishOnce", "collectProfile", "contexts", | ||
| ), | ||
| } | ||
| if diff := cmp.Diff(want, got, optstrans); diff != "" { | ||
| t.Fatalf("Transaction mismatch (-want +got):\n%s", diff) | ||
| for i, tt := range tests { | ||
| var foundMatch = false | ||
| gotSpans := got[i] | ||
|
|
||
| var diffs []string | ||
| for _, gotSpan := range gotSpans { | ||
| if diff := cmp.Diff(tt.WantSpan, gotSpan, optstrans); diff != "" { | ||
| diffs = append(diffs, diff) | ||
| } else { | ||
| foundMatch = true | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if foundMatch { | ||
| continue | ||
| } else { | ||
| t.Errorf("Span mismatch (-want +got):\n%s", strings.Join(diffs, "\n")) | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.