diff --git a/docs/platforms/go/common/enriching-events/scopes/index.mdx b/docs/platforms/go/common/enriching-events/scopes/index.mdx
index a307f4d3df0f11..8177327079e5f3 100644
--- a/docs/platforms/go/common/enriching-events/scopes/index.mdx
+++ b/docs/platforms/go/common/enriching-events/scopes/index.mdx
@@ -72,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 3c1cccc4789f7a..b9c59f5605160b 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,44 +55,29 @@ 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)
})
-// 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")
-// Error level is sent as an error event to Sentry
+// Sending an error level log to Sentry.
logger.Errorf("oh no!")
-
-// Fatal level is sent as an error event to Sentry and terminates the application
+// Fatal also sends an error level log to Sentry, while also terminating the current process.
logger.Fatalf("can't continue...")
```
@@ -102,6 +88,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 +101,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 +120,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 f0192cfe949fd8..4a1e9ab3ea8dcb 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 ed8de056209add..3cce44cfd83126 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 d608ce19e5fe56..8c391ad5f293f7 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 c25eeb67832796..8b7ae47d14d16b 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 f804594e6d7c04..f5af8062fbb253 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 228e9376e20e7f..e43e47e35965e9 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 00000000000000..c304fad4692b7e
--- /dev/null
+++ b/docs/platforms/go/guides/fiberv3/index.mdx
@@ -0,0 +1,148 @@
+---
+title: Fiber v3
+description: "Learn how to add Sentry instrumentation to programs using Fiber v3."
+---
+
+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
+
+```bash
+go get github.com/getsentry/sentry-go
+go get github.com/getsentry/sentry-go/fiberv3
+```
+
+
+
+## Configure
+
+### Initialize the Sentry SDK
+
+
+
+### Options
+
+`sentryfiberv3` accepts a struct of `Options` that allows you to configure how the handler behaves.
+
+```go
+// 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
+```
+
+
+
+```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(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)
+}
+```
+
+## Usage
+
+`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.
+
+
+
+**Keep in mind that `*sentry.Hub` won't be available in middleware attached before `sentryfiberv3`!**
+
+```go
+func enhanceSentryEvent(ctx fiber.Ctx) error {
+ if hub := sentryfiberv3.GetHubFromContext(ctx); hub != nil {
+ hub.Scope().SetTag("someRandomTag", "maybeYouNeedIt")
+ }
+ 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)
+}
+```
+
+### Accessing Context in `BeforeSend` callback
+
+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{
+ 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 {
+ fmt.Println(ctx.Hostname())
+ }
+ }
+ return event
+ },
+})
+```
+
+## Next Steps
+
+- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup
diff --git a/docs/platforms/go/guides/gin/index.mdx b/docs/platforms/go/guides/gin/index.mdx
index 208deb95052575..84b01135a1f1ff 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 b66cfe7817158d..c0f437a62aecac 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 57a9dfdfb6c8fe..dbee2a6919710c 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 a2a02292415158..ff63ce5770f560 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 1709e9b4785b60..969f30a01b8afb 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"))
})
```