From ec88a5640c7c0b97facfa506c9fc60ff325fa8e5 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Wed, 18 Aug 2021 09:16:43 -0700 Subject: [PATCH] Remove use of oteltest in otelecho (#997) * Refactor to use Noop TracerProvider where possible * Use tracetest instead of oteltest in test mod * Fix B3 propagators import --- .github/dependabot.yml | 10 ++ .../labstack/echo/otelecho/echo_test.go | 153 +++--------------- .../labstack/echo/otelecho/example/go.sum | 2 - .../github.com/labstack/echo/otelecho/go.mod | 1 - .../github.com/labstack/echo/otelecho/go.sum | 2 - .../labstack/echo/otelecho/test/doc.go | 22 +++ .../labstack/echo/otelecho/test/echo_test.go | 140 ++++++++++++++++ .../labstack/echo/otelecho/test/go.mod | 16 ++ .../labstack/echo/otelecho/test/go.sum | 65 ++++++++ 9 files changed, 278 insertions(+), 133 deletions(-) create mode 100644 instrumentation/github.com/labstack/echo/otelecho/test/doc.go create mode 100644 instrumentation/github.com/labstack/echo/otelecho/test/echo_test.go create mode 100644 instrumentation/github.com/labstack/echo/otelecho/test/go.mod create mode 100644 instrumentation/github.com/labstack/echo/otelecho/test/go.sum diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7a7c93e757e..9d1914f5e94 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -285,6 +285,16 @@ updates: schedule: interval: "weekly" day: "sunday" + - + package-ecosystem: "gomod" + directory: "/instrumentation/github.com/labstack/echo/otelecho/test" + labels: + - dependencies + - go + - "Skip Changelog" + schedule: + interval: "weekly" + day: "sunday" - package-ecosystem: "gomod" directory: "/instrumentation/github.com/Shopify/sarama/otelsarama" diff --git a/instrumentation/github.com/labstack/echo/otelecho/echo_test.go b/instrumentation/github.com/labstack/echo/otelecho/echo_test.go index f636b0371ea..b9481f89a10 100644 --- a/instrumentation/github.com/labstack/echo/otelecho/echo_test.go +++ b/instrumentation/github.com/labstack/echo/otelecho/echo_test.go @@ -26,123 +26,14 @@ import ( "github.com/labstack/echo/v4" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/oteltest" "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" b3prop "go.opentelemetry.io/contrib/propagators/b3" - "go.opentelemetry.io/otel/attribute" - oteltrace "go.opentelemetry.io/otel/trace" ) -func TestChildSpanFromGlobalTracer(t *testing.T) { - otel.SetTracerProvider(oteltest.NewTracerProvider()) - - router := echo.New() - router.Use(Middleware("foobar")) - router.GET("/user/:id", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) - _, ok := span.(*oteltest.Span) - assert.True(t, ok) - return c.NoContent(200) - }) - - r := httptest.NewRequest("GET", "/user/123", nil) - w := httptest.NewRecorder() - - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusOK, w.Result().StatusCode, "should call the 'user' handler") -} - -func TestChildSpanFromCustomTracer(t *testing.T) { - provider := oteltest.NewTracerProvider() - - router := echo.New() - router.Use(Middleware("foobar", WithTracerProvider(provider))) - router.GET("/user/:id", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) - _, ok := span.(*oteltest.Span) - assert.True(t, ok) - return c.NoContent(200) - }) - - r := httptest.NewRequest("GET", "/user/123", nil) - w := httptest.NewRecorder() - - router.ServeHTTP(w, r) - assert.Equal(t, http.StatusOK, w.Result().StatusCode, "should call the 'user' handler") -} - -func TestTrace200(t *testing.T) { - sr := new(oteltest.SpanRecorder) - provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) - - router := echo.New() - router.Use(Middleware("foobar", WithTracerProvider(provider))) - router.GET("/user/:id", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) - mspan, ok := span.(*oteltest.Span) - require.True(t, ok) - assert.Equal(t, attribute.StringValue("foobar"), mspan.Attributes()["http.server_name"]) - id := c.Param("id") - return c.String(200, id) - }) - - r := httptest.NewRequest("GET", "/user/123", nil) - w := httptest.NewRecorder() - - // do and verify the request - router.ServeHTTP(w, r) - response := w.Result() - require.Equal(t, http.StatusOK, response.StatusCode) - - // verify traces look good - spans := sr.Completed() - require.Len(t, spans, 1) - span := spans[0] - assert.Equal(t, "/user/:id", span.Name()) - assert.Equal(t, oteltrace.SpanKindServer, span.SpanKind()) - assert.Equal(t, attribute.StringValue("foobar"), span.Attributes()["http.server_name"]) - assert.Equal(t, attribute.IntValue(http.StatusOK), span.Attributes()["http.status_code"]) - assert.Equal(t, attribute.StringValue("GET"), span.Attributes()["http.method"]) - assert.Equal(t, attribute.StringValue("/user/123"), span.Attributes()["http.target"]) - assert.Equal(t, attribute.StringValue("/user/:id"), span.Attributes()["http.route"]) -} - -func TestError(t *testing.T) { - sr := new(oteltest.SpanRecorder) - provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) - - // setup - router := echo.New() - router.Use(Middleware("foobar", WithTracerProvider(provider))) - wantErr := errors.New("oh no") - // configure a handler that returns an error and 5xx status - // code - router.GET("/server_err", func(c echo.Context) error { - return wantErr - }) - r := httptest.NewRequest("GET", "/server_err", nil) - w := httptest.NewRecorder() - router.ServeHTTP(w, r) - response := w.Result() - assert.Equal(t, http.StatusInternalServerError, response.StatusCode) - - // verify the errors and status are correct - spans := sr.Completed() - require.Len(t, spans, 1) - span := spans[0] - assert.Equal(t, "/server_err", span.Name()) - assert.Equal(t, attribute.StringValue("foobar"), span.Attributes()["http.server_name"]) - assert.Equal(t, attribute.IntValue(http.StatusInternalServerError), span.Attributes()["http.status_code"]) - assert.Equal(t, attribute.StringValue("oh no"), span.Attributes()["echo.error"]) - // server errors set the status - assert.Equal(t, codes.Error, span.StatusCode()) -} - func TestErrorOnlyHandledOnce(t *testing.T) { router := echo.New() timesHandlingError := 0 @@ -164,7 +55,7 @@ func TestGetSpanNotInstrumented(t *testing.T) { router := echo.New() router.GET("/ping", func(c echo.Context) error { // Assert we don't have a span on the context. - span := oteltrace.SpanFromContext(c.Request().Context()) + span := trace.SpanFromContext(c.Request().Context()) ok := !span.SpanContext().IsValid() assert.True(t, ok) return c.String(200, "ok") @@ -177,24 +68,27 @@ func TestGetSpanNotInstrumented(t *testing.T) { } func TestPropagationWithGlobalPropagators(t *testing.T) { - sr := new(oteltest.SpanRecorder) - provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) + provider := trace.NewNoopTracerProvider() otel.SetTextMapPropagator(propagation.TraceContext{}) r := httptest.NewRequest("GET", "/user/123", nil) w := httptest.NewRecorder() - ctx, pspan := provider.Tracer(tracerName).Start(context.Background(), "test") + ctx := context.Background() + sc := trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: trace.TraceID{0x01}, + SpanID: trace.SpanID{0x01}, + }) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) + ctx, _ = provider.Tracer(tracerName).Start(ctx, "test") otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(r.Header)) router := echo.New() router.Use(Middleware("foobar", WithTracerProvider(provider))) router.GET("/user/:id", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) - mspan, ok := span.(*oteltest.Span) - require.True(t, ok) - assert.Equal(t, pspan.SpanContext().TraceID(), mspan.SpanContext().TraceID()) - assert.Equal(t, pspan.SpanContext().SpanID(), mspan.ParentSpanID()) + span := trace.SpanFromContext(c.Request().Context()) + assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) + assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) return c.NoContent(200) }) @@ -204,25 +98,28 @@ func TestPropagationWithGlobalPropagators(t *testing.T) { } func TestPropagationWithCustomPropagators(t *testing.T) { - sr := new(oteltest.SpanRecorder) - provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) + provider := trace.NewNoopTracerProvider() b3 := b3prop.New() r := httptest.NewRequest("GET", "/user/123", nil) w := httptest.NewRecorder() - ctx, pspan := provider.Tracer(tracerName).Start(context.Background(), "test") + ctx := context.Background() + sc := trace.NewSpanContext(trace.SpanContextConfig{ + TraceID: trace.TraceID{0x01}, + SpanID: trace.SpanID{0x01}, + }) + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) + ctx, _ = provider.Tracer(tracerName).Start(ctx, "test") b3.Inject(ctx, propagation.HeaderCarrier(r.Header)) router := echo.New() router.Use(Middleware("foobar", WithTracerProvider(provider), WithPropagators(b3))) router.GET("/user/:id", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) - mspan, ok := span.(*oteltest.Span) - require.True(t, ok) - assert.Equal(t, pspan.SpanContext().TraceID(), mspan.SpanContext().TraceID()) - assert.Equal(t, pspan.SpanContext().SpanID(), mspan.ParentSpanID()) + span := trace.SpanFromContext(c.Request().Context()) + assert.Equal(t, sc.TraceID(), span.SpanContext().TraceID()) + assert.Equal(t, sc.SpanID(), span.SpanContext().SpanID()) return c.NoContent(200) }) @@ -241,7 +138,7 @@ func TestSkipper(t *testing.T) { router := echo.New() router.Use(Middleware("foobar", WithSkipper(skipper))) router.GET("/ping", func(c echo.Context) error { - span := oteltrace.SpanFromContext(c.Request().Context()) + span := trace.SpanFromContext(c.Request().Context()) assert.False(t, span.SpanContext().HasSpanID()) assert.False(t, span.SpanContext().HasTraceID()) return c.NoContent(200) diff --git a/instrumentation/github.com/labstack/echo/otelecho/example/go.sum b/instrumentation/github.com/labstack/echo/otelecho/example/go.sum index 9335edd5bc7..d575703e2db 100644 --- a/instrumentation/github.com/labstack/echo/otelecho/example/go.sum +++ b/instrumentation/github.com/labstack/echo/otelecho/example/go.sum @@ -30,8 +30,6 @@ go.opentelemetry.io/otel v1.0.0-RC2 h1:SHhxSjB+omnGZPgGlKe+QMp3MyazcOHdQ8qwo89oK go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC2 h1:crksoFyTPDDywRJDUW36OZma+C3HhcYwQLPUZZMXFO0= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC2/go.mod h1:6kVxj1C/f3irP/IeeZNbcEwbg3rwnM6a7bCrcGbIJeI= -go.opentelemetry.io/otel/oteltest v1.0.0-RC2 h1:xNKqMhlZYkASSyvF4JwObZFMq0jhFN3c3SP+2rCzVPk= -go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A= go.opentelemetry.io/otel/sdk v1.0.0-RC2 h1:ROuteeSCBaZNjiT9JcFzZepmInDvLktR28Y6qKo8bCs= go.opentelemetry.io/otel/sdk v1.0.0-RC2/go.mod h1:fgwHyiDn4e5k40TD9VX243rOxXR+jzsWBZYA2P5jpEw= go.opentelemetry.io/otel/trace v1.0.0-RC2 h1:dunAP0qDULMIT82atj34m5RgvsIK6LcsXf1c/MsYg1w= diff --git a/instrumentation/github.com/labstack/echo/otelecho/go.mod b/instrumentation/github.com/labstack/echo/otelecho/go.mod index 837504302f9..0c63c61852b 100644 --- a/instrumentation/github.com/labstack/echo/otelecho/go.mod +++ b/instrumentation/github.com/labstack/echo/otelecho/go.mod @@ -13,6 +13,5 @@ require ( go.opentelemetry.io/contrib v0.22.0 go.opentelemetry.io/contrib/propagators/b3 v0.22.0 go.opentelemetry.io/otel v1.0.0-RC2 - go.opentelemetry.io/otel/oteltest v1.0.0-RC2 go.opentelemetry.io/otel/trace v1.0.0-RC2 ) diff --git a/instrumentation/github.com/labstack/echo/otelecho/go.sum b/instrumentation/github.com/labstack/echo/otelecho/go.sum index 145d95e7ded..22f12f2e87b 100644 --- a/instrumentation/github.com/labstack/echo/otelecho/go.sum +++ b/instrumentation/github.com/labstack/echo/otelecho/go.sum @@ -28,8 +28,6 @@ github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52 github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= go.opentelemetry.io/otel v1.0.0-RC2 h1:SHhxSjB+omnGZPgGlKe+QMp3MyazcOHdQ8qwo89oKbg= go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= -go.opentelemetry.io/otel/oteltest v1.0.0-RC2 h1:xNKqMhlZYkASSyvF4JwObZFMq0jhFN3c3SP+2rCzVPk= -go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A= go.opentelemetry.io/otel/trace v1.0.0-RC2 h1:dunAP0qDULMIT82atj34m5RgvsIK6LcsXf1c/MsYg1w= go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= diff --git a/instrumentation/github.com/labstack/echo/otelecho/test/doc.go b/instrumentation/github.com/labstack/echo/otelecho/test/doc.go new file mode 100644 index 00000000000..6799fac12c2 --- /dev/null +++ b/instrumentation/github.com/labstack/echo/otelecho/test/doc.go @@ -0,0 +1,22 @@ +// 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 test validates the otelecho instrumentation with the default SDK. + +This package is in a separate module from the instrumentation it tests to +isolate the dependency of the default SDK and not impose this as a transitive +dependency for users. +*/ +package test diff --git a/instrumentation/github.com/labstack/echo/otelecho/test/echo_test.go b/instrumentation/github.com/labstack/echo/otelecho/test/echo_test.go new file mode 100644 index 00000000000..489647e2a81 --- /dev/null +++ b/instrumentation/github.com/labstack/echo/otelecho/test/echo_test.go @@ -0,0 +1,140 @@ +// 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. + +// Based on https://github.com/DataDog/dd-trace-go/blob/8fb554ff7cf694267f9077ae35e27ce4689ed8b6/contrib/gin-gonic/gin/gintrace_test.go + +package test + +import ( + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/labstack/echo/v4" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" + + "go.opentelemetry.io/otel/attribute" + oteltrace "go.opentelemetry.io/otel/trace" +) + +func TestChildSpanFromGlobalTracer(t *testing.T) { + sr := tracetest.NewSpanRecorder() + provider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) + otel.SetTracerProvider(provider) + + router := echo.New() + router.Use(otelecho.Middleware("foobar")) + router.GET("/user/:id", func(c echo.Context) error { + return c.NoContent(200) + }) + + r := httptest.NewRequest("GET", "/user/123", nil) + w := httptest.NewRecorder() + + router.ServeHTTP(w, r) + assert.Equal(t, http.StatusOK, w.Result().StatusCode, "should call the 'user' handler") + assert.Len(t, sr.Ended(), 1) +} + +func TestChildSpanFromCustomTracer(t *testing.T) { + sr := tracetest.NewSpanRecorder() + provider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) + + router := echo.New() + router.Use(otelecho.Middleware("foobar", otelecho.WithTracerProvider(provider))) + router.GET("/user/:id", func(c echo.Context) error { + return c.NoContent(200) + }) + + r := httptest.NewRequest("GET", "/user/123", nil) + w := httptest.NewRecorder() + + router.ServeHTTP(w, r) + assert.Equal(t, http.StatusOK, w.Result().StatusCode, "should call the 'user' handler") + assert.Len(t, sr.Ended(), 1) +} + +func TestTrace200(t *testing.T) { + sr := tracetest.NewSpanRecorder() + provider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) + + router := echo.New() + router.Use(otelecho.Middleware("foobar", otelecho.WithTracerProvider(provider))) + router.GET("/user/:id", func(c echo.Context) error { + id := c.Param("id") + return c.String(200, id) + }) + + r := httptest.NewRequest("GET", "/user/123", nil) + w := httptest.NewRecorder() + + // do and verify the request + router.ServeHTTP(w, r) + response := w.Result() + require.Equal(t, http.StatusOK, response.StatusCode) + + // verify traces look good + spans := sr.Ended() + require.Len(t, spans, 1) + span := spans[0] + assert.Equal(t, "/user/:id", span.Name()) + assert.Equal(t, oteltrace.SpanKindServer, span.SpanKind()) + attrs := span.Attributes() + assert.Contains(t, attrs, attribute.String("http.server_name", "foobar")) + assert.Contains(t, attrs, attribute.Int("http.status_code", http.StatusOK)) + assert.Contains(t, attrs, attribute.String("http.method", "GET")) + assert.Contains(t, attrs, attribute.String("http.target", "/user/123")) + assert.Contains(t, attrs, attribute.String("http.route", "/user/:id")) +} + +func TestError(t *testing.T) { + sr := tracetest.NewSpanRecorder() + provider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) + + // setup + router := echo.New() + router.Use(otelecho.Middleware("foobar", otelecho.WithTracerProvider(provider))) + wantErr := errors.New("oh no") + // configure a handler that returns an error and 5xx status + // code + router.GET("/server_err", func(c echo.Context) error { + return wantErr + }) + r := httptest.NewRequest("GET", "/server_err", nil) + w := httptest.NewRecorder() + router.ServeHTTP(w, r) + response := w.Result() + assert.Equal(t, http.StatusInternalServerError, response.StatusCode) + + // verify the errors and status are correct + spans := sr.Ended() + require.Len(t, spans, 1) + span := spans[0] + assert.Equal(t, "/server_err", span.Name()) + attrs := span.Attributes() + assert.Contains(t, attrs, attribute.String("http.server_name", "foobar")) + assert.Contains(t, attrs, attribute.Int("http.status_code", http.StatusInternalServerError)) + assert.Contains(t, attrs, attribute.String("echo.error", "oh no")) + // server errors set the status + assert.Equal(t, codes.Error, span.Status().Code) +} diff --git a/instrumentation/github.com/labstack/echo/otelecho/test/go.mod b/instrumentation/github.com/labstack/echo/otelecho/test/go.mod new file mode 100644 index 00000000000..8d61972d6ac --- /dev/null +++ b/instrumentation/github.com/labstack/echo/otelecho/test/go.mod @@ -0,0 +1,16 @@ +module go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho/test + +go 1.15 + +require ( + github.com/labstack/echo/v4 v4.5.0 + github.com/stretchr/testify v1.7.0 + go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.22.0 + go.opentelemetry.io/otel v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b + go.opentelemetry.io/otel/sdk v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b + go.opentelemetry.io/otel/trace v1.0.0-RC2 +) + +replace go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho => ../ + +replace go.opentelemetry.io/contrib/propagators/b3 => ../../../../../../propagators/b3 diff --git a/instrumentation/github.com/labstack/echo/otelecho/test/go.sum b/instrumentation/github.com/labstack/echo/otelecho/test/go.sum new file mode 100644 index 00000000000..1a489e54e75 --- /dev/null +++ b/instrumentation/github.com/labstack/echo/otelecho/test/go.sum @@ -0,0 +1,65 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/labstack/echo/v4 v4.5.0 h1:JXk6H5PAw9I3GwizqUHhYyS4f45iyGebR/c1xNCeOCY= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +go.opentelemetry.io/contrib v0.22.0 h1:0F7gDEjgb1WGn4ODIjaCAg75hmqF+UN0LiVgwxsCodc= +go.opentelemetry.io/contrib v0.22.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM= +go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= +go.opentelemetry.io/otel v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b h1:mVdpWpFdeOeGPCpwO95rocgtrkE12gZhDU4LA9K9TNE= +go.opentelemetry.io/otel v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b/go.mod h1:WrhiZahmIBdsXGO6mYjS6eW6kZzI/9GfGHFpRi8X/Yg= +go.opentelemetry.io/otel/sdk v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b h1:3L//VzNirHuL0jZSmHFeQOIdGvNmSsfnl4g9UV6ZRcI= +go.opentelemetry.io/otel/sdk v1.0.0-RC2.0.20210812161231-a8bb0bf89f3b/go.mod h1:RiCEArosW4fWBJshjrl1H4IAzoRwI0sIqfqac5ramT8= +go.opentelemetry.io/otel/trace v1.0.0-RC2 h1:dunAP0qDULMIT82atj34m5RgvsIK6LcsXf1c/MsYg1w= +go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=