Skip to content

Commit

Permalink
Merge pull request #633 from emanuelef/add-skip-urls
Browse files Browse the repository at this point in the history
OtelFiber: Add Next config setting
  • Loading branch information
ReneWerner87 authored Jun 26, 2023
2 parents 65154d1 + 2755c52 commit 9cc7ba7
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 5 deletions.
97 changes: 96 additions & 1 deletion otelfiber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,6 +24,102 @@ 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)

### 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"
}
```
10 changes: 10 additions & 0 deletions otelfiber/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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
Expand All @@ -28,6 +29,14 @@ 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
})
}

// WithPropagators specifies propagators to use for extracting
// information from the HTTP requests. If none are specified, global
// ones will be used.
Expand Down Expand Up @@ -77,3 +86,4 @@ func WithPort(port int) Option {
cfg.Port = &port
})
}

8 changes: 4 additions & 4 deletions otelfiber/example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
6 changes: 6 additions & 0 deletions otelfiber/example/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand All @@ -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=
Expand All @@ -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=
Expand Down
5 changes: 5 additions & 0 deletions otelfiber/fiber.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func Middleware(opts ...Option) fiber.Handler {
}

return func(c *fiber.Ctx) error {
// Don't execute middleware if Next returns true
if cfg.Next != nil && cfg.Next(c) {
return c.Next()
}

c.Locals(tracerKey, tracer)
savedCtx, cancel := context.WithCancel(c.UserContext())

Expand Down
21 changes: 21 additions & 0 deletions otelfiber/fiber_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ func TestChildSpanFromCustomTracer(t *testing.T) {
assert.True(t, ok)
}

func TestSkipWithNext(t *testing.T) {
otel.SetTracerProvider(oteltest.NewTracerProvider())

var gotSpan oteltrace.Span

app := fiber.New()
app.Use(Middleware(WithNext(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)
})

_, _ = 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))
Expand Down

0 comments on commit 9cc7ba7

Please sign in to comment.