github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/cmd/cli/command/track.go (about) 1 package command 2 3 import ( 4 "strings" 5 "sync" 6 7 "github.com/defang-io/defang/src/pkg" 8 "github.com/defang-io/defang/src/pkg/cli" 9 cliClient "github.com/defang-io/defang/src/pkg/cli/client" 10 "github.com/spf13/cobra" 11 "github.com/spf13/pflag" 12 ) 13 14 var disableAnalytics = pkg.GetenvBool("DEFANG_DISABLE_ANALYTICS") 15 16 type P = cliClient.Property // shorthand for tracking properties 17 18 // trackWG is used to wait for all tracking to complete. 19 var trackWG = sync.WaitGroup{} 20 21 // Track sends a tracking event to the server in a separate goroutine. 22 func Track(name string, props ...P) { 23 if disableAnalytics { 24 return 25 } 26 if client == nil { 27 client, _ = cli.Connect(cluster, nil) 28 } 29 trackWG.Add(1) 30 go func(client cliClient.Client) { 31 defer trackWG.Done() 32 _ = client.Track(name, props...) 33 }(client) 34 } 35 36 // flushAllTracking waits for all tracking goroutines to complete. 37 func FlushAllTracking() { 38 trackWG.Wait() 39 } 40 41 // trackCmd sends a tracking event for a Cobra command and its arguments. 42 func trackCmd(cmd *cobra.Command, verb string, props ...P) { 43 command := "Unknown" 44 if cmd != nil { 45 command = cmd.Name() 46 // Ignore tracking for shell completion requests 47 if command == cobra.ShellCompRequestCmd { 48 return 49 } 50 calledAs := cmd.CalledAs() 51 cmd.VisitParents(func(c *cobra.Command) { 52 calledAs = c.CalledAs() + " " + calledAs 53 if c.HasParent() { // skip root command 54 command = c.Name() + "-" + command 55 } 56 }) 57 props = append(props, P{Name: "CalledAs", Value: calledAs}) 58 cmd.Flags().Visit(func(f *pflag.Flag) { 59 props = append(props, P{Name: f.Name, Value: f.Value}) 60 }) 61 } 62 Track(strings.Title(command+" "+verb), props...) 63 }