diff --git a/go.mod b/go.mod index 35c52b4040..1fddeea98e 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( github.com/cosmos/gogoproto v1.6.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 @@ -213,7 +214,6 @@ require ( github.com/firefart/nonamedreturns v1.0.5 // 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.6 // indirect github.com/go-chi/chi/v5 v5.0.12 // indirect github.com/go-critic/go-critic v0.11.4 // indirect diff --git a/ignite/cmd/ignite/main.go b/ignite/cmd/ignite/main.go index 3b5236bb20..33b1dbd15f 100644 --- a/ignite/cmd/ignite/main.go +++ b/ignite/cmd/ignite/main.go @@ -19,12 +19,13 @@ import ( "github.com/ignite/cli/v29/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 { @@ -41,6 +42,7 @@ func run() int { } var wg sync.WaitGroup analytics.SendMetric(&wg, subCmd) + analytics.SendErrors(&wg, ctx) err = cmd.ExecuteContext(ctx) if err != nil { @@ -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 } diff --git a/ignite/internal/analytics/analytics.go b/ignite/internal/analytics/analytics.go index 3858aa7117..c2227a2622 100644 --- a/ignite/internal/analytics/analytics.go +++ b/ignite/internal/analytics/analytics.go @@ -3,6 +3,7 @@ package analytics import ( "context" "encoding/json" + "fmt" "os" "path/filepath" "strconv" @@ -16,6 +17,7 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/gitpod" "github.com/ignite/cli/v29/ignite/pkg/matomo" "github.com/ignite/cli/v29/ignite/pkg/randstr" + "github.com/ignite/cli/v29/ignite/pkg/sentry" "github.com/ignite/cli/v29/ignite/version" ) @@ -52,6 +54,7 @@ func SendMetric(wg *sync.WaitGroup, cmd *cobra.Command) { } dntInfo, err := checkDNT() + fmt.Println(dntInfo, err) if err != nil || dntInfo.DoNotTrack { return } @@ -99,11 +102,30 @@ func SendMetric(wg *sync.WaitGroup, cmd *cobra.Command) { }() } +// SendErrors send command errors to Sentry. +func SendErrors(wg *sync.WaitGroup, ctx context.Context) { + 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) { - if dnt, err := strconv.ParseBool(os.Getenv(envDoNotTrack)); err != nil || dnt { - return anonIdentity{DoNotTrack: true}, nil + if dnt := os.Getenv(envDoNotTrack); dnt != "" { + if dnt, err := strconv.ParseBool(dnt); err != nil || dnt { + return anonIdentity{DoNotTrack: true}, nil + } } globalPath, err := config.DirPath() diff --git a/ignite/pkg/sentry/sentry.go b/ignite/pkg/sentry/sentry.go new file mode 100644 index 0000000000..ef3adc4c95 --- /dev/null +++ b/ignite/pkg/sentry/sentry.go @@ -0,0 +1,46 @@ +package sentry + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/getsentry/sentry-go" + + "github.com/ignite/cli/v29/ignite/version" +) + +const IgniteDNS = "https://examplePublicKey@o0.ingest.sentry.io/0" + +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, fmt.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, fmt.Errorf("failed to init sentry: %w", err) + } + + return func() { + sentry.Flush(time.Second * 2) + }, nil +} + +func getEnvironment(igniteVersion string) string { + if strings.Contains(igniteVersion, "dev") { + return "development" + } else { + return "production" + } +}