diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 10def8396..bad2f25eb 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -23,6 +23,8 @@ endif::[] https://github.com/elastic/apm-agent-go/compare/v1.13.1...master[View commits] +- module/apmhttp: add apmhttp.WithClientSpanType ClientOption to set the span type of http client requests {pull}1106[#(1106)] + [[release-notes-1.x]] === Go Agent version 1.x diff --git a/module/apmhttp/client.go b/module/apmhttp/client.go index f48ca4877..e629e7d4f 100644 --- a/module/apmhttp/client.go +++ b/module/apmhttp/client.go @@ -59,6 +59,7 @@ func WrapRoundTripper(r http.RoundTripper, o ...ClientOption) http.RoundTripper r: r, requestName: ClientRequestName, requestIgnorer: IgnoreNone, + spanType: "external.http", } for _, o := range o { o(rt) @@ -71,6 +72,7 @@ type roundTripper struct { requestName RequestNameFunc requestIgnorer RequestIgnorerFunc traceRequests bool + spanType string } // RoundTrip delegates to r.r, emitting a span if req's context @@ -102,7 +104,7 @@ func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { } name := r.requestName(req) - span := tx.StartSpan(name, "external.http", apm.SpanFromContext(ctx)) + span := tx.StartSpan(name, r.spanType, apm.SpanFromContext(ctx)) var rt *requestTracer if !span.Dropped() { traceContext = span.TraceContext() @@ -211,3 +213,12 @@ func WithClientRequestName(r RequestNameFunc) ClientOption { rt.requestName = r }) } + +// WithClientSpanType sets the span type for HTTP client requests. +// +// Defaults to "external.http". +func WithClientSpanType(spanType string) ClientOption { + return ClientOption(func(rt *roundTripper) { + rt.spanType = spanType + }) +} diff --git a/module/apmhttp/client_test.go b/module/apmhttp/client_test.go index ae77d5611..2a5f6d682 100644 --- a/module/apmhttp/client_test.go +++ b/module/apmhttp/client_test.go @@ -354,6 +354,22 @@ func TestClientOutcome(t *testing.T) { assert.Equal(t, "failure", spans[2].Outcome) } +func TestWithClientSpanType(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusTeapot) + })) + defer server.Close() + + option := apmhttp.WithClientSpanType("cache") + _, spans, _ := apmtest.WithTransaction(func(ctx context.Context) { + mustGET(ctx, server.URL, option) + }) + + require.Len(t, spans, 1) + span := spans[0] + assert.Equal(t, "cache", span.Type) +} + func mustGET(ctx context.Context, url string, o ...apmhttp.ClientOption) (statusCode int, responseBody string) { client := apmhttp.WrapClient(http.DefaultClient, o...) resp, err := ctxhttp.Get(ctx, client, url)