func()

in module/apmhttp/client.go [80:136]


func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if r.requestIgnorer(req) {
		return r.r.RoundTrip(req)
	}
	ctx := req.Context()
	tx := apm.TransactionFromContext(ctx)
	if tx == nil {
		return r.r.RoundTrip(req)
	}

	// RoundTrip is not supposed to mutate req, so copy req
	// and set the trace-context headers only in the copy.
	reqCopy := *req
	reqCopy.Header = make(http.Header, len(req.Header))
	for k, v := range req.Header {
		reqCopy.Header[k] = v
	}
	req = &reqCopy

	propagateLegacyHeader := tx.ShouldPropagateLegacyHeader()
	traceContext := tx.TraceContext()
	if !traceContext.Options.Recorded() {
		SetHeaders(req, traceContext, propagateLegacyHeader)
		return r.r.RoundTrip(req)
	}

	name := r.requestName(req)
	span := tx.StartExitSpan(name, r.spanType, apm.SpanFromContext(ctx))
	var rt *requestTracer
	if !span.Dropped() {
		traceContext = span.TraceContext()
		ctx = apm.ContextWithSpan(ctx, span)
		if r.traceRequests {
			ctx, rt = withClientTrace(ctx, tx, span)
		}
		req = RequestWithContext(ctx, req)
		span.Context.SetHTTPRequest(req)
	} else {
		span.End()
		span = nil
	}

	SetHeaders(req, traceContext, propagateLegacyHeader)
	resp, err := r.r.RoundTrip(req)
	if span != nil {
		if err != nil {
			if rt != nil {
				rt.end()
			}
			span.End()
		} else {
			span.Context.SetHTTPStatusCode(resp.StatusCode)
			resp.Body = &responseBody{span: span, body: resp.Body, requestTracer: rt}
		}
	}
	return resp, err
}