Skip to content

Commit

Permalink
chore(cli): update telemetry implementation and update docs page
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalbreuninger committed Dec 20, 2024
1 parent 4d57616 commit 7d03ab8
Show file tree
Hide file tree
Showing 19 changed files with 670 additions and 544 deletions.
20 changes: 7 additions & 13 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"os"
"os/exec"
"runtime/debug"

"github.com/loft-sh/devpod/cmd/agent"
"github.com/loft-sh/devpod/cmd/context"
Expand Down Expand Up @@ -35,8 +34,6 @@ func NewRootCmd() *cobra.Command {
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error {
telemetry.Collector.SetCLIData(cobraCmd, globalFlags)

if globalFlags.LogOutput == "json" {
log2.Default.SetFormat(log2.JSONFormat)
} else if globalFlags.LogOutput == "raw" {
Expand All @@ -57,6 +54,11 @@ func NewRootCmd() *cobra.Command {
_ = os.Setenv(config.DEVPOD_HOME, globalFlags.DevPodHome)
}

devPodConfig, err := config.LoadConfig(globalFlags.Context, globalFlags.Provider)
if err == nil {
telemetry.StartCLI(devPodConfig, cobraCmd)
}

return nil
},
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -72,21 +74,13 @@ func NewRootCmd() *cobra.Command {
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
defer func() {
// recover from panic in order to log it via telemetry
if err := recover(); err != nil {
retErr := fmt.Errorf("panic: %v %s", err, debug.Stack())
telemetry.Collector.RecordEndEvent(retErr)
log2.Default.Fatal(retErr)
}
}()

// build the root command
rootCmd := BuildRoot()

// execute command
err := rootCmd.Execute()
telemetry.Collector.RecordEndEvent(err)
telemetry.CollectorCLI.RecordCLI(err)
telemetry.CollectorCLI.Flush()
if err != nil {
//nolint:all
if sshExitErr, ok := err.(*ssh.ExitError); ok {
Expand Down
2 changes: 2 additions & 0 deletions cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/loft-sh/devpod/pkg/port"
provider2 "github.com/loft-sh/devpod/pkg/provider"
devssh "github.com/loft-sh/devpod/pkg/ssh"
"github.com/loft-sh/devpod/pkg/telemetry"
"github.com/loft-sh/devpod/pkg/tunnel"
"github.com/loft-sh/devpod/pkg/version"
workspace2 "github.com/loft-sh/devpod/pkg/workspace"
Expand Down Expand Up @@ -86,6 +87,7 @@ func NewUpCmd(f *flags.GlobalFlags) *cobra.Command {
if err != nil {
return fmt.Errorf("prepare workspace client: %w", err)
}
telemetry.CollectorCLI.SetClient(client)

return cmd.Run(ctx, devPodConfig, client, logger)
},
Expand Down
39 changes: 16 additions & 23 deletions docs/pages/other-topics/telemetry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,25 @@ Below you can find an example of the payload that DevPod CLI would send to our t

```yaml
{
"type":"cmdfinished", # type of event, another type is "cmdstarted"
"event":{
"type":"devpod_cli", # type of event
"machine_id":"3ed2c7...ee308e6", # securely hashed machine ID to de-duplicate information received from the same user
"timestamp":1683878643781772,
"executionID":"23736e5...83b3d656a0", # random ID to de-duplicate information received via different event types
"command":"devpod provider delete", # the CLI command that was executed
"provider":"kubernetes", # the default provider
"processingTime":71980, # how long it took for the command to execute
"errors":"provider 'docker' does not exist"
"properties": {
"command":"devpod provider delete", # the CLI command that was executed
"provider":"kubernetes", # the default provider
"source_type":"git:", # the workspace source type (git, image, local, container, unknown)
"ide":"vscode", # the IDE used to open a workspace
"desktop":"true", # whether this cli command has been executed by DevPod Desktop or is a direct CLI invokation
"version":"v0.5.29", # the CLI version
"error":"provider 'docker' does not exist" # an error that occured during command execution
}
},
"instanceProperties":{
"uid":"3ed2c7...ee308e6", # securely hashed machine ID to de-duplicate information received from the same user
"arch":"amd64", # CPU architecture
"os":"linux", # Operating system
"version":{ # DevPod CLI version
"major":"0",
"minor":"1",
"patch":"0"
},
"flags":{
"setFlags":[ # List of flags(names only) that were set
"debug"
]
},
"ui": false
"user":{
"machine_id":"3ed2c7...ee308e6", # securely hashed machine ID to de-duplicate information received from the same user
"arch":"amd64", # CPU architecture
"os":"linux", # Operating system
},
"token":"eyJhbG...coNz80" # Token generated from the static key included in the CLI binary. It is used to validate payload integrity.
}
```

Expand All @@ -58,4 +51,4 @@ To disable the telemetry execute the following command:

```bash
devpod context set-options -o TELEMETRY=false
```
```
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ require (
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/loft-sh/admin-apis v0.0.0-20241127134028-9cfb6b23ec44 // indirect
github.com/loft-sh/analytics-client v0.0.0-20240219162240-2f4c64b2494e // indirect
github.com/loft-sh/apiserver v0.0.0-20241008120650-f17d504a4d0d // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ github.com/loft-sh/admin-apis v0.0.0-20241127134028-9cfb6b23ec44 h1:Sq6qEsKSiZHY
github.com/loft-sh/admin-apis v0.0.0-20241127134028-9cfb6b23ec44/go.mod h1:MWczNwKvWssHo1KaeZKaWDdRLYSNbWqQBGsTLoCNd7U=
github.com/loft-sh/agentapi/v4 v4.2.0-alpha.6 h1:eVIzaW+EvIygxNXl5163c1+WcUr8c95OP6lj8FcJHUc=
github.com/loft-sh/agentapi/v4 v4.2.0-alpha.6/go.mod h1:yqbIMmyXqbzZcK0DlwldRLy0xb3lYnH4NoI3K+iETlM=
github.com/loft-sh/analytics-client v0.0.0-20240219162240-2f4c64b2494e h1:JcPnMaoczikvpasi8OJ47dCkWZjfgFubWa4V2SZo7h0=
github.com/loft-sh/analytics-client v0.0.0-20240219162240-2f4c64b2494e/go.mod h1:FFWcGASyM2QlWTDTCG/WBVM/XYr8btqYt335TFNRCFg=
github.com/loft-sh/api/v4 v4.0.0-alpha.6.0.20241129074910-a24d4104d586 h1:nBLJCtuGQH0Cq4lkaUJsDqSUYueWT874YVuW66BQ9S0=
github.com/loft-sh/api/v4 v4.0.0-alpha.6.0.20241129074910-a24d4104d586/go.mod h1:bPDJ1+vZBBEIoPgykfy+TzOwLHtTvWAbTSHexnj4tJA=
github.com/loft-sh/apiserver v0.0.0-20241008120650-f17d504a4d0d h1:73wE8wtsnJm4bXtFbTDRG1EgN4LonpPdgzF3HFhP7kA=
Expand Down
9 changes: 0 additions & 9 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import (
"time"

"github.com/ghodss/yaml"
"github.com/loft-sh/devpod/pkg/telemetry"
"github.com/loft-sh/devpod/pkg/types"
"github.com/loft-sh/devpod/pkg/version"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -271,13 +269,6 @@ func LoadConfig(contextOverride string, providerOverride string) (*Config, error

config.Origin = configOrigin

// make sure to not send telemetry if disabled or in dev mode
if config.ContextOption(ContextOptionTelemetry) != "false" && version.GetVersion() != version.DevVersion {
go func() {
telemetry.Collector.RecordStartEvent(config.Current().DefaultProvider)
}()
}

return config, nil
}

Expand Down
23 changes: 23 additions & 0 deletions pkg/provider/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var (
WorkspaceSourceLocal = "local:"
WorkspaceSourceImage = "image:"
WorkspaceSourceContainer = "container:"
WorkspaceSourceUnknown = "unknown:"
)

type Workspace struct {
Expand Down Expand Up @@ -262,6 +263,28 @@ func (w WorkspaceSource) String() string {
return ""
}

func (w WorkspaceSource) Type() string {
if w.GitRepository != "" {
if w.GitPRReference != "" {
return WorkspaceSourceGit + "pr"
} else if w.GitBranch != "" {
return WorkspaceSourceGit + "branch"
} else if w.GitCommit != "" {
return WorkspaceSourceGit + "commit"
}

return WorkspaceSourceGit
} else if w.LocalFolder != "" {
return WorkspaceSourceLocal
} else if w.Image != "" {
return WorkspaceSourceImage
} else if w.Container != "" {
return WorkspaceSourceContainer
}

return WorkspaceSourceUnknown
}

func ParseWorkspaceSource(source string) *WorkspaceSource {
if strings.HasPrefix(source, WorkspaceSourceGit) {
gitRepo, gitPRReference, gitBranch, gitCommit, gitSubdir := git.NormalizeRepository(strings.TrimPrefix(source, WorkspaceSourceGit))
Expand Down
Loading

0 comments on commit 7d03ab8

Please sign in to comment.