diff --git a/_examples/echo/main.go b/_examples/echo/main.go index 77de46888..77db175f3 100644 --- a/_examples/echo/main.go +++ b/_examples/echo/main.go @@ -49,7 +49,7 @@ func main() { 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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/_examples/fasthttp/main.go b/_examples/fasthttp/main.go index 827048bb8..7dd1fb28e 100644 --- a/_examples/fasthttp/main.go +++ b/_examples/fasthttp/main.go @@ -58,7 +58,7 @@ func main() { defaultHandler := func(ctx *fasthttp.RequestCtx) { if hub := sentryfasthttp.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/_examples/feature-showcase/main.go b/_examples/feature-showcase/main.go index 42f75d264..9bd823950 100644 --- a/_examples/feature-showcase/main.go +++ b/_examples/feature-showcase/main.go @@ -47,7 +47,7 @@ func captureMessage() { func configureScope() { sentry.ConfigureScope(func(scope *sentry.Scope) { - scope.SetExtra("oristhis", "justfantasy") + scope.SetTag("oristhis", "justfantasy") scope.SetTag("isthis", "reallife") scope.SetLevel(sentry.LevelFatal) scope.SetUser(sentry.User{ @@ -80,8 +80,8 @@ func addBreadcrumbs() { func withScopeAndConfigureScope() { sentry.WithScope(func(scope *sentry.Scope) { sentry.ConfigureScope(func(scope *sentry.Scope) { - scope.SetExtras(map[string]interface{}{ - "istillcant": 42, + scope.SetTags(map[string]string{ + "istillcant": "42", "believe": "that", }) scope.SetTags(map[string]string{ diff --git a/_examples/fiber/main.go b/_examples/fiber/main.go index c2a3664f2..e98d9c879 100644 --- a/_examples/fiber/main.go +++ b/_examples/fiber/main.go @@ -50,7 +50,7 @@ func main() { app.All("/", func(ctx *fiber.Ctx) error { if hub := sentryfiber.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/_examples/gin/main.go b/_examples/gin/main.go index c08e6e81b..1a394c302 100644 --- a/_examples/gin/main.go +++ b/_examples/gin/main.go @@ -42,7 +42,7 @@ func main() { app.GET("/", func(ctx *gin.Context) { if hub := sentrygin.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/_examples/iris/main.go b/_examples/iris/main.go index c01745fcd..734ea3f69 100644 --- a/_examples/iris/main.go +++ b/_examples/iris/main.go @@ -43,7 +43,7 @@ func main() { app.Get("/", func(ctx iris.Context) { if hub := sentryiris.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/_examples/negroni/main.go b/_examples/negroni/main.go index b93967e53..7405aabac 100644 --- a/_examples/negroni/main.go +++ b/_examples/negroni/main.go @@ -44,7 +44,7 @@ func main() { 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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) rw.WriteHeader(http.StatusOK) diff --git a/_examples/recover/main.go b/_examples/recover/main.go index 5caff7e0c..1000163f5 100644 --- a/_examples/recover/main.go +++ b/_examples/recover/main.go @@ -50,7 +50,7 @@ func main() { }) sentry.ConfigureScope(func(scope *sentry.Scope) { - scope.SetExtra("oristhis", "justfantasy") + scope.SetTag("oristhis", "justfantasy") scope.SetTag("isthis", "reallife") scope.SetLevel(sentry.LevelFatal) scope.SetUser(sentry.User{ diff --git a/echo/README.md b/echo/README.md index b1be6ec3b..a03878f00 100644 --- a/echo/README.md +++ b/echo/README.md @@ -101,7 +101,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/fasthttp/README.md b/fasthttp/README.md index 5a8e3611f..aac1f0b39 100644 --- a/fasthttp/README.md +++ b/fasthttp/README.md @@ -94,7 +94,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/fiber/README.md b/fiber/README.md index a070c2398..c94456938 100644 --- a/fiber/README.md +++ b/fiber/README.md @@ -99,7 +99,7 @@ app.All("/foo", enhanceSentryEvent, func(ctx *fiber.Ctx) { app.All("/", func(ctx *fiber.Ctx) { if hub := sentryfiber.GetHubFromContext(ctx); hub != nil { hub.WithScope(func(scope *sentry.Scope) { - scope.SetExtra("unwantedQuery", "someQueryDataMaybe") + scope.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/gin/README.md b/gin/README.md index e03c79498..aa402c9c5 100644 --- a/gin/README.md +++ b/gin/README.md @@ -92,7 +92,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/http/README.md b/http/README.md index 373e539d8..62b29cfea 100644 --- a/http/README.md +++ b/http/README.md @@ -81,7 +81,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/iris/README.md b/iris/README.md index a8a4d094e..6966c3766 100644 --- a/iris/README.md +++ b/iris/README.md @@ -91,7 +91,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) } diff --git a/negroni/README.md b/negroni/README.md index bc24db1dd..31e7a4870 100644 --- a/negroni/README.md +++ b/negroni/README.md @@ -97,7 +97,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.SetTag("unwantedQuery", "someQueryDataMaybe") hub.CaptureMessage("User provided unwanted query string, but we recovered just fine") }) rw.WriteHeader(http.StatusOK) diff --git a/scope.go b/scope.go index fea4221f6..862f4c27a 100644 --- a/scope.go +++ b/scope.go @@ -223,6 +223,13 @@ func (scope *Scope) SetAttributes(attrs ...attribute.Builder) { } } +// RemoveAttribute removes an attribute from the current scope. +func (scope *Scope) RemoveAttribute(key string) { + scope.mu.Lock() + defer scope.mu.Unlock() + delete(scope.attributes, key) +} + // SetTag adds a tag to the current scope. func (scope *Scope) SetTag(key, value string) { scope.mu.Lock() @@ -276,6 +283,10 @@ func (scope *Scope) RemoveContext(key string) { } // SetExtra adds an extra to the current scope. +// +// Deprecated: Use [Scope.SetAttributes] instead, which attaches typed key-value +// pairs to logs and metrics. Note that attributes do not attach to error events; +// if you only capture errors, use [Scope.SetTag] or [Scope.SetContext] to enrich them. func (scope *Scope) SetExtra(key string, value interface{}) { scope.mu.Lock() defer scope.mu.Unlock() @@ -284,6 +295,10 @@ func (scope *Scope) SetExtra(key string, value interface{}) { } // SetExtras assigns multiple extras to the current scope. +// +// Deprecated: Use [Scope.SetAttributes] instead, which attaches typed key-value +// pairs to logs and metrics. Note that attributes do not attach to error events; +// if you only capture errors, use [Scope.SetTag] or [Scope.SetContext] to enrich them. func (scope *Scope) SetExtras(extra map[string]interface{}) { scope.mu.Lock() defer scope.mu.Unlock() @@ -294,6 +309,10 @@ func (scope *Scope) SetExtras(extra map[string]interface{}) { } // RemoveExtra removes a extra from the current scope. +// +// Deprecated: Use [Scope.RemoveAttribute] instead. Note that attributes only +// attach to logs and metrics, not error events. If you only capture errors, +// use [Scope.RemoveTag] or [Scope.RemoveContext] instead. func (scope *Scope) RemoveExtra(key string) { scope.mu.Lock() defer scope.mu.Unlock() diff --git a/scope_concurrency_test.go b/scope_concurrency_test.go index 3f2312b9b..447bad6f0 100644 --- a/scope_concurrency_test.go +++ b/scope_concurrency_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/getsentry/sentry-go" + "github.com/getsentry/sentry-go/attribute" ) func TestConcurrentScopeUsage(_ *testing.T) { @@ -51,6 +52,8 @@ func touchScope(scope *sentry.Scope, x int) { scope.SetTag("foo", "bar") scope.SetContext("foo", sentry.Context{"foo": "bar"}) scope.SetExtra("foo", "bar") + scope.SetAttributes(attribute.String("foo", "bar")) + scope.RemoveAttribute("foo") scope.SetLevel(sentry.LevelDebug) scope.SetFingerprint([]string{"foo"}) scope.AddBreadcrumb(&sentry.Breadcrumb{Message: "foo"}, 100) diff --git a/scope_test.go b/scope_test.go index 4aac17566..7df0d9791 100644 --- a/scope_test.go +++ b/scope_test.go @@ -149,6 +149,30 @@ func TestScope_SetAttributes(t *testing.T) { }, scope.attributes) } +func TestScopeRemoveAttributeOnEmptyScope(t *testing.T) { + scope := NewScope() + scope.RemoveAttribute("key.nonexistent") + + assertEqual(t, make(map[string]attribute.Value), scope.attributes) +} + +func TestScopeRemoveAttributeNotInPopulateAttrs(t *testing.T) { + scope := NewScope() + scope.SetAttributes( + attribute.String("key.one", "val1"), + attribute.String("key.two", "val2"), + ) + scope.RemoveAttribute("key.two") + + attrs := make(map[string]attribute.Value) + scope.populateAttrs(attrs) + + if _, ok := attrs["key.two"]; ok { + t.Error("removed attribute should not appear in populateAttrs output") + } + assertEqual(t, attribute.StringValue("val1"), attrs["key.one"]) +} + func TestScopeRemoveTag(t *testing.T) { scope := NewScope() scope.SetTag("a", "foo")