Skip to content

Commit

Permalink
Fix Sentry Hook Global Scope
Browse files Browse the repository at this point in the history
that led to errors being duplicated in following events sharing the same scope.

Now, every event gets its own local scope.
  • Loading branch information
mpass99 authored and MrSerth committed Aug 15, 2024
1 parent f3265b7 commit 06deab0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 22 deletions.
2 changes: 1 addition & 1 deletion pkg/logging/context_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// ContextHook logs the values referenced by the of dto.LoggedContextKeys.
// By default Logrus does not log the values stored in the passed context.
// By default, Logrus does not log the values stored in the passed context.
type ContextHook struct{}

// Fire is triggered on new log entries.
Expand Down
20 changes: 20 additions & 0 deletions pkg/logging/logging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http/httptest"
"testing"

"github.com/getsentry/sentry-go"
"github.com/openHPI/poseidon/pkg/dto"
"github.com/openHPI/poseidon/tests"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -41,3 +42,22 @@ func (s *MainTestSuite) TestHTTPMiddlewareDebugsWhenStatusOK() {
s.Len(hook.Entries, 1)
s.Equal(logrus.DebugLevel, hook.LastEntry().Level)
}

func (s *MainTestSuite) TestSentryHookDoesNotModifyGlobalScope() {
client, err := sentry.NewClient(sentry.ClientOptions{AttachStacktrace: false})
s.Require().NoError(err)
sentry.CurrentHub().BindClient(client)
InitializeLogging(logrus.DebugLevel.String(), dto.FormatterText)

event := client.EventFromMessage("TestEvent", sentry.LevelError)
event = sentry.CurrentHub().Scope().ApplyToEvent(event, nil)
_, ok := event.Contexts[SentryContextKey]
s.Require().False(ok)

log.WithField(dto.KeyRunnerID, tests.DefaultRunnerID).Warn("Test")

event = client.EventFromMessage("TestEvent", sentry.LevelError)
event = sentry.CurrentHub().Scope().ApplyToEvent(event, nil)
_, ok = event.Contexts[SentryContextKey]
s.Require().False(ok)
}
48 changes: 27 additions & 21 deletions pkg/logging/sentry_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
// Consider replacing this with a more feature rich, additional dependency: https://github.com/evalphobia/logrus_sentry
type SentryHook struct{}

const SentryContextKey = "Poseidon Details"

var ErrHubInvalid = errors.New("the hub is invalid")

// Fire is triggered on new log entries.
func (hook *SentryHook) Fire(entry *logrus.Entry) error {
func (hook *SentryHook) Fire(entry *logrus.Entry) (err error) {
var hub *sentry.Hub
if entry.Context != nil {
hub = sentry.GetHubFromContext(entry.Context)
Expand All @@ -25,29 +27,33 @@ func (hook *SentryHook) Fire(entry *logrus.Entry) error {
if hub == nil {
hub = sentry.CurrentHub()
}
client, scope := hub.Client(), hub.Scope()
if client == nil || scope == nil {
return ErrHubInvalid
}

scope.SetContext("Poseidon Details", entry.Data)
if runnerID, ok := entry.Data[dto.KeyRunnerID].(string); ok {
scope.SetTag(dto.KeyRunnerID, runnerID)
}
if environmentID, ok := entry.Data[dto.KeyEnvironmentID].(string); ok {
scope.SetTag(dto.KeyEnvironmentID, environmentID)
}
hub.WithScope(func(scope *sentry.Scope) {
client := hub.Client()
if client == nil || scope == nil {
err = ErrHubInvalid
return
}

event := client.EventFromMessage(entry.Message, sentry.Level(entry.Level.String()))
event.Timestamp = entry.Time
if data, ok := entry.Data["error"]; ok {
err, ok := data.(error)
if ok {
entry.Data["error"] = err.Error()
scope.SetContext(SentryContextKey, entry.Data)
if runnerID, ok := entry.Data[dto.KeyRunnerID].(string); ok {
scope.SetTag(dto.KeyRunnerID, runnerID)
}
}
hub.CaptureEvent(event)
return nil
if environmentID, ok := entry.Data[dto.KeyEnvironmentID].(string); ok {
scope.SetTag(dto.KeyEnvironmentID, environmentID)
}

event := client.EventFromMessage(entry.Message, sentry.Level(entry.Level.String()))
event.Timestamp = entry.Time
if data, ok := entry.Data["error"]; ok {
entryError, ok := data.(error)
if ok {
entry.Data["error"] = entryError.Error()
}
}
hub.CaptureEvent(event)
})
return err
}

// Levels returns all levels this hook should be registered to.
Expand Down

0 comments on commit 06deab0

Please sign in to comment.