diff --git a/Changelog.md b/Changelog.md index 25fb80a3..accd62d1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,10 @@ # ProtonMail Bridge and Import-Export app Changelog Changelog [format](http://keepachangelog.com/en/1.0.0/) +## Untaged +### Changed +* GODT-180 Updated Sentry client. + ## [IE 1.2.1] Elbe diff --git a/internal/cmd/main.go b/internal/cmd/main.go index e83d806b..f09d56cd 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -22,7 +22,7 @@ import ( "runtime" "github.com/ProtonMail/proton-bridge/pkg/constants" - "github.com/getsentry/raven-go" + "github.com/getsentry/sentry-go" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -51,10 +51,14 @@ var ( // Main sets up Sentry, filters out unwanted args, creates app and runs it. func Main(appName, usage string, extraFlags []cli.Flag, run func(*cli.Context) error) { - if err := raven.SetDSN(constants.DSNSentry); err != nil { + err := sentry.Init(sentry.ClientOptions{ + Dsn: constants.DSNSentry, + Release: constants.Revision, + }) + + if err != nil { log.WithError(err).Errorln("Can not setup sentry DSN") } - raven.SetRelease(constants.Revision) filterProcessSerialNumberFromArgs() filterRestartNumberFromArgs() diff --git a/pkg/pmapi/users.go b/pkg/pmapi/users.go index b5c86e09..4d723ddb 100644 --- a/pkg/pmapi/users.go +++ b/pkg/pmapi/users.go @@ -18,7 +18,7 @@ package pmapi import ( - "github.com/getsentry/raven-go" + "github.com/getsentry/sentry-go" "github.com/pkg/errors" ) @@ -119,7 +119,11 @@ func (c *client) UpdateUser() (user *User, err error) { } c.user = user - raven.SetUserContext(&raven.User{ID: user.ID}) + sentry.ConfigureScope(func(scope *sentry.Scope) { + scope.SetUser(sentry.User{ + ID: user.ID, + }) + }) var tmpList AddressList if tmpList, err = c.GetAddresses(); err == nil { diff --git a/pkg/sentry/report.go b/pkg/sentry/report.go index a5bc478e..cd967584 100644 --- a/pkg/sentry/report.go +++ b/pkg/sentry/report.go @@ -18,135 +18,15 @@ package sentry import ( - "fmt" - "regexp" + "errors" "runtime" - "runtime/pprof" - "strconv" - "strings" + "time" - "github.com/getsentry/raven-go" + "github.com/getsentry/sentry-go" log "github.com/sirupsen/logrus" ) -const fileParseError = "[file parse error]" - -var isGoroutine = regexp.MustCompile("^goroutine [[:digit:]]+.*") //nolint[gochecknoglobals] - -// Threads implements standard sentry thread report. -type Threads struct { - Values []Thread `json:"values"` -} - -// Class specifier. -func (s *Threads) Class() string { return "threads" } - -// Thread wraps a single stacktrace. -type Thread struct { - ID int `json:"id"` - Name string `json:"name"` - Crashed bool `json:"crashed"` - Stacktrace *raven.Stacktrace `json:"stacktrace"` -} - -// TraceAllRoutines traces all goroutines and saves them to the current object. -func (s *Threads) TraceAllRoutines() { - s.Values = []Thread{} - goroutines := &strings.Builder{} - _ = pprof.Lookup("goroutine").WriteTo(goroutines, 2) - - thread := Thread{ID: -1} - var frame *raven.StacktraceFrame - for _, v := range strings.Split(goroutines.String(), "\n") { - // Ignore empty lines. - if v == "" { - continue - } - - // New routine. - if isGoroutine.MatchString(v) { - if thread.ID >= 0 { - s.Values = append(s.Values, thread) - } - thread = Thread{ID: thread.ID + 1, Name: v, Crashed: thread.ID == -1, Stacktrace: &raven.Stacktrace{Frames: []*raven.StacktraceFrame{}}} - continue - } - - // New function. - if frame == nil { - frame = &raven.StacktraceFrame{Function: v} - continue - } - - // Set filename and add frame. - if frame.Filename == "" { - fld := strings.Fields(v) - if len(fld) != 2 { - frame.Filename = fileParseError - frame.AbsolutePath = v - } else { - frame.Filename = fld[0] - sp := strings.Split(fld[0], ":") - if len(sp) > 1 { - i, err := strconv.Atoi(sp[len(sp)-1]) - if err == nil { - frame.Filename = strings.Join(sp[:len(sp)-1], ":") - frame.Lineno = i - } - } - } - if frame.AbsolutePath == "" && frame.Filename != fileParseError { - frame.AbsolutePath = frame.Filename - if sp := strings.Split(frame.Filename, "/"); len(sp) > 1 { - frame.Filename = sp[len(sp)-1] - } - } - thread.Stacktrace.Frames = append([]*raven.StacktraceFrame{frame}, thread.Stacktrace.Frames...) - frame = nil - continue - } - } - // Add last thread. - s.Values = append(s.Values, thread) -} - -func findPanicSender(s *Threads, err error) string { - out := "error nil" - if err != nil { - out = err.Error() - } - for _, thread := range s.Values { - if !thread.Crashed { - continue - } - for i, fr := range thread.Stacktrace.Frames { - if strings.HasSuffix(fr.Filename, "panic.go") && strings.HasPrefix(fr.Function, "panic") { - // Next frame if any. - j := 0 - if i > j { - j = i - 1 - } - - // Directory and filename. - fname := thread.Stacktrace.Frames[j].AbsolutePath - if sp := strings.Split(fname, "/"); len(sp) > 2 { - fname = strings.Join(sp[len(sp)-2:], "/") - } - - // Line number. - if ln := thread.Stacktrace.Frames[j].Lineno; ln > 0 { - fname = fmt.Sprintf("%s:%d", fname, ln) - } - - out = fmt.Sprintf("%s: %s", fname, out) - break // Just first panic. - } - } - } - return out -} - -// ReportSentryCrash reports a sentry crash with stacktrace from all goroutines. +// ReportSentryCrash reports a sentry crash. func ReportSentryCrash(clientID, appVersion, userAgent string, reportErr error) (err error) { if reportErr == nil { return @@ -160,18 +40,16 @@ func ReportSentryCrash(clientID, appVersion, userAgent string, reportErr error) "UserID": "", } - threads := &Threads{} - threads.TraceAllRoutines() - errorWithFile := findPanicSender(threads, reportErr) - packet := raven.NewPacket(errorWithFile, threads) + sentry.WithScope(func(scope *sentry.Scope) { + scope.SetTags(tags) + sentry.CaptureException(reportErr) + }) - eventID, ch := raven.Capture(packet, tags) - - if err = <-ch; err == nil { - log.WithField("errorID", eventID).Warn("Reported sentry error") - } else { - log.WithField("error", reportErr).WithError(err).Error("Failed to report sentry error") + if !sentry.Flush(time.Second * 10) { + log.WithField("error", reportErr).Error("failed to report sentry error") + return errors.New("failed to report sentry error") } - return err + log.WithField("error", reportErr).Warn("reported sentry error") + return } diff --git a/pkg/sentry/report_test.go b/pkg/sentry/report_test.go deleted file mode 100644 index 4c902ee4..00000000 --- a/pkg/sentry/report_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2020 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - -package sentry - -import ( - "errors" - "testing" - - "github.com/getsentry/raven-go" -) - -func TestSentryCrashReport(t *testing.T) { - if err := ReportSentryCrash( - "clientID", - "appVersion", - "useragent", - errors.New("Testing crash report - api proxy; goroutines with threads, find origin"), - ); err != nil { - t.Fatal("Expected no error while report, but have", err) - } -} - -func (s *Threads) TraceAllRoutinesTest() { - s.Values = []Thread{ - { - ID: 0, - Name: "goroutine 20 [running]", - Crashed: true, - Stacktrace: &raven.Stacktrace{ - Frames: []*raven.StacktraceFrame{ - { - Filename: "/home/dev/build/go-1.10.2/go/src/runtime/pprof/pprof.go", - Function: "runtime/pprof.writeGoroutineStacks(0x9b7de0, 0xc4203e2900, 0xd0, 0xd0)", - Lineno: 650, - }, - }, - }, - }, - { - ID: 1, - Name: "goroutine 20 [chan receive]", - Crashed: false, - Stacktrace: &raven.Stacktrace{ - Frames: []*raven.StacktraceFrame{ - { - Filename: "/home/dev/build/go-1.10.2/go/src/testing/testing.go", - Function: "testing.(*T).Run(0xc4203e42d0, 0x90f445, 0x15, 0x97d358, 0x47a501)", - Lineno: 825, - }, - }, - }, - }, - } -}