Skip to content

Commit

Permalink
feat: global tags (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
greywolve committed Sep 26, 2023
1 parent 8bf9a15 commit 68e2c0f
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
3 changes: 3 additions & 0 deletions client.go
Expand Up @@ -224,6 +224,8 @@ type ClientOptions struct {
// is not optimized for long chains either. The top-level error together with a
// stack trace is often the most useful information.
MaxErrorDepth int
// Default event tags. These are overridden by tags set on a scope.
Tags map[string]string
}

// Client is the underlying processor that is used by the main API and Hub
Expand Down Expand Up @@ -375,6 +377,7 @@ func (client *Client) setupIntegrations() {
new(modulesIntegration),
new(ignoreErrorsIntegration),
new(ignoreTransactionsIntegration),
new(globalTagsIntegration),
}

if client.options.Integrations != nil {
Expand Down
64 changes: 64 additions & 0 deletions integrations.go
Expand Up @@ -2,6 +2,7 @@ package sentry

import (
"fmt"
"os"
"regexp"
"runtime"
"runtime/debug"
Expand Down Expand Up @@ -325,3 +326,66 @@ func (cfi *contextifyFramesIntegration) addContextLinesToFrame(frame Frame, line
}
return frame
}

// ================================
// Global Tags Integration
// ================================

const envTagsPrefix = "SENTRY_TAGS_"

type globalTagsIntegration struct {
tags map[string]string
envTags map[string]string
}

func (ti *globalTagsIntegration) Name() string {
return "GlobalTags"
}

func (ti *globalTagsIntegration) SetupOnce(client *Client) {
ti.tags = make(map[string]string, len(client.options.Tags))
for k, v := range client.options.Tags {
ti.tags[k] = v
}

ti.envTags = loadEnvTags()

client.AddEventProcessor(ti.processor)
}

func (ti *globalTagsIntegration) processor(event *Event, hint *EventHint) *Event {
if len(ti.tags) == 0 && len(ti.envTags) == 0 {
return event
}

if event.Tags == nil {
event.Tags = make(map[string]string, len(ti.tags)+len(ti.envTags))
}

for k, v := range ti.tags {
if _, ok := event.Tags[k]; !ok {
event.Tags[k] = v
}
}

for k, v := range ti.envTags {
if _, ok := event.Tags[k]; !ok {
event.Tags[k] = v
}
}

return event
}

func loadEnvTags() map[string]string {
tags := map[string]string{}
for _, pair := range os.Environ() {
parts := strings.Split(pair, "=")
if !strings.HasPrefix(parts[0], envTagsPrefix) {
continue
}
tag := strings.TrimPrefix(parts[0], envTagsPrefix)
tags[tag] = parts[1]
}
return tags
}
48 changes: 48 additions & 0 deletions integrations_test.go
Expand Up @@ -2,6 +2,7 @@ package sentry

import (
"encoding/json"
"os"
"path/filepath"
"regexp"
"runtime/debug"
Expand Down Expand Up @@ -421,3 +422,50 @@ func TestEnvironmentIntegrationDoesNotOverrideExistingContexts(t *testing.T) {
t.Errorf(`contexts["custom"]["key"] = %#v, want "value"`, contexts["custom"]["key"])
}
}

func TestGlobalTagsIntegration(t *testing.T) {
os.Setenv("SENTRY_TAGS_foo", "foo_value_env")
os.Setenv("SENTRY_TAGS_bar", "bar_value_env")
os.Setenv("SENTRY_TAGS_baz", "baz_value_env")
defer os.Unsetenv("SENTRY_TAGS_foo")
defer os.Unsetenv("SENTRY_TAGS_bar")
defer os.Unsetenv("SENTRY_TAGS_baz")

transport := &TransportMock{}
client, err := NewClient(ClientOptions{
Transport: transport,
Tags: map[string]string{
"foo": "foo_value_client_options",
"baz": "baz_value_client_options",
},
Integrations: func([]Integration) []Integration {
return []Integration{new(globalTagsIntegration)}
},
})
if err != nil {
t.Fatal(err)
}

scope := NewScope()
scope.SetTags(map[string]string{"foo": "foo_value_scope"})

event := NewEvent()
event.Message = "event message"
client.CaptureEvent(event, nil, scope)

assertEqual(t,
transport.lastEvent.Tags["foo"],
"foo_value_scope",
"scope tag should override any global tag",
)
assertEqual(t,
transport.lastEvent.Tags["bar"],
"bar_value_env",
"env tag present if not overridden by scope or client options tags",
)
assertEqual(t,
transport.lastEvent.Tags["baz"],
"baz_value_client_options",
"client options tag present if not overridden by scope and overrides env tag",
)
}

0 comments on commit 68e2c0f

Please sign in to comment.