Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbc83de2

Browse files
authored
feat: add prebuilt workspaces telemetry (#18084)
Adds telemetry for a _global_ account of prebuilt workspaces created,failed to build, and claimed.Partitioning this data by template/preset tuple is not currently inscope.---------Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent69c9006 commitbc83de2

File tree

3 files changed

+173
-1
lines changed

3 files changed

+173
-1
lines changed

‎cli/server.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
864864
BuiltinPostgres:builtinPostgres,
865865
DeploymentID:deploymentID,
866866
Database:options.Database,
867+
Experiments:coderd.ReadExperiments(options.Logger,options.DeploymentValues.Experiments.Value()),
867868
Logger:logger.Named("telemetry"),
868869
URL:vals.Telemetry.URL.Value(),
869870
Tunnel:tunnel!=nil,

‎coderd/telemetry/telemetry.go‎

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"google.golang.org/protobuf/types/known/wrapperspb"
2929

3030
"cdr.dev/slog"
31+
3132
"github.com/coder/coder/v2/buildinfo"
3233
clitelemetry"github.com/coder/coder/v2/cli/telemetry"
3334
"github.com/coder/coder/v2/coderd/database"
@@ -47,7 +48,8 @@ type Options struct {
4748
Database database.Store
4849
Logger slog.Logger
4950
// URL is an endpoint to direct telemetry towards!
50-
URL*url.URL
51+
URL*url.URL
52+
Experiments codersdk.Experiments
5153

5254
DeploymentIDstring
5355
DeploymentConfig*codersdk.DeploymentValues
@@ -683,6 +685,52 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
683685
}
684686
returnnil
685687
})
688+
eg.Go(func()error {
689+
if!r.options.Experiments.Enabled(codersdk.ExperimentWorkspacePrebuilds) {
690+
returnnil
691+
}
692+
693+
metrics,err:=r.options.Database.GetPrebuildMetrics(ctx)
694+
iferr!=nil {
695+
returnxerrors.Errorf("get prebuild metrics: %w",err)
696+
}
697+
698+
vartotalCreated,totalFailed,totalClaimedint64
699+
for_,metric:=rangemetrics {
700+
totalCreated+=metric.CreatedCount
701+
totalFailed+=metric.FailedCount
702+
totalClaimed+=metric.ClaimedCount
703+
}
704+
705+
snapshot.PrebuiltWorkspaces=make([]PrebuiltWorkspace,0,3)
706+
now:=dbtime.Now()
707+
708+
iftotalCreated>0 {
709+
snapshot.PrebuiltWorkspaces=append(snapshot.PrebuiltWorkspaces,PrebuiltWorkspace{
710+
ID:uuid.New(),
711+
CreatedAt:now,
712+
EventType:PrebuiltWorkspaceEventTypeCreated,
713+
Count:int(totalCreated),
714+
})
715+
}
716+
iftotalFailed>0 {
717+
snapshot.PrebuiltWorkspaces=append(snapshot.PrebuiltWorkspaces,PrebuiltWorkspace{
718+
ID:uuid.New(),
719+
CreatedAt:now,
720+
EventType:PrebuiltWorkspaceEventTypeFailed,
721+
Count:int(totalFailed),
722+
})
723+
}
724+
iftotalClaimed>0 {
725+
snapshot.PrebuiltWorkspaces=append(snapshot.PrebuiltWorkspaces,PrebuiltWorkspace{
726+
ID:uuid.New(),
727+
CreatedAt:now,
728+
EventType:PrebuiltWorkspaceEventTypeClaimed,
729+
Count:int(totalClaimed),
730+
})
731+
}
732+
returnnil
733+
})
686734

687735
err:=eg.Wait()
688736
iferr!=nil {
@@ -1152,6 +1200,7 @@ type Snapshot struct {
11521200
Organizations []Organization`json:"organizations"`
11531201
TelemetryItems []TelemetryItem`json:"telemetry_items"`
11541202
UserTailnetConnections []UserTailnetConnection`json:"user_tailnet_connections"`
1203+
PrebuiltWorkspaces []PrebuiltWorkspace`json:"prebuilt_workspaces"`
11551204
}
11561205

11571206
// Deployment contains information about the host running Coder.
@@ -1724,6 +1773,21 @@ type UserTailnetConnection struct {
17241773
CoderDesktopVersion*string`json:"coder_desktop_version"`
17251774
}
17261775

1776+
typePrebuiltWorkspaceEventTypestring
1777+
1778+
const (
1779+
PrebuiltWorkspaceEventTypeCreatedPrebuiltWorkspaceEventType="created"
1780+
PrebuiltWorkspaceEventTypeFailedPrebuiltWorkspaceEventType="failed"
1781+
PrebuiltWorkspaceEventTypeClaimedPrebuiltWorkspaceEventType="claimed"
1782+
)
1783+
1784+
typePrebuiltWorkspacestruct {
1785+
ID uuid.UUID`json:"id"`
1786+
CreatedAt time.Time`json:"created_at"`
1787+
EventTypePrebuiltWorkspaceEventType`json:"event_type"`
1788+
Countint`json:"count"`
1789+
}
1790+
17271791
typenoopReporterstruct{}
17281792

17291793
func (*noopReporter)Report(_*Snapshot) {}

‎coderd/telemetry/telemetry_test.go‎

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,113 @@ func TestTelemetryItem(t *testing.T) {
370370
require.Equal(t,item.Value,"new_value")
371371
}
372372

373+
funcTestPrebuiltWorkspacesTelemetry(t*testing.T) {
374+
t.Parallel()
375+
ctx:=testutil.Context(t,testutil.WaitMedium)
376+
db,_:=dbtestutil.NewDB(t)
377+
378+
cases:= []struct {
379+
namestring
380+
experimentEnabledbool
381+
storeFnfunc(store database.Store) database.Store
382+
expectedSnapshotEntriesint
383+
expectedCreatedint
384+
expectedFailedint
385+
expectedClaimedint
386+
}{
387+
{
388+
name:"experiment enabled",
389+
experimentEnabled:true,
390+
storeFn:func(store database.Store) database.Store {
391+
return&mockDB{Store:store}
392+
},
393+
expectedSnapshotEntries:3,
394+
expectedCreated:5,
395+
expectedFailed:2,
396+
expectedClaimed:3,
397+
},
398+
{
399+
name:"experiment enabled, prebuilds not used",
400+
experimentEnabled:true,
401+
storeFn:func(store database.Store) database.Store {
402+
return&emptyMockDB{Store:store}
403+
},
404+
},
405+
{
406+
name:"experiment disabled",
407+
experimentEnabled:false,
408+
storeFn:func(store database.Store) database.Store {
409+
return&mockDB{Store:store}
410+
},
411+
},
412+
}
413+
414+
for_,tc:=rangecases {
415+
t.Run(tc.name,func(t*testing.T) {
416+
t.Parallel()
417+
418+
deployment,snapshot:=collectSnapshot(ctx,t,db,func(opts telemetry.Options) telemetry.Options {
419+
opts.Database=tc.storeFn(db)
420+
iftc.experimentEnabled {
421+
opts.Experiments= codersdk.Experiments{
422+
codersdk.ExperimentWorkspacePrebuilds,
423+
}
424+
}
425+
returnopts
426+
})
427+
428+
require.NotNil(t,deployment)
429+
require.NotNil(t,snapshot)
430+
431+
require.Len(t,snapshot.PrebuiltWorkspaces,tc.expectedSnapshotEntries)
432+
433+
eventCounts:=make(map[telemetry.PrebuiltWorkspaceEventType]int)
434+
for_,event:=rangesnapshot.PrebuiltWorkspaces {
435+
eventCounts[event.EventType]=event.Count
436+
require.NotEqual(t,uuid.Nil,event.ID)
437+
require.False(t,event.CreatedAt.IsZero())
438+
}
439+
440+
require.Equal(t,tc.expectedCreated,eventCounts[telemetry.PrebuiltWorkspaceEventTypeCreated])
441+
require.Equal(t,tc.expectedFailed,eventCounts[telemetry.PrebuiltWorkspaceEventTypeFailed])
442+
require.Equal(t,tc.expectedClaimed,eventCounts[telemetry.PrebuiltWorkspaceEventTypeClaimed])
443+
})
444+
}
445+
}
446+
447+
typemockDBstruct {
448+
database.Store
449+
}
450+
451+
func (*mockDB)GetPrebuildMetrics(context.Context) ([]database.GetPrebuildMetricsRow,error) {
452+
return []database.GetPrebuildMetricsRow{
453+
{
454+
TemplateName:"template1",
455+
PresetName:"preset1",
456+
OrganizationName:"org1",
457+
CreatedCount:3,
458+
FailedCount:1,
459+
ClaimedCount:2,
460+
},
461+
{
462+
TemplateName:"template2",
463+
PresetName:"preset2",
464+
OrganizationName:"org1",
465+
CreatedCount:2,
466+
FailedCount:1,
467+
ClaimedCount:1,
468+
},
469+
},nil
470+
}
471+
472+
typeemptyMockDBstruct {
473+
database.Store
474+
}
475+
476+
func (*emptyMockDB)GetPrebuildMetrics(context.Context) ([]database.GetPrebuildMetricsRow,error) {
477+
return []database.GetPrebuildMetricsRow{},nil
478+
}
479+
373480
funcTestShouldReportTelemetryDisabled(t*testing.T) {
374481
t.Parallel()
375482
// Description | telemetryEnabled (db) | telemetryEnabled (is) | Report Telemetry Disabled |

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp