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

External API Requests all end up as "Unknown Domain" #970

Open
alkanna opened this issue Feb 25, 2025 · 1 comment
Open

External API Requests all end up as "Unknown Domain" #970

alkanna opened this issue Feb 25, 2025 · 1 comment

Comments

@alkanna
Copy link

alkanna commented Feb 25, 2025

Is there a trick to this ?
I created an instrumented http client that just implements a custom RoundTripper, in which I create a span if needed and enrich its data and set it as an http.client operation.
Is this supposed to be working with the current version of sentry-go ?

This is the RoundTripper :

// RoundTrip implements the http.RoundTripper interface
func (t *SentryTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.BaseTransport == nil {
		t.BaseTransport = httpx.NewClient().Transport
	}

	if len(t.TracePropagationTargets) > 0 {
		requestURL := req.URL.String()
		foundMatch := false
		for _, target := range t.TracePropagationTargets {
			if strings.Contains(requestURL, target) {
				foundMatch = true
				break
			}
		}

		if !foundMatch {
			return t.BaseTransport.RoundTrip(req)
		}
	}

	ctx := req.Context()

	hub := sentry.GetHubFromContext(ctx)
	if hub == nil {
		if currentHub := sentry.CurrentHub(); currentHub != nil {
			hub = currentHub.Clone()
			ctx = sentry.SetHubOnContext(ctx, hub)
			req = req.WithContext(ctx)

			req.Header.Set("baggage", hub.GetBaggage())
			req.Header.Set("sentry-trace", hub.GetTraceparent())
		}

		return t.BaseTransport.RoundTrip(req)
	}

	parentSpan := sentry.SpanFromContext(ctx)
	if parentSpan == nil {
		req.Header.Set("baggage", hub.GetBaggage())
		req.Header.Set("sentry-trace", hub.GetTraceparent())

		return t.BaseTransport.RoundTrip(req)
	}

	cleanRequestURL := req.URL.Redacted()

	spanName := fmt.Sprintf("%s %s", req.Method, cleanRequestURL)

	span := parentSpan.StartChild("http.client", sentry.WithTransactionName(spanName))

	span.Name = spanName

	defer span.Finish()

	span.SetData("http.query", req.URL.Query().Encode())
	span.SetData("http.fragment", req.URL.Fragment)
	span.SetData("http.request.method", req.Method)
	span.SetData("server.address", req.URL.Hostname())
	span.SetData("server.port", req.URL.Port())

	span.SetData("description", fmt.Sprintf("%s %s", req.Method, req.URL.Host))
	span.SetData("url", req.URL.String())
	span.SetData("url.full", req.URL.String())
	span.SetData("url.scheme", req.URL.Scheme)
	span.SetData("http.protocol.name", req.URL.Scheme)
	span.SetData("http.request.body.size", req.ContentLength)
	span.SetData("network.protocol.version", req.Proto)

	AddDetailsToSpan(ctx, span)

	req.Header.Set("baggage", span.ToBaggage())
	req.Header.Set("sentry-trace", span.ToSentryTrace())

	newReq := req.WithContext(span.Context())
	resp, err := t.BaseTransport.RoundTrip(newReq)
	if err != nil {
		span.Status = sentry.SpanStatusInternalError
		span.SetData("error", err.Error())
	}

	if resp != nil {
		span.Status = HTTPtoSpanStatus(resp.StatusCode)
		span.SetData("http.response.status_code", resp.StatusCode)
		span.SetData("http.response_content_length", resp.ContentLength)
	}

	return resp, err
}
@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Feb 25, 2025
@cleptric
Copy link
Member

Looks alright to me, I suppose you refer to the Outbound API Requests showing you Unknown Domain? The required span attributes are documented on https://develop.sentry.dev/sdk/telemetry/traces/modules/requests/, but as I said, look good to me.
Could you share a link to your org in case you use sentry.io so we could take a look?

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

No branches or pull requests

2 participants