telemetry support
Fixes #832 Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
87
cmd/dagger/cmd/common/track.go
Normal file
87
cmd/dagger/cmd/common/track.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/spf13/cobra"
|
||||
"go.dagger.io/dagger/state"
|
||||
"go.dagger.io/dagger/telemetry"
|
||||
)
|
||||
|
||||
// TrackCommand sends telemetry about a command execution
|
||||
func TrackCommand(ctx context.Context, cmd *cobra.Command, props ...*telemetry.Property) chan struct{} {
|
||||
props = append([]*telemetry.Property{
|
||||
{
|
||||
Name: "command",
|
||||
Value: commandName(cmd),
|
||||
},
|
||||
}, props...)
|
||||
|
||||
return telemetry.TrackAsync(ctx, "Command Executed", props...)
|
||||
}
|
||||
|
||||
func commandName(cmd *cobra.Command) string {
|
||||
parts := []string{}
|
||||
for c := cmd; c.Parent() != nil; c = c.Parent() {
|
||||
parts = append([]string{c.Name()}, parts...)
|
||||
}
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
// TrackWorkspaceCommand is like TrackCommand but includes workspace and
|
||||
// optionally environment metadata.
|
||||
func TrackWorkspaceCommand(ctx context.Context, cmd *cobra.Command, w *state.Workspace, env *state.State, props ...*telemetry.Property) chan struct{} {
|
||||
props = append([]*telemetry.Property{
|
||||
{
|
||||
// Hash the repository URL for privacy
|
||||
Name: "git_repository_hash",
|
||||
Value: hash(gitRepoURL(w.Path)),
|
||||
},
|
||||
{
|
||||
// The workspace path might contain the username (e.g. /home/user/workspace), so we hash itfor privacy.
|
||||
Name: "workspace_path_hash",
|
||||
Value: hash(w.Path),
|
||||
},
|
||||
}, props...)
|
||||
|
||||
if env != nil {
|
||||
props = append([]*telemetry.Property{
|
||||
{
|
||||
Name: "environment_name",
|
||||
Value: env.Name,
|
||||
},
|
||||
}, props...)
|
||||
}
|
||||
|
||||
return TrackCommand(ctx, cmd, props...)
|
||||
}
|
||||
|
||||
// hash returns the sha256 digest of the string
|
||||
func hash(s string) string {
|
||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
|
||||
}
|
||||
|
||||
// gitRepoURL returns the git repository remote, if any.
|
||||
func gitRepoURL(path string) string {
|
||||
repo, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{
|
||||
DetectDotGit: true,
|
||||
})
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
origin, err := repo.Remote("origin")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if urls := origin.Config().URLs; len(urls) > 0 {
|
||||
return urls[0]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
@@ -38,6 +38,8 @@ var computeCmd = &cobra.Command{
|
||||
lg := logger.New()
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
doneCh := common.TrackCommand(ctx, cmd)
|
||||
|
||||
st := &state.State{
|
||||
Name: "FIXME",
|
||||
Path: args[0],
|
||||
@@ -191,6 +193,8 @@ var computeCmd = &cobra.Command{
|
||||
return nil
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to up environment")
|
||||
}
|
||||
|
@@ -269,6 +269,8 @@ var docCmd = &cobra.Command{
|
||||
lg := logger.New()
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
doneCh := common.TrackCommand(ctx, cmd)
|
||||
|
||||
format := viper.GetString("format")
|
||||
if format != textFormat &&
|
||||
format != markdownFormat &&
|
||||
@@ -297,6 +299,8 @@ var docCmd = &cobra.Command{
|
||||
}
|
||||
p := Parse(ctx, packageName, val)
|
||||
fmt.Printf("%s", p.Format(format))
|
||||
|
||||
<-doneCh
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,12 @@ var editCmd = &cobra.Command{
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||
|
||||
lg = lg.With().
|
||||
Str("environment", st.Name).
|
||||
Logger()
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st)
|
||||
|
||||
data, err := yaml.Marshal(st)
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("unable to marshal state")
|
||||
@@ -80,6 +86,8 @@ var editCmd = &cobra.Command{
|
||||
return nil
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Str("environment", st.Name).Msg("invalid input")
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -36,10 +37,13 @@ var initCmd = &cobra.Command{
|
||||
dir = cwd
|
||||
}
|
||||
|
||||
_, err := state.Init(ctx, dir)
|
||||
workspace, err := state.Init(ctx, dir)
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to initialize workspace")
|
||||
}
|
||||
|
||||
<-common.TrackWorkspaceCommand(ctx, cmd, workspace, nil)
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,6 @@ package input
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -23,7 +22,7 @@ var containerCmd = &cobra.Command{
|
||||
lg := logger.New()
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
updateEnvironmentInput(ctx, common.NewClient(ctx, false), args[0], state.DockerInput(args[1]))
|
||||
updateEnvironmentInput(ctx, cmd, args[0], state.DockerInput(args[1]))
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ var dirCmd = &cobra.Command{
|
||||
p = "./" + p
|
||||
}
|
||||
|
||||
updateEnvironmentInput(ctx, common.NewClient(ctx, false), args[0],
|
||||
updateEnvironmentInput(ctx, cmd, args[0],
|
||||
state.DirInput(
|
||||
p,
|
||||
viper.GetStringSlice("include"),
|
||||
|
@@ -3,7 +3,6 @@ package input
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -33,7 +32,7 @@ var gitCmd = &cobra.Command{
|
||||
subDir = args[3]
|
||||
}
|
||||
|
||||
updateEnvironmentInput(ctx, common.NewClient(ctx, false), args[0], state.GitInput(args[1], ref, subDir))
|
||||
updateEnvironmentInput(ctx, cmd, args[0], state.GitInput(args[1], ref, subDir))
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,6 @@ package input
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -25,7 +24,7 @@ var jsonCmd = &cobra.Command{
|
||||
|
||||
updateEnvironmentInput(
|
||||
ctx,
|
||||
common.NewClient(ctx, false),
|
||||
cmd,
|
||||
args[0],
|
||||
state.JSONInput(readInput(ctx, args[1])),
|
||||
)
|
||||
|
@@ -40,6 +40,8 @@ var listCmd = &cobra.Command{
|
||||
Str("environment", st.Name).
|
||||
Logger()
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st)
|
||||
|
||||
c, err := client.New(ctx, "", false)
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("unable to create client")
|
||||
@@ -77,6 +79,8 @@ var listCmd = &cobra.Command{
|
||||
return nil
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to query environment")
|
||||
}
|
||||
|
@@ -8,11 +8,11 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/client"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/environment"
|
||||
"go.dagger.io/dagger/solver"
|
||||
"go.dagger.io/dagger/state"
|
||||
"go.dagger.io/dagger/telemetry"
|
||||
)
|
||||
|
||||
// Cmd exposes the top-level command
|
||||
@@ -35,12 +35,23 @@ func init() {
|
||||
)
|
||||
}
|
||||
|
||||
func updateEnvironmentInput(ctx context.Context, cl *client.Client, target string, input state.Input) {
|
||||
lg := log.Ctx(ctx)
|
||||
func updateEnvironmentInput(ctx context.Context, cmd *cobra.Command, target string, input state.Input) {
|
||||
lg := *log.Ctx(ctx)
|
||||
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||
|
||||
lg = lg.With().
|
||||
Str("environment", st.Name).
|
||||
Logger()
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st, &telemetry.Property{
|
||||
Name: "input_target",
|
||||
Value: target,
|
||||
})
|
||||
|
||||
cl := common.NewClient(ctx, false)
|
||||
|
||||
st.SetInput(target, input)
|
||||
|
||||
err := cl.Do(ctx, st, func(ctx context.Context, env *environment.Environment, s solver.Solver) error {
|
||||
@@ -52,12 +63,14 @@ func updateEnvironmentInput(ctx context.Context, cl *client.Client, target strin
|
||||
return nil
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Str("environment", st.Name).Msg("invalid input")
|
||||
lg.Fatal().Err(err).Msg("invalid input")
|
||||
}
|
||||
|
||||
if err := workspace.Save(ctx, st); err != nil {
|
||||
lg.Fatal().Err(err).Str("environment", st.Name).Msg("cannot update environment")
|
||||
lg.Fatal().Err(err).Msg("cannot update environment")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
"golang.org/x/term"
|
||||
@@ -44,7 +43,7 @@ var secretCmd = &cobra.Command{
|
||||
|
||||
updateEnvironmentInput(
|
||||
ctx,
|
||||
common.NewClient(ctx, false),
|
||||
cmd,
|
||||
args[0],
|
||||
state.SecretInput(secret),
|
||||
)
|
||||
|
@@ -3,7 +3,6 @@ package input
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -25,7 +24,7 @@ var textCmd = &cobra.Command{
|
||||
|
||||
updateEnvironmentInput(
|
||||
ctx,
|
||||
common.NewClient(ctx, false),
|
||||
cmd,
|
||||
args[0],
|
||||
state.TextInput(readInput(ctx, args[1])),
|
||||
)
|
||||
|
@@ -3,7 +3,6 @@ package input
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||
"go.dagger.io/dagger/state"
|
||||
)
|
||||
@@ -25,7 +24,7 @@ var yamlCmd = &cobra.Command{
|
||||
|
||||
updateEnvironmentInput(
|
||||
ctx,
|
||||
common.NewClient(ctx, false),
|
||||
cmd,
|
||||
args[0],
|
||||
state.YAMLInput(readInput(ctx, args[1])),
|
||||
)
|
||||
|
@@ -30,6 +30,8 @@ var listCmd = &cobra.Command{
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, nil)
|
||||
|
||||
environments, err := workspace.List(ctx)
|
||||
if err != nil {
|
||||
lg.
|
||||
@@ -44,6 +46,8 @@ var listCmd = &cobra.Command{
|
||||
line := fmt.Sprintf("%s\t%s\t", e.Name, formatPath(e.Path))
|
||||
fmt.Fprintln(w, line)
|
||||
}
|
||||
|
||||
<-doneCh
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -32,12 +32,15 @@ var newCmd = &cobra.Command{
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
_, err := workspace.Create(ctx, name, state.Plan{
|
||||
st, err := workspace.Create(ctx, name, state.Plan{
|
||||
Package: viper.GetString("package"),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to create environment")
|
||||
}
|
||||
|
||||
<-common.TrackWorkspaceCommand(ctx, cmd, workspace, st)
|
||||
},
|
||||
}
|
||||
|
||||
|
@@ -34,11 +34,19 @@ var listCmd = &cobra.Command{
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||
|
||||
lg = lg.With().
|
||||
Str("environment", st.Name).
|
||||
Logger()
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st)
|
||||
|
||||
cl := common.NewClient(ctx, false)
|
||||
err := cl.Do(ctx, st, func(ctx context.Context, env *environment.Environment, s solver.Solver) error {
|
||||
return ListOutputs(ctx, env, true)
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to scan outputs")
|
||||
}
|
||||
|
@@ -30,8 +30,6 @@ var queryCmd = &cobra.Command{
|
||||
lg := logger.New()
|
||||
ctx := lg.WithContext(cmd.Context())
|
||||
|
||||
cueOpts := parseQueryFlags()
|
||||
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
state := common.CurrentEnvironmentState(ctx, workspace)
|
||||
|
||||
@@ -39,11 +37,14 @@ var queryCmd = &cobra.Command{
|
||||
Str("environment", state.Name).
|
||||
Logger()
|
||||
|
||||
cueOpts := parseQueryFlags()
|
||||
cuePath := cue.MakePath()
|
||||
if len(args) > 0 {
|
||||
cuePath = cue.ParsePath(args[0])
|
||||
}
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, state)
|
||||
|
||||
cl := common.NewClient(ctx, false)
|
||||
cueVal := compiler.NewValue()
|
||||
|
||||
@@ -62,6 +63,8 @@ var queryCmd = &cobra.Command{
|
||||
return nil
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to query environment")
|
||||
}
|
||||
|
@@ -37,6 +37,12 @@ var upCmd = &cobra.Command{
|
||||
workspace := common.CurrentWorkspace(ctx)
|
||||
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||
|
||||
lg = lg.With().
|
||||
Str("environment", st.Name).
|
||||
Logger()
|
||||
|
||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st)
|
||||
|
||||
cl := common.NewClient(ctx, viper.GetBool("no-cache"))
|
||||
|
||||
err := cl.Do(ctx, st, func(ctx context.Context, env *environment.Environment, s solver.Solver) error {
|
||||
@@ -57,6 +63,8 @@ var upCmd = &cobra.Command{
|
||||
return output.ListOutputs(ctx, env, term.IsTerminal(int(os.Stdout.Fd())))
|
||||
})
|
||||
|
||||
<-doneCh
|
||||
|
||||
if err != nil {
|
||||
lg.Fatal().Err(err).Msg("failed to up environment")
|
||||
}
|
||||
|
Reference in New Issue
Block a user