@@ -44,6 +44,7 @@ import (
44
44
type metrics struct {
45
45
BackupWaitingTimeHist prometheus.Histogram
46
46
BackupWaitingTimeoutCounter prometheus.Counter
47
+ InitializerHistogram prometheus.HistogramVec
47
48
}
48
49
49
50
// WorkspaceService implements the InitService and WorkspaceService
@@ -108,6 +109,17 @@ func NewWorkspaceService(ctx context.Context, cfg Config, kubernetesNamespace st
108
109
return nil , xerrors .Errorf ("cannot register Prometheus counter for backup waiting timeouts: %w" , err )
109
110
}
110
111
112
+ initializerHistogram := prometheus .NewHistogramVec (prometheus.HistogramOpts {
113
+ Name : "initializer_bytes_second" ,
114
+ Help : "initializer speed in bytes per second" ,
115
+ Buckets : prometheus .ExponentialBuckets (1024 * 1024 , 2 , 15 ),
116
+ }, []string {"kind" })
117
+
118
+ err = reg .Register (initializerHistogram )
119
+ if err != nil {
120
+ return nil , xerrors .Errorf ("cannot register Prometheus counter for initializer speed per second: %w" , err )
121
+ }
122
+
111
123
return & WorkspaceService {
112
124
config : cfg ,
113
125
store : store ,
@@ -118,6 +130,7 @@ func NewWorkspaceService(ctx context.Context, cfg Config, kubernetesNamespace st
118
130
metrics : & metrics {
119
131
BackupWaitingTimeHist : waitingTimeHist ,
120
132
BackupWaitingTimeoutCounter : waitingTimeoutCounter ,
133
+ InitializerHistogram : * initializerHistogram ,
121
134
},
122
135
// we permit five concurrent backups at any given time, hence the five in the channel
123
136
backupWorkspaceLimiter : make (chan struct {}, 5 ),
@@ -282,6 +295,8 @@ func (s *WorkspaceService) InitWorkspace(ctx context.Context, req *api.InitWorks
282
295
log .WithError (err ).WithField ("workspaceId" , req .Id ).Error ("cannot initialize workspace" )
283
296
return nil , status .Error (codes .FailedPrecondition , err .Error ())
284
297
}
298
+
299
+ s .recordInitializerMetrics (workspace .Location )
285
300
}
286
301
287
302
if req .PersistentVolumeClaim {
@@ -310,6 +325,27 @@ func (s *WorkspaceService) InitWorkspace(ctx context.Context, req *api.InitWorks
310
325
return & api.InitWorkspaceResponse {}, nil
311
326
}
312
327
328
+ func (s * WorkspaceService ) recordInitializerMetrics (path string ) {
329
+ readyFile := filepath .Join (path , wsinit .WorkspaceReadyFile )
330
+
331
+ content , err := os .ReadFile (readyFile )
332
+ if err != nil {
333
+ log .WithError (err ).Errorf ("could not find ready file at %v" , readyFile )
334
+ return
335
+ }
336
+
337
+ var ready csapi.WorkspaceReadyMessage
338
+ err = json .Unmarshal (content , & ready )
339
+ if err != nil {
340
+ log .WithError (err ).Error ("could not unmarshal ready" )
341
+ return
342
+ }
343
+
344
+ for _ , m := range ready .Metrics {
345
+ s .metrics .InitializerHistogram .WithLabelValues (m .Type ).Observe (float64 (m .Size ) / m .Duration .Seconds ())
346
+ }
347
+ }
348
+
313
349
func (s * WorkspaceService ) creator (req * api.InitWorkspaceRequest ) session.WorkspaceFactory {
314
350
var checkoutLocation string
315
351
allLocations := csapi .GetCheckoutLocationsFromInitializer (req .Initializer )
0 commit comments