feat(coderd): add coder_app usage stats (#9001)

Updates #8658
This commit is contained in:
Mathias Fredriksson
2023-08-16 15:22:00 +03:00
committed by GitHub
parent f3c707648c
commit 6fd9975aed
31 changed files with 1730 additions and 62 deletions
+21
View File
@@ -0,0 +1,21 @@
package wsproxy
import (
"context"
"github.com/coder/coder/coderd/workspaceapps"
"github.com/coder/coder/enterprise/wsproxy/wsproxysdk"
)
var _ workspaceapps.StatsReporter = (*appStatsReporter)(nil)
type appStatsReporter struct {
Client *wsproxysdk.Client
}
func (r *appStatsReporter) Report(ctx context.Context, stats []workspaceapps.StatsReport) error {
err := r.Client.ReportAppStats(ctx, wsproxysdk.ReportAppStatsRequest{
Stats: stats,
})
return err
}
+15 -2
View File
@@ -79,6 +79,8 @@ type Options struct {
// By default, CORs is set to accept external requests
// from the dashboardURL. This should only be used in development.
AllowAllCors bool
StatsCollectorOptions workspaceapps.StatsCollectorOptions
}
func (o *Options) Validate() error {
@@ -262,8 +264,17 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
}
}
workspaceAppsLogger := opts.Logger.Named("workspaceapps")
if opts.StatsCollectorOptions.Logger == nil {
named := workspaceAppsLogger.Named("stats_collector")
opts.StatsCollectorOptions.Logger = &named
}
if opts.StatsCollectorOptions.Reporter == nil {
opts.StatsCollectorOptions.Reporter = &appStatsReporter{Client: client}
}
s.AppServer = &workspaceapps.Server{
Logger: opts.Logger.Named("workspaceapps"),
Logger: workspaceAppsLogger,
DashboardURL: opts.DashboardURL,
AccessURL: opts.AccessURL,
Hostname: opts.AppHostname,
@@ -279,9 +290,11 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
},
AppSecurityKey: secKey,
AgentProvider: agentProvider,
DisablePathApps: opts.DisablePathApps,
SecureAuthCookie: opts.SecureAuthCookie,
AgentProvider: agentProvider,
StatsCollector: workspaceapps.NewStatsCollector(opts.StatsCollectorOptions),
}
derpHandler := derphttp.Handler(derpServer)
+2
View File
@@ -478,6 +478,7 @@ func TestWorkspaceProxyWorkspaceApps_Wsconncache(t *testing.T) {
"CF-Connecting-IP",
},
},
WorkspaceAppsStatsCollectorOptions: opts.StatsCollectorOptions,
},
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
@@ -536,6 +537,7 @@ func TestWorkspaceProxyWorkspaceApps_SingleTailnet(t *testing.T) {
"CF-Connecting-IP",
},
},
WorkspaceAppsStatsCollectorOptions: opts.StatsCollectorOptions,
},
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
@@ -152,6 +152,25 @@ func (c *Client) IssueSignedAppTokenHTML(ctx context.Context, rw http.ResponseWr
return res, true
}
type ReportAppStatsRequest struct {
Stats []workspaceapps.StatsReport `json:"stats"`
}
// ReportAppStats reports the given app stats to the primary coder server.
func (c *Client) ReportAppStats(ctx context.Context, req ReportAppStatsRequest) error {
resp, err := c.Request(ctx, http.MethodPost, "/api/v2/workspaceproxies/me/app-stats", req)
if err != nil {
return xerrors.Errorf("make request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return codersdk.ReadBodyAsError(resp)
}
return nil
}
type RegisterWorkspaceProxyRequest struct {
// AccessURL that hits the workspace proxy api.
AccessURL string `json:"access_url"`