From 3b145dfa112871dd7dc7f5215f419f9ca52e1300 Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 14:54:38 -0400 Subject: [PATCH 01/16] Add convenience wrappers for http.Get/Post, etc. Add convenience wrappers for http.{Get,Post,Head,PostForm} using the otelhttp transport and taking a context.Context directly. Makes instrumenting code using the original http convenience methods a one-line change instead of a multiline one. --- instrumentation/net/http/otelhttp/client.go | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 instrumentation/net/http/otelhttp/client.go diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go new file mode 100644 index 00000000000..b833b593c4b --- /dev/null +++ b/instrumentation/net/http/otelhttp/client.go @@ -0,0 +1,58 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otelhttp + +import ( + "context" + "io" + "net/http" + "net/url" + "strings" +) + +var otelDefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} + +// Convenience replacement for http.Get +func Get(ctx context.Context, url string) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return nil, err + } + return otelDefaultClient.Do(req) +} + +// Convenience replacement for http.Head +func Head(ctx context.Context, url string) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) + if err != nil { + return nil, err + } + return otelDefaultClient.Do(req) +} + +// Convenience replacement for http.Post +func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error) { + req, err := http.NewRequestWithContext(ctx, "POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", contentType) + return otelDefaultClient.Do(req) +} + +// Convenience replacement for http.PostForm +func PostForm(ctx context.Context, url string, data url.Values) (resp *http.Response, err error) { + return Post(ctx, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} From 6579bb304db29de7ebf5028c86f4b26e630df38c Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 15:06:24 -0400 Subject: [PATCH 02/16] Update instrumentation/net/http/otelhttp/client.go Co-authored-by: Anthony Mirabella --- instrumentation/net/http/otelhttp/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index b833b593c4b..c1b5f2a6d6a 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -24,7 +24,7 @@ import ( var otelDefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} -// Convenience replacement for http.Get +// Get is a convenient replacement for http.Get that adds a span around the request. func Get(ctx context.Context, url string) (resp *http.Response, err error) { req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { From 137ccecbf0654fefd9398d2bb7628efcdc81024b Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 15:06:32 -0400 Subject: [PATCH 03/16] Update instrumentation/net/http/otelhttp/client.go Co-authored-by: Anthony Mirabella --- instrumentation/net/http/otelhttp/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index c1b5f2a6d6a..2c972d3d87f 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -42,7 +42,7 @@ func Head(ctx context.Context, url string) (resp *http.Response, err error) { return otelDefaultClient.Do(req) } -// Convenience replacement for http.Post +// Post is a convenient replacement for http.Post that adds a span around the request. func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *http.Response, err error) { req, err := http.NewRequestWithContext(ctx, "POST", url, body) if err != nil { From 9a85caedb249863d9d8c8e6d841af1d0b17fa1e4 Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 15:06:39 -0400 Subject: [PATCH 04/16] Update instrumentation/net/http/otelhttp/client.go Co-authored-by: Anthony Mirabella --- instrumentation/net/http/otelhttp/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index 2c972d3d87f..5510ea91f0f 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -52,7 +52,7 @@ func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *h return otelDefaultClient.Do(req) } -// Convenience replacement for http.PostForm +// PostForm is a convenient replacement for http.PostForm that adds a span around the request. func PostForm(ctx context.Context, url string, data url.Values) (resp *http.Response, err error) { return Post(ctx, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) } From 609f2962379b50bb258826c8d6209cb9c08bdf5c Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 15:06:47 -0400 Subject: [PATCH 05/16] Update instrumentation/net/http/otelhttp/client.go Co-authored-by: Anthony Mirabella --- instrumentation/net/http/otelhttp/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index 5510ea91f0f..d40b4e63484 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -33,7 +33,7 @@ func Get(ctx context.Context, url string) (resp *http.Response, err error) { return otelDefaultClient.Do(req) } -// Convenience replacement for http.Head +// Head is a convenient replacement for http.Head that adds a span around the request. func Head(ctx context.Context, url string) (resp *http.Response, err error) { req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) if err != nil { From 016d632da48e34b704c392842b01108623dc7a13 Mon Sep 17 00:00:00 2001 From: John Bley Date: Fri, 9 Oct 2020 15:09:21 -0400 Subject: [PATCH 06/16] Document new convenience wrappers in CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f73b2346892..43eca6f2465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm Instead, a new `WithTracerProvider` option is added to configure the `TracerProvider` used when creating the `Tracer` for the instrumentation. (#373) - Remove `go.opentelemetry.io/otel/sdk` dependency from instrumentation. (#381) +### Added + +- `otelhttp.{Get,Head,Post,PostForm} convenience wrappers for their `http` counterparts. (#390) + ### Fixed - The `go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho.Middleware` no longer sends duplicate errors to the global `ErrorHandler`. (#377, #364) From 2837de8d4cbf4f94686332a7231b9ecc840ab306 Mon Sep 17 00:00:00 2001 From: John Bley Date: Sun, 11 Oct 2020 13:00:20 -0400 Subject: [PATCH 07/16] Add tests, don't use cached global client. --- instrumentation/net/http/otelhttp/client.go | 11 +-- .../net/http/otelhttp/client_test.go | 73 +++++++++++++++++++ 2 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 instrumentation/net/http/otelhttp/client_test.go diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index d40b4e63484..47416cd11d2 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -22,15 +22,14 @@ import ( "strings" ) -var otelDefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} - // Get is a convenient replacement for http.Get that adds a span around the request. func Get(ctx context.Context, url string) (resp *http.Response, err error) { req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, err } - return otelDefaultClient.Do(req) + client := http.Client{Transport: NewTransport(http.DefaultTransport)} + return client.Do(req) } // Head is a convenient replacement for http.Head that adds a span around the request. @@ -39,7 +38,8 @@ func Head(ctx context.Context, url string) (resp *http.Response, err error) { if err != nil { return nil, err } - return otelDefaultClient.Do(req) + client := http.Client{Transport: NewTransport(http.DefaultTransport)} + return client.Do(req) } // Post is a convenient replacement for http.Post that adds a span around the request. @@ -49,7 +49,8 @@ func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *h return nil, err } req.Header.Set("Content-Type", contentType) - return otelDefaultClient.Do(req) + client := http.Client{Transport: NewTransport(http.DefaultTransport)} + return client.Do(req) } // PostForm is a convenient replacement for http.PostForm that adds a span around the request. diff --git a/instrumentation/net/http/otelhttp/client_test.go b/instrumentation/net/http/otelhttp/client_test.go new file mode 100644 index 00000000000..76e179f480a --- /dev/null +++ b/instrumentation/net/http/otelhttp/client_test.go @@ -0,0 +1,73 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package otelhttp + +import ( + "context" + "net/http" + "net/http/httptest" + "strings" + "testing" + "net/url" + + "go.opentelemetry.io/otel/api/global" + + mocktrace "go.opentelemetry.io/contrib/internal/trace" +) + +func TestConvenienceWrappers(t *testing.T) { + provider, tracer := mocktrace.NewTracerProviderAndTracer(instrumentationName) + oldProvider := global.TracerProvider() + global.SetTracerProvider(provider) + defer global.SetTracerProvider(oldProvider) + + content := []byte("Hello, world!") + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("traceparent") == "" { + t.Fatal("Expected traceparent header") + } + if _, err := w.Write(content); err != nil { + t.Fatal(err) + } + })) + defer ts.Close() + + context,span := tracer.Start(context.Background(), "parent") + defer span.End() + + _, err := Get(context, ts.URL); + if err != nil { + t.Fatal(err) + } + + _, err = Head(context, ts.URL); + if err != nil { + t.Fatal(err) + } + + _, err = Post(context, ts.URL, "text/plain", strings.NewReader("test")); + if err != nil { + t.Fatal(err) + } + + form := make(url.Values) + form.Set("foo", "bar") + _, err = PostForm(context, ts.URL, form); + if err != nil { + t.Fatal(err) + } + +} From d700ecb83d9522c3c26a0158e3356ee19c576f14 Mon Sep 17 00:00:00 2001 From: John Bley Date: Sun, 11 Oct 2020 13:09:01 -0400 Subject: [PATCH 08/16] code format --- instrumentation/net/http/otelhttp/client_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client_test.go b/instrumentation/net/http/otelhttp/client_test.go index 76e179f480a..a7bd7dcfc22 100644 --- a/instrumentation/net/http/otelhttp/client_test.go +++ b/instrumentation/net/http/otelhttp/client_test.go @@ -18,9 +18,9 @@ import ( "context" "net/http" "net/http/httptest" + "net/url" "strings" "testing" - "net/url" "go.opentelemetry.io/otel/api/global" @@ -45,27 +45,27 @@ func TestConvenienceWrappers(t *testing.T) { })) defer ts.Close() - context,span := tracer.Start(context.Background(), "parent") + context, span := tracer.Start(context.Background(), "parent") defer span.End() - _, err := Get(context, ts.URL); + _, err := Get(context, ts.URL) if err != nil { t.Fatal(err) } - _, err = Head(context, ts.URL); + _, err = Head(context, ts.URL) if err != nil { t.Fatal(err) } - _, err = Post(context, ts.URL, "text/plain", strings.NewReader("test")); + _, err = Post(context, ts.URL, "text/plain", strings.NewReader("test")) if err != nil { t.Fatal(err) } form := make(url.Values) form.Set("foo", "bar") - _, err = PostForm(context, ts.URL, form); + _, err = PostForm(context, ts.URL, form) if err != nil { t.Fatal(err) } From 4bccf993796348d8065d9b53cbe15d6670d5d197 Mon Sep 17 00:00:00 2001 From: John Bley Date: Mon, 12 Oct 2020 12:53:35 -0400 Subject: [PATCH 09/16] Expose DefaultClient and use it for all convenience wrappers. --- instrumentation/net/http/otelhttp/client.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index 47416cd11d2..91160c6ef0a 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -22,14 +22,15 @@ import ( "strings" ) +var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} + // Get is a convenient replacement for http.Get that adds a span around the request. func Get(ctx context.Context, url string) (resp *http.Response, err error) { req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return nil, err } - client := http.Client{Transport: NewTransport(http.DefaultTransport)} - return client.Do(req) + return DefaultClient.Do(req) } // Head is a convenient replacement for http.Head that adds a span around the request. @@ -38,8 +39,7 @@ func Head(ctx context.Context, url string) (resp *http.Response, err error) { if err != nil { return nil, err } - client := http.Client{Transport: NewTransport(http.DefaultTransport)} - return client.Do(req) + return DefaultClient.Do(req) } // Post is a convenient replacement for http.Post that adds a span around the request. @@ -49,8 +49,7 @@ func Post(ctx context.Context, url, contentType string, body io.Reader) (resp *h return nil, err } req.Header.Set("Content-Type", contentType) - client := http.Client{Transport: NewTransport(http.DefaultTransport)} - return client.Do(req) + return DefaultClient.Do(req) } // PostForm is a convenient replacement for http.PostForm that adds a span around the request. From acf53c418c7c7cce9a42805ba24a399622a7a59b Mon Sep 17 00:00:00 2001 From: John Bley Date: Tue, 13 Oct 2020 12:49:58 -0400 Subject: [PATCH 10/16] Update instrumentation/net/http/otelhttp/client.go Co-authored-by: Sam Xie --- instrumentation/net/http/otelhttp/client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index 91160c6ef0a..4f1bcbfc30b 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -22,6 +22,9 @@ import ( "strings" ) +// DefaultClient is the default Client and is used by Get, Head, Post and PostForm. +// Some changes in OTel might not affect the DefaultClient, such as setting a new global propagator. +// Setting up a new client to apply changes. var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} // Get is a convenient replacement for http.Get that adds a span around the request. From 931f1ab83be5f8ee65ab8a144f34c9980ca44be0 Mon Sep 17 00:00:00 2001 From: John Bley Date: Wed, 14 Oct 2020 15:02:55 -0400 Subject: [PATCH 11/16] Update CHANGELOG.md Co-authored-by: Tyler Yahn --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43eca6f2465..83fc767b621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Added -- `otelhttp.{Get,Head,Post,PostForm} convenience wrappers for their `http` counterparts. (#390) +- `otelhttp.{Get,Head,Post,PostForm}` convenience wrappers for their `http` counterparts. (#390) ### Fixed From 7406373eed7b212aa59e1e257670e219e9046694 Mon Sep 17 00:00:00 2001 From: John Bley Date: Wed, 14 Oct 2020 15:08:02 -0400 Subject: [PATCH 12/16] Don't bother attempting to reset the global provider. --- instrumentation/net/http/otelhttp/client_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client_test.go b/instrumentation/net/http/otelhttp/client_test.go index a7bd7dcfc22..3181a4e2042 100644 --- a/instrumentation/net/http/otelhttp/client_test.go +++ b/instrumentation/net/http/otelhttp/client_test.go @@ -29,9 +29,7 @@ import ( func TestConvenienceWrappers(t *testing.T) { provider, tracer := mocktrace.NewTracerProviderAndTracer(instrumentationName) - oldProvider := global.TracerProvider() global.SetTracerProvider(provider) - defer global.SetTracerProvider(oldProvider) content := []byte("Hello, world!") From 21b6d316fc1c16f8ecd8fcddc900771f72aece63 Mon Sep 17 00:00:00 2001 From: John Bley Date: Wed, 14 Oct 2020 15:27:07 -0400 Subject: [PATCH 13/16] Assert existence of 4 clients spans for 4 client operations --- instrumentation/net/http/otelhttp/client_test.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client_test.go b/instrumentation/net/http/otelhttp/client_test.go index 3181a4e2042..70912f63263 100644 --- a/instrumentation/net/http/otelhttp/client_test.go +++ b/instrumentation/net/http/otelhttp/client_test.go @@ -46,26 +46,34 @@ func TestConvenienceWrappers(t *testing.T) { context, span := tracer.Start(context.Background(), "parent") defer span.End() - _, err := Get(context, ts.URL) + res, err := Get(context, ts.URL) if err != nil { t.Fatal(err) } + res.Body.Close() - _, err = Head(context, ts.URL) + res, err = Head(context, ts.URL) if err != nil { t.Fatal(err) } + res.Body.Close() - _, err = Post(context, ts.URL, "text/plain", strings.NewReader("test")) + res, err = Post(context, ts.URL, "text/plain", strings.NewReader("test")) if err != nil { t.Fatal(err) } + res.Body.Close() form := make(url.Values) form.Set("foo", "bar") - _, err = PostForm(context, ts.URL, form) + res, err = PostForm(context, ts.URL, form) if err != nil { t.Fatal(err) } + res.Body.Close() + + if len(tracer.EndedSpans()) != 4 { + t.Fatal("expected 4 client spans") + } } From 8d808126bddcb60add8b43342837457e1b01eaa7 Mon Sep 17 00:00:00 2001 From: John Bley Date: Thu, 15 Oct 2020 15:35:26 -0400 Subject: [PATCH 14/16] Improve comment on DefaultClient. --- instrumentation/net/http/otelhttp/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client.go b/instrumentation/net/http/otelhttp/client.go index 4f1bcbfc30b..0816b9f5daa 100644 --- a/instrumentation/net/http/otelhttp/client.go +++ b/instrumentation/net/http/otelhttp/client.go @@ -23,8 +23,8 @@ import ( ) // DefaultClient is the default Client and is used by Get, Head, Post and PostForm. -// Some changes in OTel might not affect the DefaultClient, such as setting a new global propagator. -// Setting up a new client to apply changes. +// Please be careful of intitialization order - for example, if you change +// the global propagator, the DefaultClient might still be using the old one var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)} // Get is a convenient replacement for http.Get that adds a span around the request. From b86f1a75b82bbf344c7d215ceed43d5dacf7bf5a Mon Sep 17 00:00:00 2001 From: John Bley Date: Tue, 20 Oct 2020 13:26:39 -0400 Subject: [PATCH 15/16] Improve span testing. --- instrumentation/net/http/otelhttp/client_test.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/instrumentation/net/http/otelhttp/client_test.go b/instrumentation/net/http/otelhttp/client_test.go index 70912f63263..66ec363d851 100644 --- a/instrumentation/net/http/otelhttp/client_test.go +++ b/instrumentation/net/http/otelhttp/client_test.go @@ -24,6 +24,8 @@ import ( "go.opentelemetry.io/otel/api/global" + "github.com/stretchr/testify/assert" + mocktrace "go.opentelemetry.io/contrib/internal/trace" ) @@ -34,9 +36,6 @@ func TestConvenienceWrappers(t *testing.T) { content := []byte("Hello, world!") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Header.Get("traceparent") == "" { - t.Fatal("Expected traceparent header") - } if _, err := w.Write(content); err != nil { t.Fatal(err) } @@ -72,8 +71,10 @@ func TestConvenienceWrappers(t *testing.T) { } res.Body.Close() - if len(tracer.EndedSpans()) != 4 { - t.Fatal("expected 4 client spans") - } - + spans := tracer.EndedSpans() + assert.Equal(t, 4, len(spans)) + assert.Equal(t, "GET", spans[0].Name) + assert.Equal(t, "HEAD", spans[1].Name) + assert.Equal(t, "POST", spans[2].Name) + assert.Equal(t, "POST", spans[3].Name) } From 68ca5a882ee2cbfdf7798d4f9342e519ff079f26 Mon Sep 17 00:00:00 2001 From: John Bley Date: Wed, 21 Oct 2020 09:40:01 -0400 Subject: [PATCH 16/16] Move release note to unreleased section --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b41ca850aa..cc1e2b2e9ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Added + +- `otelhttp.{Get,Head,Post,PostForm}` convenience wrappers for their `http` counterparts. (#390) + ## Fixed - `/detectors/aws` no longer fails if instance metadata is not available (e.g. not running in AWS) (#401) @@ -26,10 +30,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Remove `go.opentelemetry.io/otel/sdk` dependency from instrumentation. (#381) - Use `httpsnoop` in `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux` to ensure `http.ResponseWriter` additional interfaces are preserved. (#388) -### Added - -- `otelhttp.{Get,Head,Post,PostForm}` convenience wrappers for their `http` counterparts. (#390) - ### Fixed - The `go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho.Middleware` no longer sends duplicate errors to the global `ErrorHandler`. (#377, #364)