Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: report bug to sentry (backport #4328) #4358

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Changes

- [#4357](https://github.com/ignite/cli/pull/4357) Bump chain dependencies (store, ics, log, etc)
- [#4328](https://github.com/ignite/cli/pull/4328) Send ignite bug report to sentry. Opt out the same way as for usage analytics

## [`v28.5.2`](https://github.com/ignite/cli/releases/tag/v28.5.2)

Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/cosmos/gogoproto v1.7.0
github.com/emicklei/proto v1.12.2
github.com/emicklei/proto-contrib v0.15.0
github.com/getsentry/sentry-go v0.27.0
github.com/go-delve/delve v1.21.0
github.com/go-git/go-git/v5 v5.12.0
github.com/go-openapi/analysis v0.23.0
Expand Down Expand Up @@ -222,10 +223,9 @@ require (
github.com/firefart/nonamedreturns v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/ghostiam/protogetter v0.3.5 // indirect
github.com/ghostiam/protogetter v0.3.6 // indirect
github.com/go-chi/chi/v5 v5.0.13 // indirect
github.com/go-critic/go-critic v0.11.2 // indirect
github.com/go-critic/go-critic v0.11.4 // indirect
github.com/go-delve/liner v1.2.3-0.20231231155935-4726ab1d7f62 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlya
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghostiam/protogetter v0.3.5 h1:+f7UiF8XNd4w3a//4DnusQ2SZjPkUjxkMEfjbxOK4Ug=
github.com/ghostiam/protogetter v0.3.5/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw=
github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk=
github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU=
Expand All @@ -498,8 +498,8 @@ github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-chi/chi/v5 v5.0.13 h1:JlH2F2M8qnwl0N1+JFFzlX9TlKJYas3aPXdiuTmJL+w=
github.com/go-chi/chi/v5 v5.0.13/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-critic/go-critic v0.11.2 h1:81xH/2muBphEgPtcwH1p6QD+KzXl2tMSi3hXjBSxDnM=
github.com/go-critic/go-critic v0.11.2/go.mod h1:OePaicfjsf+KPy33yq4gzv6CO7TEQ9Rom6ns1KsJnl8=
github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU=
github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc=
github.com/go-delve/delve v1.21.0 h1:npcc8TZhdVxaMSJon+zqcE3bXM/ck8SSOOWw/id13jI=
github.com/go-delve/delve v1.21.0/go.mod h1:U+OAdfhewudkHsVs/AwhfpSBu7t/NgIXH3+my4T5q78=
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d/go.mod h1:biJCRbqp51wS+I92HMqn5H8/A0PAhxn2vyOT+JqhiGI=
Expand Down
7 changes: 5 additions & 2 deletions ignite/cmd/ignite/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ import (
"github.com/ignite/cli/v28/ignite/pkg/xstrings"
)

const exitCodeOK, exitCodeError = 0, 1

func main() {
os.Exit(run())
}

func run() int {
const exitCodeOK, exitCodeError = 0, 1
ctx := clictx.From(context.Background())
cmd, cleanUp, err := ignitecmd.New(ctx)
if err != nil {
Expand All @@ -41,6 +42,7 @@ func run() int {
}
var wg sync.WaitGroup
analytics.SendMetric(&wg, subCmd)
analytics.EnableSentry(&wg, ctx)

err = cmd.ExecuteContext(ctx)
if err != nil {
Expand Down Expand Up @@ -77,7 +79,8 @@ func run() int {
return exitCodeError
}

wg.Wait() // waits for all metrics to be sent
// waits for analytics to finish
wg.Wait()

return exitCodeOK
}
Expand Down
18 changes: 18 additions & 0 deletions ignite/internal/analytics/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"github.com/ignite/cli/v28/ignite/pkg/gitpod"
"github.com/ignite/cli/v28/ignite/pkg/matomo"
"github.com/ignite/cli/v28/ignite/pkg/randstr"
"github.com/ignite/cli/v28/ignite/pkg/sentry"
"github.com/ignite/cli/v28/ignite/version"
)

Expand Down Expand Up @@ -99,6 +100,23 @@
}()
}

// EnableSentry enable errors reporting to Sentry.
func EnableSentry(wg *sync.WaitGroup, ctx context.Context) {

Check warning on line 104 in ignite/internal/analytics/analytics.go

View workflow job for this annotation

GitHub Actions / Lint Go code

context-as-argument: context.Context should be the first parameter of a function (revive)
dntInfo, err := checkDNT()
if err != nil || dntInfo.DoNotTrack {
return
}

closeSentry, err := sentry.InitSentry(ctx)
wg.Add(1)
go func() {
defer wg.Done()
if err == nil {
defer closeSentry()
}
}()
}

// checkDNT check if the user allow to track data or if the DO_NOT_TRACK
// env var is set https://consoledonottrack.com/
func checkDNT() (anonIdentity, error) {
Expand Down
33 changes: 26 additions & 7 deletions ignite/pkg/errors/xerrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,45 @@ package errors

import (
"github.com/cockroachdb/errors"
"github.com/getsentry/sentry-go"
)

// New creates an error with a simple error message.
// A stack trace is retained.
func New(msg string) error { return errors.New(msg) }
func New(msg string) error {
err := errors.New(msg)
sentry.CaptureException(err)
return err
}

// Errorf aliases Newf().
func Errorf(format string, args ...interface{}) error { return errors.Errorf(format, args...) }
func Errorf(format string, args ...interface{}) error {
err := errors.Errorf(format, args...)
sentry.CaptureException(err)
return err
}

// WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error {
errWithStack := errors.WithStack(err)
sentry.CaptureException(errWithStack)
return errWithStack
}

// Wrap wraps an error with a message prefix. A stack trace is retained.
func Wrap(err error, msg string) error { return errors.Wrap(err, msg) }
func Wrap(err error, msg string) error {
errWrap := errors.Wrap(err, msg)
sentry.CaptureException(errWrap)
return errWrap
}

// Wrapf wraps an error with a formatted message prefix. A stack
// trace is also retained. If the format is empty, no prefix is added,
// but the extra arguments are still processed for reportable strings.
func Wrapf(err error, format string, args ...interface{}) error {
return errors.Wrapf(err, format, args...)
errWrap := errors.Wrapf(err, format, args...)
sentry.CaptureException(errWrap)
return errWrap
}

// Unwrap accesses the direct cause of the error if any, otherwise
Expand All @@ -52,6 +74,3 @@ func Is(err, reference error) bool { return errors.Is(err, reference) }
// As(interface{}) bool such that As(target) returns true. As will panic if target
// is not a non-nil pointer to a type which implements error or is of interface type.
func As(err error, target interface{}) bool { return errors.As(err, target) }

// WithStack annotates err with a stack trace at the point WithStack was called.
func WithStack(err error) error { return errors.WithStack(err) }
48 changes: 48 additions & 0 deletions ignite/pkg/sentry/sentry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package sentry

import (
"context"
"fmt"
"strings"
"time"

"github.com/getsentry/sentry-go"

"github.com/ignite/cli/v28/ignite/pkg/errors"
"github.com/ignite/cli/v28/ignite/version"
)

const IgniteDNS = "https://bugs.ignite.com"

func InitSentry(ctx context.Context) (deferMe func(), err error) {
sentrySyncTransport := sentry.NewHTTPSyncTransport()
sentrySyncTransport.Timeout = time.Second * 3

igniteInfo, err := version.GetInfo(ctx)
if err != nil {
return nil, errors.Errorf("failed to init sentry: %w", err)
}

if err := sentry.Init(sentry.ClientOptions{
Dsn: IgniteDNS,
Transport: sentrySyncTransport,
Environment: getEnvironment(igniteInfo.CLIVersion),
Release: fmt.Sprintf("ignite@%s", igniteInfo.CLIVersion),
SampleRate: 1.0, // get all events
}); err != nil {
return nil, errors.Errorf("failed to init sentry: %w", err)
}

return func() {
sentry.Recover()
sentry.Flush(time.Second * 2)
}, nil
}

func getEnvironment(igniteVersion string) string {
if strings.Contains(igniteVersion, "dev") {
return "development"
}

return "production"
}
Loading