Skip to content

feat(coderd): add coder_app usage stats #9001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
befb4dc
feat(coderd): track `coder_app` usage
mafredri Aug 9, 2023
0bb672a
amend pr comments
mafredri Aug 10, 2023
1171a9d
refactor stats with rollups, add tests
mafredri Aug 10, 2023
858264a
add close
mafredri Aug 14, 2023
e8969d3
fix wsproxy endpoint auth todo
mafredri Aug 14, 2023
7dc4ff2
add backlog for re-reporting in case of failure
mafredri Aug 14, 2023
0561f8d
update dbauthz
mafredri Aug 14, 2023
59d69ac
use dbauthz.AsSystemRestricted for collector flush
mafredri Aug 14, 2023
97ef37b
add stats collection test to apptest
mafredri Aug 14, 2023
fda79c6
Merge branch 'main' into mafredri/feat-add-app-usage-to-template-insi…
mafredri Aug 14, 2023
8926dd0
fix migrations
mafredri Aug 14, 2023
1705138
update plumbing to fix wsproxy tests
mafredri Aug 14, 2023
d709e68
test the stat output in apptest
mafredri Aug 14, 2023
6ec178b
fix issues
mafredri Aug 14, 2023
7db34ba
fix id in dbfake
mafredri Aug 14, 2023
ca83430
fix gen
mafredri Aug 14, 2023
80b7ff3
Merge branch 'main' into mafredri/feat-add-app-usage-to-template-insi…
mafredri Aug 15, 2023
8039a4d
add fixture
mafredri Aug 15, 2023
7e2ec9f
use 15s timeout and timer reset
mafredri Aug 16, 2023
70f6249
pass now to rollup
mafredri Aug 16, 2023
5615e27
track last insert id in fakedb
mafredri Aug 16, 2023
9418abd
fix migration indentation
mafredri Aug 16, 2023
a032f8a
remove sqlc type alias
mafredri Aug 16, 2023
94563ef
defer collect stats
mafredri Aug 16, 2023
e27e905
remove stale comment
mafredri Aug 16, 2023
be67aef
preallocate batch slices
mafredri Aug 16, 2023
37d06e3
Merge branch 'main' into mafredri/feat-add-app-usage-to-template-insi…
mafredri Aug 16, 2023
c9272c5
lower log level to debug for start/stop
mafredri Aug 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ type Options struct {

UpdateAgentMetrics func(ctx context.Context, username, workspaceName, agentName string, metrics []agentsdk.AgentMetric)
StatsBatcher *batchstats.Batcher

WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
}

// @title Coder API
Expand Down Expand Up @@ -418,8 +420,17 @@ func New(options *Options) *API {
}
}

workspaceAppsLogger := options.Logger.Named("workspaceapps")
if options.WorkspaceAppsStatsCollectorOptions.Logger == nil {
named := workspaceAppsLogger.Named("stats_collector")
options.WorkspaceAppsStatsCollectorOptions.Logger = &named
}
if options.WorkspaceAppsStatsCollectorOptions.Reporter == nil {
options.WorkspaceAppsStatsCollectorOptions.Reporter = workspaceapps.NewStatsDBReporter(options.Database, workspaceapps.DefaultStatsDBReporterBatchSize)
}

api.workspaceAppServer = &workspaceapps.Server{
Logger: options.Logger.Named("workspaceapps"),
Logger: workspaceAppsLogger,

DashboardURL: api.AccessURL,
AccessURL: api.AccessURL,
Expand All @@ -430,6 +441,7 @@ func New(options *Options) *API {
SignedTokenProvider: api.WorkspaceAppsProvider,
AgentProvider: api.agentProvider,
AppSecurityKey: options.AppSecurityKey,
StatsCollector: workspaceapps.NewStatsCollector(options.WorkspaceAppsStatsCollectorOptions),

DisablePathApps: options.DeploymentValues.DisablePathApps.Value(),
SecureAuthCookie: options.DeploymentValues.SecureAuthCookie.Value(),
Expand Down Expand Up @@ -1020,6 +1032,7 @@ func (api *API) Close() error {
if api.updateChecker != nil {
api.updateChecker.Close()
}
_ = api.workspaceAppServer.Close()
coordinator := api.TailnetCoordinator.Load()
if coordinator != nil {
_ = (*coordinator).Close()
Expand Down
65 changes: 34 additions & 31 deletions coderd/coderdtest/coderdtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ type Options struct {
// as part of your test.
Logger *slog.Logger
StatsBatcher *batchstats.Batcher

WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
}

// New constructs a codersdk client connected to an in-memory API instance.
Expand Down Expand Up @@ -394,37 +396,38 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
Pubsub: options.Pubsub,
GitAuthConfigs: options.GitAuthConfigs,

Auditor: options.Auditor,
AWSCertificates: options.AWSCertificates,
AzureCertificates: options.AzureCertificates,
GithubOAuth2Config: options.GithubOAuth2Config,
RealIPConfig: options.RealIPConfig,
OIDCConfig: options.OIDCConfig,
GoogleTokenValidator: options.GoogleTokenValidator,
SSHKeygenAlgorithm: options.SSHKeygenAlgorithm,
DERPServer: derpServer,
APIRateLimit: options.APIRateLimit,
LoginRateLimit: options.LoginRateLimit,
FilesRateLimit: options.FilesRateLimit,
Authorizer: options.Authorizer,
Telemetry: telemetry.NewNoop(),
TemplateScheduleStore: &templateScheduleStore,
TLSCertificates: options.TLSCertificates,
TrialGenerator: options.TrialGenerator,
TailnetCoordinator: options.Coordinator,
BaseDERPMap: derpMap,
DERPMapUpdateFrequency: 150 * time.Millisecond,
MetricsCacheRefreshInterval: options.MetricsCacheRefreshInterval,
AgentStatsRefreshInterval: options.AgentStatsRefreshInterval,
DeploymentValues: options.DeploymentValues,
UpdateCheckOptions: options.UpdateCheckOptions,
SwaggerEndpoint: options.SwaggerEndpoint,
AppSecurityKey: AppSecurityKey,
SSHConfig: options.ConfigSSH,
HealthcheckFunc: options.HealthcheckFunc,
HealthcheckTimeout: options.HealthcheckTimeout,
HealthcheckRefresh: options.HealthcheckRefresh,
StatsBatcher: options.StatsBatcher,
Auditor: options.Auditor,
AWSCertificates: options.AWSCertificates,
AzureCertificates: options.AzureCertificates,
GithubOAuth2Config: options.GithubOAuth2Config,
RealIPConfig: options.RealIPConfig,
OIDCConfig: options.OIDCConfig,
GoogleTokenValidator: options.GoogleTokenValidator,
SSHKeygenAlgorithm: options.SSHKeygenAlgorithm,
DERPServer: derpServer,
APIRateLimit: options.APIRateLimit,
LoginRateLimit: options.LoginRateLimit,
FilesRateLimit: options.FilesRateLimit,
Authorizer: options.Authorizer,
Telemetry: telemetry.NewNoop(),
TemplateScheduleStore: &templateScheduleStore,
TLSCertificates: options.TLSCertificates,
TrialGenerator: options.TrialGenerator,
TailnetCoordinator: options.Coordinator,
BaseDERPMap: derpMap,
DERPMapUpdateFrequency: 150 * time.Millisecond,
MetricsCacheRefreshInterval: options.MetricsCacheRefreshInterval,
AgentStatsRefreshInterval: options.AgentStatsRefreshInterval,
DeploymentValues: options.DeploymentValues,
UpdateCheckOptions: options.UpdateCheckOptions,
SwaggerEndpoint: options.SwaggerEndpoint,
AppSecurityKey: AppSecurityKey,
SSHConfig: options.ConfigSSH,
HealthcheckFunc: options.HealthcheckFunc,
HealthcheckTimeout: options.HealthcheckTimeout,
HealthcheckRefresh: options.HealthcheckRefresh,
StatsBatcher: options.StatsBatcher,
WorkspaceAppsStatsCollectorOptions: options.WorkspaceAppsStatsCollectorOptions,
}
}

Expand Down
7 changes: 7 additions & 0 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,13 @@ func (q *querier) InsertWorkspaceApp(ctx context.Context, arg database.InsertWor
return q.db.InsertWorkspaceApp(ctx, arg)
}

func (q *querier) InsertWorkspaceAppStats(ctx context.Context, arg database.InsertWorkspaceAppStatsParams) error {
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
return err
}
return q.db.InsertWorkspaceAppStats(ctx, arg)
}

func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertWorkspaceBuildParams) error {
w, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
if err != nil {
Expand Down
Loading