From ad94e7eff9a689e38fa7fbf6bbc7ab98ac2b55c4 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Mon, 10 Aug 2026 09:59:56 +0200 Subject: [PATCH 1/4] feat(go): align docs with v0.48.0 --- .../common/enriching-events/scopes/index.mdx | 8 ++ docs/platforms/go/common/logs/logrus.mdx | 73 +++---------------- docs/platforms/go/common/logs/slog.mdx | 20 ++--- docs/platforms/go/common/migration.mdx | 10 ++- .../instrumentation/auto-instrumentation.mdx | 3 +- docs/platforms/go/guides/echo/index.mdx | 2 +- docs/platforms/go/guides/fasthttp/index.mdx | 3 +- docs/platforms/go/guides/fiber/index.mdx | 2 +- docs/platforms/go/guides/fiberv3/index.mdx | 67 +++++++++++++++++ docs/platforms/go/guides/gin/index.mdx | 2 +- docs/platforms/go/guides/http/index.mdx | 2 +- docs/platforms/go/guides/iris/index.mdx | 2 +- docs/platforms/go/guides/negroni/index.mdx | 2 +- platform-includes/set-extra/go.mdx | 4 +- 14 files changed, 112 insertions(+), 88 deletions(-) create mode 100644 docs/platforms/go/guides/fiberv3/index.mdx diff --git a/docs/platforms/go/common/enriching-events/scopes/index.mdx b/docs/platforms/go/common/enriching-events/scopes/index.mdx index a307f4d3df0f1..0f58f5cb38a4f 100644 --- a/docs/platforms/go/common/enriching-events/scopes/index.mdx +++ b/docs/platforms/go/common/enriching-events/scopes/index.mdx @@ -39,6 +39,14 @@ then merge the event with the topmost scope's data. ## Configuring the Scope +`PushScope` returns the new scope, so you can configure a temporary scope directly: + +```go +scope := sentry.PushScope() +defer sentry.PopScope() +scope.SetTag("request.type", "background") +``` + The most useful operation when working with scopes is the function. It can be used to reconfigure the current scope. You can, for instance, add custom tags or inform Sentry about the currently authenticated user. diff --git a/docs/platforms/go/common/logs/logrus.mdx b/docs/platforms/go/common/logs/logrus.mdx index 3c1cccc4789f7..09b75e226c9d9 100644 --- a/docs/platforms/go/common/logs/logrus.mdx +++ b/docs/platforms/go/common/logs/logrus.mdx @@ -1,6 +1,6 @@ --- title: Logrus -description: "Integrate Logrus with Sentry to capture and send both logs and events." +description: "Integrate Logrus with Sentry to capture structured logs." sidebar_order: 10 --- @@ -28,12 +28,13 @@ go get github.com/getsentry/sentry-go/logrus ### Options `sentrylogrus` provides two types of hooks to configure the integration with Sentry. Both hooks accept these options: + - **Levels**: A slice of `logrus.Level` specifying which log levels to capture - **ClientOptions**: Standard `sentry.ClientOptions` for configuration ## Verify -To integrate Sentry with Logrus, you can set up both log hooks and event hooks to capture different types of data at various log levels. +To integrate Sentry with Logrus, configure the log hook with the levels you want to send as structured logs. ```go // Initialize Sentry SDK @@ -54,31 +55,17 @@ if client == nil { log.Fatalf("Sentry client is nil") } -// Create log hook to send logs on Info level +// Send selected log levels as structured logs. logHook := sentrylogrus.NewLogHookFromClient( - []logrus.Level{logrus.InfoLevel}, - client, -) - -// Create event hook to send events on Error, Fatal, Panic levels -eventHook := sentrylogrus.NewEventHookFromClient( - []logrus.Level{ - logrus.ErrorLevel, - logrus.FatalLevel, - logrus.PanicLevel, - }, + []logrus.Level{logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel}, client, ) -defer eventHook.Flush(5 * time.Second) defer logHook.Flush(5 * time.Second) -logger.AddHook(eventHook) logger.AddHook(logHook) -// Flushes before calling os.Exit(1) when using logger.Fatal -// (else all defers are not called, and Sentry does not have time to send the event) +// Flush before calling os.Exit(1) when using logger.Fatal. logrus.RegisterExitHandler(func() { - eventHook.Flush(5 * time.Second) logHook.Flush(5 * time.Second) }) @@ -88,10 +75,7 @@ logger.Infof("Application has started") // Example of logging with attributes logger.WithField("user", "test-user").Error("An error occurred") -// Error level is sent as an error event to Sentry logger.Errorf("oh no!") - -// Fatal level is sent as an error event to Sentry and terminates the application logger.Fatalf("can't continue...") ``` @@ -102,6 +86,7 @@ by using `sentrylogrus.NewLogHookFromClient()` and passing an already created `s send them to Sentry's structured logging system. #### NewLogHook + ```go logHook, err := sentrylogrus.NewLogHook( []logrus.Level{logrus.InfoLevel, logrus.WarnLevel}, @@ -114,6 +99,7 @@ logHook, err := sentrylogrus.NewLogHook( #### NewLogHookFromClient Use `NewLogHookFromClient` if you've already initialized the Sentry SDK. + ```go if err := sentry.Init(sentry.ClientOptions{ Dsn: "___PUBLIC_DSN___", @@ -132,46 +118,9 @@ if client != nil { } ``` -### EventHook - -You also have two ways to create a new `EventHook`. Either by using `sentrylogrus.NewEventHook()` and passing the `sentry.ClientOptions`, or -by using `sentrylogrus.NewEventFromClient()` and passing an already created `sentry.Client`. These hook captures log entries and -send them as events. This is helpful for error tracking and alerting. - -#### NewEventHook -```go -eventHook, err := sentrylogrus.NewEventHook( - []logrus.Level{logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel}, - sentry.ClientOptions{ - Dsn: "___PUBLIC_DSN___", - Debug: true, - AttachStacktrace: true, - }, -) -``` -#### NewEventHookFromClient - -Use `NewEventHookFromClient` if you've already initialized the Sentry SDK. -```go -if err := sentry.Init(sentry.ClientOptions{ - Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", -}); err != nil { - log.Fatalf("Sentry initialization failed: %v", err) -} -hub := sentry.CurrentHub() -client := hub.Client() -if client != nil { - eventHook := sentrylogrus.NewEventHookFromClient( - []logrus.Level{logrus.InfoLevel, logrus.WarnLevel}, - client, - ) -} else { - log.Fatalf("Sentrylogrus initialization failed: nil client") -} -``` - - When using both hooks, ensure you flush both of them before the application exits and register exit handlers for fatal logs to avoid losing pending events. + Logrus sends records as structured logs. To capture an error as an issue, call + `sentry.CaptureException` or `sentry.CaptureMessage` explicitly. - + diff --git a/docs/platforms/go/common/logs/slog.mdx b/docs/platforms/go/common/logs/slog.mdx index f0192cfe949fd..4a1e9ab3ea8dc 100644 --- a/docs/platforms/go/common/logs/slog.mdx +++ b/docs/platforms/go/common/logs/slog.mdx @@ -29,19 +29,16 @@ go get github.com/getsentry/sentry-go/slog `sentryslog` accepts a `sentryslog.Option` struct to control which records are sent to Sentry and how they're enriched before sending. -| Field | Type | Description | Default | -| ----------------- | ------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| `EventLevel` | `[]slog.Level` | Log levels to capture as Sentry events | `[]slog.Level{slog.LevelError, sentryslog.LevelFatal}` | -| `LogLevel` | `[]slog.Level` | Log levels to capture as Sentry log entries | `[]slog.Level{slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError, sentryslog.LevelFatal}` | -| `Hub` | `*sentry.Hub` | Hub to use when capturing events | Current hub | -| `Converter` | `Converter` | Custom converter for turning log records into Sentry events | `sentryslog.DefaultConverter` | -| `AttrFromContext` | `[]func(context.Context) []slog.Attr` | Functions that add attributes from the current context | None | -| `AddSource` | `bool` | Include file and line information in Sentry output | `false` | -| `ReplaceAttr` | `func([]string, slog.Attr) slog.Attr` | Rewrite or filter attributes before sending | None | +| Field | Type | Description | Default | +| ----------------- | ------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| `LogLevel` | `[]slog.Level` | Log levels to capture as Sentry log entries | `[]slog.Level{slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError, sentryslog.LevelFatal}` | +| `AttrFromContext` | `[]func(context.Context) []slog.Attr` | Add attributes from the current context | None | +| `AddSource` | `bool` | Include source information in Sentry output | `false` | +| `ReplaceAttr` | `func([]string, slog.Attr) slog.Attr` | Rewrite or filter attributes before sending | None | ## Verify -This example sends `ERROR` records as events and `INFO`/`WARN` records as structured logs. +This example sends selected records as structured logs. ```go package main @@ -56,8 +53,7 @@ import ( func main() { ctx := context.Background() handler := sentryslog.Option{ - EventLevel: []slog.Level{slog.LevelError, sentryslog.LevelFatal}, - LogLevel: []slog.Level{slog.LevelInfo, slog.LevelWarn}, + LogLevel: []slog.Level{slog.LevelInfo, slog.LevelWarn, slog.LevelError}, AddSource: true, }.NewSentryHandler(ctx) diff --git a/docs/platforms/go/common/migration.mdx b/docs/platforms/go/common/migration.mdx index ed8de056209ad..3cce44cfd8312 100644 --- a/docs/platforms/go/common/migration.mdx +++ b/docs/platforms/go/common/migration.mdx @@ -25,7 +25,6 @@ go get github.com/getsentry/sentry-go raven-go - ```go import "github.com/getsentry/raven-go" @@ -71,7 +70,6 @@ SetIncludePaths() sentry-go - ```go sentry.Init(sentry.ClientOptions{ Dsn: "___PUBLIC_DSN___", @@ -91,7 +89,6 @@ Available options: see [Configuration](/platforms/go/configuration/options/) sec By default, TLS uses the host's root CA set. If you don't have `ca-certificates` (which should be your go-to way of fixing the missing certificates issue) and want to use `gocertifi` instead, you can provide pre-loaded cert files as one of the options to `sentry.Init` call: - ```go package main @@ -362,11 +359,16 @@ sentry-go ```go // use `sentry.WithScope`, see "Context / Per-event Section" +import "github.com/getsentry/sentry-go/attribute" + path := "filename.ext" f, err := os.Open(path) if err != nil { sentry.WithScope(func(scope *sentry.Scope) { - scope.SetExtras(map[string]interface{}{"path": path, "cwd": os.Getwd()}) + scope.SetAttributes( + attribute.String("path", path), + attribute.String("cwd", os.Getwd()), + ) sentry.CaptureException(err) }) } diff --git a/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx b/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx index d608ce19e5fe5..8c391ad5f293f 100644 --- a/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx +++ b/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx @@ -18,7 +18,8 @@ Sentry provides middleware for the following Go HTTP frameworks: | --------- | -------------------- | ------------------------------------------------ | | Gin | `sentry-go/gin` | [Gin guide](/platforms/go/guides/gin/) | | Echo | `sentry-go/echo` | [Echo guide](/platforms/go/guides/echo/) | -| Fiber | `sentry-go/fiber` | [Fiber guide](/platforms/go/guides/fiber/) | +| Fiber v2 | `sentry-go/fiber` | [Fiber guide](/platforms/go/guides/fiber/) | +| Fiber v3 | `sentry-go/fiberv3` | [Fiber v3 guide](/platforms/go/guides/fiberv3/) | | net/http | `sentry-go/http` | [net/http guide](/platforms/go/guides/http/) | | Iris | `sentry-go/iris` | [Iris guide](/platforms/go/guides/iris/) | | FastHTTP | `sentry-go/fasthttp` | [FastHTTP guide](/platforms/go/guides/fasthttp/) | diff --git a/docs/platforms/go/guides/echo/index.mdx b/docs/platforms/go/guides/echo/index.mdx index c25eeb6783279..8b7ae47d14d16 100644 --- a/docs/platforms/go/guides/echo/index.mdx +++ b/docs/platforms/go/guides/echo/index.mdx @@ -105,7 +105,7 @@ app.Use(func(next echo.HandlerFunc) echo.HandlerFunc { app.GET("/", func(ctx *echo.Context) error { if hub := sentryecho.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/docs/platforms/go/guides/fasthttp/index.mdx b/docs/platforms/go/guides/fasthttp/index.mdx index f804594e6d7c0..f5af8062fbb25 100644 --- a/docs/platforms/go/guides/fasthttp/index.mdx +++ b/docs/platforms/go/guides/fasthttp/index.mdx @@ -102,7 +102,7 @@ sentryHandler := sentryfasthttp.New(sentryfasthttp.Options{ defaultHandler := func(ctx *fasthttp.RequestCtx) { if hub := sentryfasthttp.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } @@ -131,7 +131,6 @@ if err := fasthttp.ListenAndServe(":3000", sentryHandler.Handle(fastHTTPHandler) ### Accessing Context in `BeforeSend` callback - ```go sentry.Init(sentry.ClientOptions{ Dsn: "___PUBLIC_DSN___", diff --git a/docs/platforms/go/guides/fiber/index.mdx b/docs/platforms/go/guides/fiber/index.mdx index 228e9376e20e7..e43e47e35965e 100644 --- a/docs/platforms/go/guides/fiber/index.mdx +++ b/docs/platforms/go/guides/fiber/index.mdx @@ -100,7 +100,7 @@ sentryHandler := sentryfiber.New(sentryfiber.Options{ defaultHandler := func(ctx *fiber.Ctx) error { if hub := sentryfiber.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/docs/platforms/go/guides/fiberv3/index.mdx b/docs/platforms/go/guides/fiberv3/index.mdx new file mode 100644 index 0000000000000..ea1f0dcfa01b4 --- /dev/null +++ b/docs/platforms/go/guides/fiberv3/index.mdx @@ -0,0 +1,67 @@ +--- +title: Fiber v3 +description: "Instrument Fiber v3 applications with Sentry." +--- + +Use the Fiber v3 middleware to capture errors and trace requests. + +## Install + +```bash +go get github.com/getsentry/sentry-go +go get github.com/getsentry/sentry-go/fiberv3 +``` + +## Configure + +Initialize Sentry before installing the middleware: + +```go +import ( + fiber "github.com/gofiber/fiber/v3" + "github.com/getsentry/sentry-go" + sentryfiber "github.com/getsentry/sentry-go/fiberv3" +) + +if err := sentry.Init(sentry.ClientOptions{Dsn: "___PUBLIC_DSN___"}); err != nil { + panic(err) +} + +app := fiber.New() +app.Use(sentryfiber.New(sentryfiber.Options{})) +``` + +Set `Repanic` to `true` if Fiber should handle recovered panics. Set `WaitForDelivery` to `true` when the application may exit before the event is sent. + +## Use The Request Hub + +The middleware adds a hub to `fiber.Ctx`. Use it instead of the global capture functions to keep request data isolated: + +```go +app.Get("/", func(ctx fiber.Ctx) error { + if hub := sentryfiber.GetHubFromContext(ctx); hub != nil { + hub.CaptureMessage("Request handled") + } + return ctx.SendStatus(fiber.StatusOK) +}) +``` + +Install the Sentry middleware before routes and any middleware that needs the request hub. + +### Access The Fiber Context In `BeforeSend` + +```go +sentry.Init(sentry.ClientOptions{ + Dsn: "___PUBLIC_DSN___", + BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event { + if hint.Context != nil { + if ctx, ok := hint.Context.Value(sentry.RequestContextKey).(fiber.Ctx); ok { + _ = ctx.Hostname() + } + } + return event + }, +}) +``` + +For Fiber v2, see the [Fiber guide](/platforms/go/guides/fiber/). diff --git a/docs/platforms/go/guides/gin/index.mdx b/docs/platforms/go/guides/gin/index.mdx index 208deb9505257..84b01135a1f1f 100644 --- a/docs/platforms/go/guides/gin/index.mdx +++ b/docs/platforms/go/guides/gin/index.mdx @@ -99,7 +99,7 @@ app.Use(func(ctx *gin.Context) { app.GET("/", func(ctx *gin.Context) { if hub := sentrygin.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/docs/platforms/go/guides/http/index.mdx b/docs/platforms/go/guides/http/index.mdx index b66cfe7817158..c0f437a62aeca 100644 --- a/docs/platforms/go/guides/http/index.mdx +++ b/docs/platforms/go/guides/http/index.mdx @@ -92,7 +92,7 @@ type handler struct{} func (h *handler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { if hub := sentry.GetHubFromContext(r.Context()); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/docs/platforms/go/guides/iris/index.mdx b/docs/platforms/go/guides/iris/index.mdx index 57a9dfdfb6c8f..dbee2a6919710 100644 --- a/docs/platforms/go/guides/iris/index.mdx +++ b/docs/platforms/go/guides/iris/index.mdx @@ -100,7 +100,7 @@ app.Use(func(ctx iris.Context) { app.Get("/", func(ctx iris.Context) { if hub := sentryiris.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/docs/platforms/go/guides/negroni/index.mdx b/docs/platforms/go/guides/negroni/index.mdx index a2a0229241515..ff63ce5770f56 100644 --- a/docs/platforms/go/guides/negroni/index.mdx +++ b/docs/platforms/go/guides/negroni/index.mdx @@ -104,7 +104,7 @@ mux := http.NewServeMux() mux.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) { hub := sentry.GetHubFromContext(r.Context()) hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) rw.WriteHeader(http.StatusOK) diff --git a/platform-includes/set-extra/go.mdx b/platform-includes/set-extra/go.mdx index 1709e9b4785b6..969f30a01b8af 100644 --- a/platform-includes/set-extra/go.mdx +++ b/platform-includes/set-extra/go.mdx @@ -1,5 +1,7 @@ ```go +import "github.com/getsentry/sentry-go/attribute" + sentry.ConfigureScope(func(scope *sentry.Scope) { - scope.SetExtra("character.name", "Mighty Fighter") + scope.SetAttributes(attribute.String("character.name", "Mighty Fighter")) }) ``` From 1d4d8013a14d329e3ca95abe5960ff7af369c4e6 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Mon, 10 Aug 2026 10:06:05 +0200 Subject: [PATCH 2/4] feat(go): align Fiber v3 page to Fiber --- docs/platforms/go/guides/fiberv3/index.mdx | 127 +++++++++++++++++---- 1 file changed, 104 insertions(+), 23 deletions(-) diff --git a/docs/platforms/go/guides/fiberv3/index.mdx b/docs/platforms/go/guides/fiberv3/index.mdx index ea1f0dcfa01b4..c304fad4692b7 100644 --- a/docs/platforms/go/guides/fiberv3/index.mdx +++ b/docs/platforms/go/guides/fiberv3/index.mdx @@ -1,9 +1,16 @@ --- title: Fiber v3 -description: "Instrument Fiber v3 applications with Sentry." +description: "Learn how to add Sentry instrumentation to programs using Fiber v3." --- -Use the Fiber v3 middleware to capture errors and trace requests. +For a quick reference, see the [Fiber v3 example](https://github.com/getsentry/sentry-go/tree/master/_examples/fiber) in the Go SDK source code repository. + +[Go Dev-style API documentation](https://pkg.go.dev/github.com/getsentry/sentry-go/fiberv3) is also available. + + + Fiber v3 uses the `github.com/getsentry/sentry-go/fiberv3` package. For Fiber + v2, use the [`sentry-go/fiber` package](/platforms/go/guides/fiber/). + ## Install @@ -12,43 +19,115 @@ go get github.com/getsentry/sentry-go go get github.com/getsentry/sentry-go/fiberv3 ``` + + ## Configure -Initialize Sentry before installing the middleware: +### Initialize the Sentry SDK + + + +### Options + +`sentryfiberv3` accepts a struct of `Options` that allows you to configure how the handler behaves. ```go -import ( - fiber "github.com/gofiber/fiber/v3" - "github.com/getsentry/sentry-go" - sentryfiber "github.com/getsentry/sentry-go/fiberv3" -) +// Repanic configures whether Sentry should repanic after recovery. Fiber v3 +// doesn't include its own Recovery handler, so set this according to how your +// application handles panics. +Repanic bool +// WaitForDelivery configures whether to block the request before continuing. +// Enable it when the application may exit before the event is delivered. +WaitForDelivery bool +// Timeout for the event delivery requests. +Timeout time.Duration +``` -if err := sentry.Init(sentry.ClientOptions{Dsn: "___PUBLIC_DSN___"}); err != nil { - panic(err) -} + + +```go +sentryHandler := sentryfiberv3.New(sentryfiberv3.Options{ + // you can modify these options + Repanic: true, + WaitForDelivery: true, + Timeout: 5 * time.Second, +}) + +app := fiber.New() +app.Use(sentryHandler) +``` +## Verify + +```go app := fiber.New() -app.Use(sentryfiber.New(sentryfiber.Options{})) + +app.Use(sentryfiberv3.New(sentryfiberv3.Options{ +// specify options here... +})) + +app.All("/", func(ctx fiber.Ctx) error { + // capturing an error intentionally to simulate usage + sentry.CaptureMessage("It works!") + + return ctx.SendStatus(fiber.StatusOK) +}) + +if err := app.Listen(":3000"); err != nil { + panic(err) +} ``` -Set `Repanic` to `true` if Fiber should handle recovered panics. Set `WaitForDelivery` to `true` when the application may exit before the event is sent. +## Usage -## Use The Request Hub +`sentryfiberv3` attaches an instance of `*sentry.Hub` to `fiber.Ctx`, which makes it available throughout the rest of the request's lifetime. +You can access it with `sentryfiberv3.GetHubFromContext()` in subsequent middleware and routes. +Use this hub instead of the global capture functions to keep data separated between requests. -The middleware adds a hub to `fiber.Ctx`. Use it instead of the global capture functions to keep request data isolated: + + +**Keep in mind that `*sentry.Hub` won't be available in middleware attached before `sentryfiberv3`!** ```go -app.Get("/", func(ctx fiber.Ctx) error { - if hub := sentryfiber.GetHubFromContext(ctx); hub != nil { - hub.CaptureMessage("Request handled") +func enhanceSentryEvent(ctx fiber.Ctx) error { + if hub := sentryfiberv3.GetHubFromContext(ctx); hub != nil { + hub.Scope().SetTag("someRandomTag", "maybeYouNeedIt") } - return ctx.SendStatus(fiber.StatusOK) + return ctx.Next() +} + +sentryHandler := sentryfiberv3.New(sentryfiberv3.Options{ + Repanic: true, + WaitForDelivery: true, }) + +defaultHandler := func(ctx fiber.Ctx) error { + if hub := sentryfiberv3.GetHubFromContext(ctx); hub != nil { + hub.WithScope(func(scope *sentry.Scope) { + scope.SetAttributes(attribute.String("unwantedQuery", "someQueryDataMaybe")) + hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") + }) + } + return ctx.SendStatus(fiber.StatusOK) +} + +fooHandler := func(ctx fiber.Ctx) error { + enhanceSentryEvent(ctx) + panic("y tho") +} + +app.Use(sentryHandler) +app.All("/foo", fooHandler) +app.All("/", defaultHandler) + +if err := app.Listen(":3000"); err != nil { + panic(err) +} ``` -Install the Sentry middleware before routes and any middleware that needs the request hub. +### Accessing Context in `BeforeSend` callback -### Access The Fiber Context In `BeforeSend` +Fiber v3 passes a `fiber.Ctx` value in the request context rather than the `*fiber.Ctx` used by Fiber v2: ```go sentry.Init(sentry.ClientOptions{ @@ -56,7 +135,7 @@ sentry.Init(sentry.ClientOptions{ BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event { if hint.Context != nil { if ctx, ok := hint.Context.Value(sentry.RequestContextKey).(fiber.Ctx); ok { - _ = ctx.Hostname() + fmt.Println(ctx.Hostname()) } } return event @@ -64,4 +143,6 @@ sentry.Init(sentry.ClientOptions{ }) ``` -For Fiber v2, see the [Fiber guide](/platforms/go/guides/fiber/). +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup From c13db53dd0febaa9c3e8d54961994443f9d3d848 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:17:56 +0200 Subject: [PATCH 3/4] fix: PushScope section and log comments --- .../common/enriching-events/scopes/index.mdx | 24 ++++++++++++------- docs/platforms/go/common/logs/logrus.mdx | 4 +++- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/platforms/go/common/enriching-events/scopes/index.mdx b/docs/platforms/go/common/enriching-events/scopes/index.mdx index 0f58f5cb38a4f..01c94b5100566 100644 --- a/docs/platforms/go/common/enriching-events/scopes/index.mdx +++ b/docs/platforms/go/common/enriching-events/scopes/index.mdx @@ -39,14 +39,6 @@ then merge the event with the topmost scope's data. ## Configuring the Scope -`PushScope` returns the new scope, so you can configure a temporary scope directly: - -```go -scope := sentry.PushScope() -defer sentry.PopScope() -scope.SetTag("request.type", "background") -``` - The most useful operation when working with scopes is the function. It can be used to reconfigure the current scope. You can, for instance, add custom tags or inform Sentry about the currently authenticated user. @@ -80,6 +72,22 @@ made will stay isolated within the call more easily isolate pieces of context information to specific locations in your code or even call to briefly remove all context information. +### Using + + and both modify the active scope, but they differ in how long the change lasts: + +- updates the current scope and keeps the change until you unset it or clear the scope. +- adds a child scope. Call to restore the previous scope, usually with `defer`. +- clones the current scope for a callback and restores it automatically when the callback returns. + +In Go, returns the new scope so you can configure it directly: + +```go +scope := sentry.PushScope() +defer sentry.PopScope() +scope.SetTag("request.type", "background") +``` + ## Setting Attributes You can set typed attributes on the scope using `SetAttributes`. These attributes are attached to logs and metrics emitted within the scope. Attributes use the `attribute` package for type safety. diff --git a/docs/platforms/go/common/logs/logrus.mdx b/docs/platforms/go/common/logs/logrus.mdx index 09b75e226c9d9..b9c59f5605160 100644 --- a/docs/platforms/go/common/logs/logrus.mdx +++ b/docs/platforms/go/common/logs/logrus.mdx @@ -69,13 +69,15 @@ logrus.RegisterExitHandler(func() { logHook.Flush(5 * time.Second) }) -// Info level is sent as a log to Sentry +// Sending an info level log to Sentry. logger.Infof("Application has started") // Example of logging with attributes logger.WithField("user", "test-user").Error("An error occurred") +// Sending an error level log to Sentry. logger.Errorf("oh no!") +// Fatal also sends an error level log to Sentry, while also terminating the current process. logger.Fatalf("can't continue...") ``` From 28a16f40e9127769ff4e48d25e43c4f64fa0fb31 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Mon, 10 Aug 2026 13:27:14 +0200 Subject: [PATCH 4/4] fix: close PlatformIdentifier --- docs/platforms/go/common/enriching-events/scopes/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/go/common/enriching-events/scopes/index.mdx b/docs/platforms/go/common/enriching-events/scopes/index.mdx index 01c94b5100566..8177327079e5f 100644 --- a/docs/platforms/go/common/enriching-events/scopes/index.mdx +++ b/docs/platforms/go/common/enriching-events/scopes/index.mdx @@ -72,7 +72,7 @@ made will stay isolated within the call more easily isolate pieces of context information to specific locations in your code or even call to briefly remove all context information. -### Using +### Using and both modify the active scope, but they differ in how long the change lasts: