mirror of https://github.com/coder/coder.git
feat(coderd): add enabled experiments to telemetry (#12656)
This commit is contained in:
parent
f0f9569d51
commit
ab95ae827d
|
@ -11,9 +11,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
|
|
|
@ -819,6 +819,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
|||
Prometheus: vals.Prometheus.Enable.Value(),
|
||||
STUN: len(vals.DERP.Server.STUNAddresses) != 0,
|
||||
Tunnel: tunnel != nil,
|
||||
Experiments: vals.Experiments.Value(),
|
||||
ParseLicenseJWT: func(lic *telemetry.License) error {
|
||||
// This will be nil when running in AGPL-only mode.
|
||||
if options.ParseLicenseClaims == nil {
|
||||
|
|
|
@ -54,6 +54,7 @@ type Options struct {
|
|||
SnapshotFrequency time.Duration
|
||||
Tunnel bool
|
||||
ParseLicenseJWT func(lic *License) error
|
||||
Experiments []string
|
||||
}
|
||||
|
||||
// New constructs a reporter for telemetry data.
|
||||
|
@ -480,6 +481,10 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
eg.Go(func() error {
|
||||
snapshot.Experiments = ConvertExperiments(r.options.Experiments)
|
||||
return nil
|
||||
})
|
||||
|
||||
err := eg.Wait()
|
||||
if err != nil {
|
||||
|
@ -741,6 +746,16 @@ func ConvertExternalProvisioner(id uuid.UUID, tags map[string]string, provisione
|
|||
}
|
||||
}
|
||||
|
||||
func ConvertExperiments(experiments []string) []Experiment {
|
||||
var out []Experiment
|
||||
|
||||
for _, exp := range experiments {
|
||||
out = append(out, Experiment{Name: exp})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Snapshot represents a point-in-time anonymized database dump.
|
||||
// Data is aggregated by latest on the server-side, so partial data
|
||||
// can be sent without issue.
|
||||
|
@ -763,6 +778,7 @@ type Snapshot struct {
|
|||
WorkspaceResourceMetadata []WorkspaceResourceMetadata `json:"workspace_resource_metadata"`
|
||||
WorkspaceResources []WorkspaceResource `json:"workspace_resources"`
|
||||
Workspaces []Workspace `json:"workspaces"`
|
||||
Experiments []Experiment `json:"experiments"`
|
||||
}
|
||||
|
||||
// Deployment contains information about the host running Coder.
|
||||
|
@ -971,6 +987,10 @@ type ExternalProvisioner struct {
|
|||
ShutdownAt *time.Time `json:"shutdown_at"`
|
||||
}
|
||||
|
||||
type Experiment struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type noopReporter struct{}
|
||||
|
||||
func (*noopReporter) Report(_ *Snapshot) {}
|
||||
|
|
|
@ -85,7 +85,7 @@ func TestTelemetry(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
_, _ = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})
|
||||
|
||||
_, snapshot := collectSnapshot(t, db)
|
||||
_, snapshot := collectSnapshot(t, db, nil)
|
||||
require.Len(t, snapshot.ProvisionerJobs, 1)
|
||||
require.Len(t, snapshot.Licenses, 1)
|
||||
require.Len(t, snapshot.Templates, 1)
|
||||
|
@ -110,21 +110,32 @@ func TestTelemetry(t *testing.T) {
|
|||
_ = dbgen.User(t, db, database.User{
|
||||
Email: "kyle@coder.com",
|
||||
})
|
||||
_, snapshot := collectSnapshot(t, db)
|
||||
_, snapshot := collectSnapshot(t, db, nil)
|
||||
require.Len(t, snapshot.Users, 1)
|
||||
require.Equal(t, snapshot.Users[0].EmailHashed, "bb44bf07cf9a2db0554bba63a03d822c927deae77df101874496df5a6a3e896d@coder.com")
|
||||
})
|
||||
t.Run("Experiments", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const expName = "my-experiment"
|
||||
exps := []string{expName}
|
||||
_, snapshot := collectSnapshot(t, dbmem.New(), func(opts telemetry.Options) telemetry.Options {
|
||||
opts.Experiments = exps
|
||||
return opts
|
||||
})
|
||||
require.Equal(t, []telemetry.Experiment{{Name: expName}}, snapshot.Experiments)
|
||||
})
|
||||
}
|
||||
|
||||
// nolint:paralleltest
|
||||
func TestTelemetryInstallSource(t *testing.T) {
|
||||
t.Setenv("CODER_TELEMETRY_INSTALL_SOURCE", "aws_marketplace")
|
||||
db := dbmem.New()
|
||||
deployment, _ := collectSnapshot(t, db)
|
||||
deployment, _ := collectSnapshot(t, db, nil)
|
||||
require.Equal(t, "aws_marketplace", deployment.InstallSource)
|
||||
}
|
||||
|
||||
func collectSnapshot(t *testing.T, db database.Store) (*telemetry.Deployment, *telemetry.Snapshot) {
|
||||
func collectSnapshot(t *testing.T, db database.Store, addOptionsFn func(opts telemetry.Options) telemetry.Options) (*telemetry.Deployment, *telemetry.Snapshot) {
|
||||
t.Helper()
|
||||
deployment := make(chan *telemetry.Deployment, 64)
|
||||
snapshot := make(chan *telemetry.Snapshot, 64)
|
||||
|
@ -149,12 +160,17 @@ func collectSnapshot(t *testing.T, db database.Store) (*telemetry.Deployment, *t
|
|||
t.Cleanup(server.Close)
|
||||
serverURL, err := url.Parse(server.URL)
|
||||
require.NoError(t, err)
|
||||
reporter, err := telemetry.New(telemetry.Options{
|
||||
options := telemetry.Options{
|
||||
Database: db,
|
||||
Logger: slogtest.Make(t, nil).Leveled(slog.LevelDebug),
|
||||
URL: serverURL,
|
||||
DeploymentID: uuid.NewString(),
|
||||
})
|
||||
}
|
||||
if addOptionsFn != nil {
|
||||
options = addOptionsFn(options)
|
||||
}
|
||||
|
||||
reporter, err := telemetry.New(options)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(reporter.Close)
|
||||
return <-deployment, <-snapshot
|
||||
|
|
Loading…
Reference in New Issue