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
}