فهرست منبع

tidy up sentry integration

Alexander Belanger 4 سال پیش
والد
کامیت
5d06cb7db6

+ 1 - 1
api/server/shared/apierrors/alerter/alerter.go

@@ -5,5 +5,5 @@ import (
 )
 
 type Alerter interface {
-	SendAlert(ctx context.Context, err error)
+	SendAlert(ctx context.Context, err error, data map[string]interface{})
 }

+ 4 - 2
api/server/shared/apierrors/alerter/noop.go

@@ -1,7 +1,9 @@
 package alerter
 
-import "context"
+import (
+	"context"
+)
 
 type NoOpAlerter struct{}
 
-func (s NoOpAlerter) SendAlert(ctx context.Context, err error) {}
+func (s NoOpAlerter) SendAlert(ctx context.Context, err error, data map[string]interface{}) {}

+ 20 - 3
api/server/shared/apierrors/alerter/sentry.go

@@ -2,6 +2,7 @@ package alerter
 
 import (
 	"context"
+	"reflect"
 
 	"github.com/getsentry/sentry-go"
 )
@@ -10,9 +11,15 @@ type SentryAlerter struct {
 	client *sentry.Client
 }
 
+func noIntegrations(ints []sentry.Integration) []sentry.Integration {
+	return []sentry.Integration{}
+}
+
 func NewSentryAlerter(sentryDSN string) (*SentryAlerter, error) {
 	sentryClient, err := sentry.NewClient(sentry.ClientOptions{
-		Dsn: sentryDSN,
+		Dsn:              sentryDSN,
+		AttachStacktrace: true,
+		Integrations:     noIntegrations,
 	})
 
 	if err != nil {
@@ -24,6 +31,16 @@ func NewSentryAlerter(sentryDSN string) (*SentryAlerter, error) {
 	}, nil
 }
 
-func (s *SentryAlerter) SendAlert(ctx context.Context, err error) {
-	s.client.CaptureException(err, &sentry.EventHint{}, nil)
+func (s *SentryAlerter) SendAlert(ctx context.Context, err error, data map[string]interface{}) {
+	s.client.CaptureEvent(&sentry.Event{
+		Message: err.Error(),
+		Extra:   data,
+		Exception: []sentry.Exception{
+			{
+				Value:      err.Error(),
+				Type:       reflect.TypeOf(err).String(),
+				Stacktrace: sentry.ExtractStacktrace(err),
+			},
+		},
+	}, nil, nil)
 }

+ 19 - 9
api/server/shared/apierrors/errors.go

@@ -98,11 +98,6 @@ func HandleAPIError(
 	r *http.Request,
 	err RequestError,
 ) {
-	// if the status code is internal server error, use alerter
-	if err.GetStatusCode() == http.StatusInternalServerError && config.Alerter != nil {
-		config.Alerter.SendAlert(r.Context(), err)
-	}
-
 	extErrorStr := err.ExternalError()
 
 	// log the internal error
@@ -110,10 +105,18 @@ func HandleAPIError(
 		Str("internal_error", err.InternalError()).
 		Str("external_error", extErrorStr)
 
-	addLoggingScopes(r.Context(), event)
+	data := addLoggingScopes(r.Context(), event)
 	addLoggingRequestMeta(r, event)
 
-	event.Msg("")
+	event.Send()
+
+	// if the status code is internal server error, use alerter
+	if err.GetStatusCode() == http.StatusInternalServerError && config.Alerter != nil {
+		data["method"] = r.Method
+		data["url"] = r.URL.String()
+
+		config.Alerter.SendAlert(r.Context(), err, data)
+	}
 
 	// send the external error
 	resp := &types.ExternalError{
@@ -132,17 +135,20 @@ func HandleAPIError(
 		addLoggingScopes(r.Context(), event)
 		addLoggingRequestMeta(r, event)
 
-		event.Msg("")
+		event.Send()
 	}
 
 	return
 }
 
-func addLoggingScopes(ctx context.Context, event *zerolog.Event) {
+func addLoggingScopes(ctx context.Context, event *zerolog.Event) map[string]interface{} {
+	res := make(map[string]interface{})
+
 	// case on the context values that exist, add them to event
 	if userVal := ctx.Value(types.UserScope); userVal != nil {
 		if userModel, ok := userVal.(*models.User); ok {
 			event.Uint("user_id", userModel.ID)
+			res["user_id"] = userModel.ID
 		}
 	}
 
@@ -152,14 +158,18 @@ func addLoggingScopes(ctx context.Context, event *zerolog.Event) {
 			for key, scope := range reqScopes {
 				if scope.Resource.Name != "" {
 					event.Str(string(key), scope.Resource.Name)
+					res[string(key)] = scope.Resource.Name
 				}
 
 				if scope.Resource.UInt != 0 {
 					event.Uint(string(key), scope.Resource.UInt)
+					res[string(key)] = scope.Resource.UInt
 				}
 			}
 		}
 	}
+
+	return res
 }
 
 func addLoggingRequestMeta(r *http.Request, event *zerolog.Event) {