From 8ef4e3b6983e42f8c04b1f8946f2df0f5538a072 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Mon, 5 Jun 2023 13:42:39 +0100 Subject: [PATCH 01/11] Skip URIs --- otelfiber/config.go | 1 + otelfiber/fiber.go | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/otelfiber/config.go b/otelfiber/config.go index a67aaa92..7dd975e2 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -15,6 +15,7 @@ type config struct { Propagators propagation.TextMapPropagator ServerName *string SpanNameFormatter func(*fiber.Ctx) string + SkipURIs []string } // Option specifies instrumentation configuration options. diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index 76bd730d..33f07f42 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -79,6 +79,16 @@ func Middleware(opts ...Option) fiber.Handler { } return func(c *fiber.Ctx) error { + skipURIs := make(map[string]struct{}) + for _, uri := range cfg.SkipURIs { + skipURIs[uri] = struct{}{} + } + + // skip uri + if _, ok := skipURIs[c.Path()]; ok { + return c.Next() + } + c.Locals(tracerKey, tracer) savedCtx, cancel := context.WithCancel(c.UserContext()) From f03a545a92d768f5c37597f21811d5f441893d05 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Mon, 5 Jun 2023 14:04:08 +0100 Subject: [PATCH 02/11] Add ski uris to config --- otelfiber/config.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/otelfiber/config.go b/otelfiber/config.go index 7dd975e2..f2dc0df5 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -78,3 +78,9 @@ func WithPort(port int) Option { cfg.Port = &port }) } + +func WithSkipURIs(uris []string) Option { + return optionFunc(func(cfg *config) { + cfg.SkipURIs = uris + }) +} From 449a6c9f958f7116e104ca4e26af6e2d41cbf174 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Mon, 5 Jun 2023 15:23:47 +0100 Subject: [PATCH 03/11] Added test --- otelfiber/fiber_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/otelfiber/fiber_test.go b/otelfiber/fiber_test.go index 62b6c822..3983b788 100644 --- a/otelfiber/fiber_test.go +++ b/otelfiber/fiber_test.go @@ -61,6 +61,24 @@ func TestChildSpanFromCustomTracer(t *testing.T) { assert.True(t, ok) } +func TestSkipURIs(t *testing.T) { + otel.SetTracerProvider(oteltest.NewTracerProvider()) + + var gotSpan oteltrace.Span + + app := fiber.New() + app.Use(Middleware(WithSkipURIs([]string{"/health"}))) + app.Get("/health", func(ctx *fiber.Ctx) error { + gotSpan = oteltrace.SpanFromContext(ctx.UserContext()) + return ctx.SendStatus(http.StatusNoContent) + }) + + _, _ = app.Test(httptest.NewRequest("GET", "/health", nil)) + + _, ok := gotSpan.(*oteltest.Span) + assert.False(t, ok) +} + func TestTrace200(t *testing.T) { sr := new(oteltest.SpanRecorder) provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)) From 46722250e557b1f75f4ca8bec8a8789a78a6c25e Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Mon, 5 Jun 2023 15:34:24 +0100 Subject: [PATCH 04/11] added comment --- otelfiber/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/otelfiber/config.go b/otelfiber/config.go index f2dc0df5..d4b977ba 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -79,6 +79,7 @@ func WithPort(port int) Option { }) } +// WithSkipURIs specifies the uris to exclude func WithSkipURIs(uris []string) Option { return optionFunc(func(cfg *config) { cfg.SkipURIs = uris From e5f41e22b05866f26e41501dcc2634122968d847 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Tue, 6 Jun 2023 07:39:52 +0100 Subject: [PATCH 05/11] Added check --- otelfiber/fiber.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index 33f07f42..93ec26a6 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -79,14 +79,17 @@ func Middleware(opts ...Option) fiber.Handler { } return func(c *fiber.Ctx) error { - skipURIs := make(map[string]struct{}) - for _, uri := range cfg.SkipURIs { - skipURIs[uri] = struct{}{} - } - // skip uri - if _, ok := skipURIs[c.Path()]; ok { - return c.Next() + if len(cfg.SkipURIs > 0) { + skipURIs := make(map[string]struct{}) + for _, uri := range cfg.SkipURIs { + skipURIs[uri] = struct{}{} + } + + // skip uri + if _, ok := skipURIs[c.Path()]; ok { + return c.Next() + } } c.Locals(tracerKey, tracer) From a512e244c8661e95e356932c134ae118a3262ada Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Tue, 6 Jun 2023 07:41:16 +0100 Subject: [PATCH 06/11] fix new line --- otelfiber/fiber.go | 1 - 1 file changed, 1 deletion(-) diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index 93ec26a6..81e87e24 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -79,7 +79,6 @@ func Middleware(opts ...Option) fiber.Handler { } return func(c *fiber.Ctx) error { - if len(cfg.SkipURIs > 0) { skipURIs := make(map[string]struct{}) for _, uri := range cfg.SkipURIs { From bf8e0c4b1cf9461a0ffcd6d596cd74ed750b3872 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Tue, 6 Jun 2023 08:01:25 +0100 Subject: [PATCH 07/11] fix check --- otelfiber/fiber.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index 81e87e24..872a6f79 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -79,7 +79,7 @@ func Middleware(opts ...Option) fiber.Handler { } return func(c *fiber.Ctx) error { - if len(cfg.SkipURIs > 0) { + if len(cfg.SkipURIs) > 0 { skipURIs := make(map[string]struct{}) for _, uri := range cfg.SkipURIs { skipURIs[uri] = struct{}{} From 64a3fd17d9a3e615f08ada811f0e3f3b269a4de6 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Fri, 16 Jun 2023 09:54:29 +0100 Subject: [PATCH 08/11] Add Next to skip --- otelfiber/config.go | 14 +++++++------- otelfiber/fiber.go | 13 +++---------- otelfiber/fiber_test.go | 7 +++++-- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/otelfiber/config.go b/otelfiber/config.go index d4b977ba..ac0cb574 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -9,13 +9,13 @@ import ( // config is used to configure the Fiber middleware. type config struct { + Next func(*fiber.Ctx) bool TracerProvider oteltrace.TracerProvider MeterProvider otelmetric.MeterProvider Port *int Propagators propagation.TextMapPropagator ServerName *string SpanNameFormatter func(*fiber.Ctx) string - SkipURIs []string } // Option specifies instrumentation configuration options. @@ -29,6 +29,12 @@ func (o optionFunc) apply(c *config) { o(c) } +func Next(f func(ctx *fiber.Ctx) bool) Option { + return optionFunc(func(cfg *config) { + cfg.Next = f + }) +} + // WithPropagators specifies propagators to use for extracting // information from the HTTP requests. If none are specified, global // ones will be used. @@ -79,9 +85,3 @@ func WithPort(port int) Option { }) } -// WithSkipURIs specifies the uris to exclude -func WithSkipURIs(uris []string) Option { - return optionFunc(func(cfg *config) { - cfg.SkipURIs = uris - }) -} diff --git a/otelfiber/fiber.go b/otelfiber/fiber.go index 872a6f79..13ec1c46 100644 --- a/otelfiber/fiber.go +++ b/otelfiber/fiber.go @@ -79,16 +79,9 @@ func Middleware(opts ...Option) fiber.Handler { } return func(c *fiber.Ctx) error { - if len(cfg.SkipURIs) > 0 { - skipURIs := make(map[string]struct{}) - for _, uri := range cfg.SkipURIs { - skipURIs[uri] = struct{}{} - } - - // skip uri - if _, ok := skipURIs[c.Path()]; ok { - return c.Next() - } + // Don't execute middleware if Next returns true + if cfg.Next != nil && cfg.Next(c) { + return c.Next() } c.Locals(tracerKey, tracer) diff --git a/otelfiber/fiber_test.go b/otelfiber/fiber_test.go index 3983b788..587ffa03 100644 --- a/otelfiber/fiber_test.go +++ b/otelfiber/fiber_test.go @@ -61,13 +61,16 @@ func TestChildSpanFromCustomTracer(t *testing.T) { assert.True(t, ok) } -func TestSkipURIs(t *testing.T) { +func TestSkipWithNext(t *testing.T) { otel.SetTracerProvider(oteltest.NewTracerProvider()) var gotSpan oteltrace.Span app := fiber.New() - app.Use(Middleware(WithSkipURIs([]string{"/health"}))) + app.Use(Middleware(Next(func(c *fiber.Ctx) bool { + return c.Path() == "/health" + }))) + app.Get("/health", func(ctx *fiber.Ctx) error { gotSpan = oteltrace.SpanFromContext(ctx.UserContext()) return ctx.SendStatus(http.StatusNoContent) From b861746202608580b69aa5e23174f6e3e0859d67 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Mon, 19 Jun 2023 19:20:04 +0100 Subject: [PATCH 09/11] rename to WithNext --- otelfiber/config.go | 2 +- otelfiber/fiber_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/otelfiber/config.go b/otelfiber/config.go index ac0cb574..0d0ffa06 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -29,7 +29,7 @@ func (o optionFunc) apply(c *config) { o(c) } -func Next(f func(ctx *fiber.Ctx) bool) Option { +func WithNext(f func(ctx *fiber.Ctx) bool) Option { return optionFunc(func(cfg *config) { cfg.Next = f }) diff --git a/otelfiber/fiber_test.go b/otelfiber/fiber_test.go index 587ffa03..81994540 100644 --- a/otelfiber/fiber_test.go +++ b/otelfiber/fiber_test.go @@ -67,7 +67,7 @@ func TestSkipWithNext(t *testing.T) { var gotSpan oteltrace.Span app := fiber.New() - app.Use(Middleware(Next(func(c *fiber.Ctx) bool { + app.Use(Middleware(WithNext(func(c *fiber.Ctx) bool { return c.Path() == "/health" }))) From 3d6de8e62476f10471121a89b740ee6db23f0c56 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Sat, 24 Jun 2023 20:29:32 +0100 Subject: [PATCH 10/11] Add config documentation --- otelfiber/README.md | 14 +++++++++++++- otelfiber/config.go | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/otelfiber/README.md b/otelfiber/README.md index 2e085038..6569ad9e 100644 --- a/otelfiber/README.md +++ b/otelfiber/README.md @@ -8,7 +8,6 @@ [OpenTelemetry](https://opentelemetry.io/) support for Fiber. - Can be found on [OpenTelemetry Registry](https://opentelemetry.io/registry/instrumentation-go-fiber/). ### Install @@ -25,6 +24,19 @@ go get -u github.com/gofiber/contrib/otelfiber otelfiber.Middleware(opts ...Option) fiber.Handler ``` +### Config + + +| Property | Type | Description | Default | +| :------------------ | :-------------------------------- | :--------------------------------------------------------------------------------- | :-------------------------------------------------------------------- | +| Next | `func(*fiber.Ctx) bool` | Define a function to skip this middleware when returned trueRequired - Rego quer | nil | +| TracerProvider | `oteltrace.TracerProvider` | Specifies a tracer provider to use for creating a tracer | nil - the global tracer provider is used | +| MeterProvider | `otelmetric.MeterProvider` | Specifies a meter provider to use for reporting | nil - the global meter provider is used | +| Port | `*int` | Specifies the value to use when setting the `net.host.port` attribute on metrics/spans | Required: If not default (`80` for `http`, `443` for `https`) | +| Propagators | `propagation.TextMapPropagator` | Specifies propagators to use for extracting information from the HTTP requests | If none are specified, global ones will be used | +| ServerName | `*string` | specifies the value to use when setting the `http.server_name` attribute on metrics/spans | - | +| SpanNameFormatter | `func(*fiber.Ctx) string` | Takes a function that will be called on every request and the returned string will become the Span Name | default formatter returns the route pathRaw | + ### Usage Please refer to [example](./example) diff --git a/otelfiber/config.go b/otelfiber/config.go index 0d0ffa06..ef84ee2a 100644 --- a/otelfiber/config.go +++ b/otelfiber/config.go @@ -29,6 +29,8 @@ func (o optionFunc) apply(c *config) { o(c) } +// WithNext takes a function that will be called on every +// request, the middleware will be skipped if returning true func WithNext(f func(ctx *fiber.Ctx) bool) Option { return optionFunc(func(cfg *config) { cfg.Next = f From 2755c52c2030b606b165705ad568c383e6c2a2d8 Mon Sep 17 00:00:00 2001 From: Emanuele Fumagalli Date: Sat, 24 Jun 2023 21:52:14 +0100 Subject: [PATCH 11/11] adding example to README --- otelfiber/README.md | 83 ++++++++++++++++++++++++++++++++++++++++ otelfiber/example/go.mod | 8 ++-- otelfiber/example/go.sum | 6 +++ 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/otelfiber/README.md b/otelfiber/README.md index 6569ad9e..01d42d84 100644 --- a/otelfiber/README.md +++ b/otelfiber/README.md @@ -40,3 +40,86 @@ otelfiber.Middleware(opts ...Option) fiber.Handler ### Usage Please refer to [example](./example) + +### Example + + +```go +package main + +import ( + "context" + "errors" + "log" + + "go.opentelemetry.io/otel/sdk/resource" + + "github.com/gofiber/fiber/v2" + + "github.com/gofiber/contrib/otelfiber" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + + //"go.opentelemetry.io/otel/exporters/jaeger" + "go.opentelemetry.io/otel/propagation" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + oteltrace "go.opentelemetry.io/otel/trace" +) + +var tracer = otel.Tracer("fiber-server") + +func main() { + tp := initTracer() + defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) + } + }() + + app := fiber.New() + + app.Use(otelfiber.Middleware()) + + app.Get("/error", func(ctx *fiber.Ctx) error { + return errors.New("abc") + }) + + app.Get("/users/:id", func(c *fiber.Ctx) error { + id := c.Params("id") + name := getUser(c.UserContext(), id) + return c.JSON(fiber.Map{"id": id, name: name}) + }) + + log.Fatal(app.Listen(":3000")) +} + +func initTracer() *sdktrace.TracerProvider { + exporter, err := stdout.New(stdout.WithPrettyPrint()) + if err != nil { + log.Fatal(err) + } + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithBatcher(exporter), + sdktrace.WithResource( + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceNameKey.String("my-service"), + )), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + return tp +} + +func getUser(ctx context.Context, id string) string { + _, span := tracer.Start(ctx, "getUser", oteltrace.WithAttributes(attribute.String("id", id))) + defer span.End() + if id == "123" { + return "otelfiber tester" + } + return "unknown" +} +``` \ No newline at end of file diff --git a/otelfiber/example/go.mod b/otelfiber/example/go.mod index dfb2e39f..a6186a44 100644 --- a/otelfiber/example/go.mod +++ b/otelfiber/example/go.mod @@ -5,7 +5,7 @@ go 1.18 replace github.com/gofiber/contrib/otelfiber => ../ require ( - github.com/gofiber/contrib/otelfiber v0.23.0 + github.com/gofiber/contrib/otelfiber v1.0.8 github.com/gofiber/fiber/v2 v2.47.0 go.opentelemetry.io/otel v1.16.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.16.0 @@ -19,17 +19,17 @@ require ( github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/klauspost/compress v1.16.3 // indirect + github.com/klauspost/compress v1.16.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/philhofer/fwd v1.1.2 // indirect - github.com/rivo/uniseg v0.4.3 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect github.com/tinylib/msgp v1.1.8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.47.0 // indirect + github.com/valyala/fasthttp v1.48.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.opentelemetry.io/contrib v1.17.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect diff --git a/otelfiber/example/go.sum b/otelfiber/example/go.sum index c483b69a..f4256dd5 100644 --- a/otelfiber/example/go.sum +++ b/otelfiber/example/go.sum @@ -13,6 +13,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= +github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -27,6 +29,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= @@ -40,6 +44,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c= github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc= +github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=