@@ -19,6 +19,13 @@ type timingKind string
1919// Copied from https://github.com/hashicorp/terraform/blob/01c0480e77263933b2b086dc8d600a69f80fad2d/internal/command/jsonformat/renderer.go
2020// We cannot reference these because they're in an internal package.
2121const (
22+ // Stage markers are used to denote the beginning and end of stages. Without
23+ // these, only discrete events (i.e. resource changes) within stages can be
24+ // measured, which may omit setup/teardown time or other unmeasured overhead.
25+ timingStageStart timingKind = "stage_start"
26+ timingStageEnd timingKind = "stage_end"
27+ timingStageError timingKind = "stage_error"
28+
2229 timingApplyStart timingKind = "apply_start"
2330 timingApplyProgress timingKind = "apply_progress"
2431 timingApplyComplete timingKind = "apply_complete"
@@ -37,9 +44,6 @@ const (
3744 timingResourceDrift timingKind = "resource_drift"
3845 timingVersion timingKind = "version"
3946 // These are not part of message_types, but we want to track init/graph timings as well.
40- timingInitStart timingKind = "init_start"
41- timingInitComplete timingKind = "init_complete"
42- timingInitErrored timingKind = "init_errored"
4347 timingGraphStart timingKind = "graph_start"
4448 timingGraphComplete timingKind = "graph_complete"
4549 timingGraphErrored timingKind = "graph_errored"
@@ -109,13 +113,13 @@ func (t *timingAggregator) ingest(ts time.Time, s *timingSpan) {
109113 ts = dbtime .Time (ts .UTC ())
110114
111115 switch s .kind {
112- case timingApplyStart , timingProvisionStart , timingRefreshStart , timingInitStart , timingGraphStart :
116+ case timingApplyStart , timingProvisionStart , timingRefreshStart , timingGraphStart , timingStageStart :
113117 s .start = ts
114118 s .state = proto .TimingState_STARTED
115- case timingApplyComplete , timingProvisionComplete , timingRefreshComplete , timingInitComplete , timingGraphComplete :
119+ case timingApplyComplete , timingProvisionComplete , timingRefreshComplete , timingGraphComplete , timingStageEnd :
116120 s .end = ts
117121 s .state = proto .TimingState_COMPLETED
118- case timingApplyErrored , timingProvisionErrored , timingInitErrored , timingGraphErrored :
122+ case timingApplyErrored , timingProvisionErrored , timingGraphErrored , timingStageError :
119123 s .end = ts
120124 s .state = proto .TimingState_FAILED
121125 case timingInitOutput :
@@ -176,8 +180,35 @@ func (t *timingAggregator) aggregate() []*proto.Timing {
176180 return out
177181}
178182
183+ // startStage denotes the beginning of a stage and returns a function which
184+ // should be called to mark the end of the stage. This is used to measure a
185+ // stage's total duration across all it's discrete events and unmeasured
186+ // overhead/events.
187+ func (t * timingAggregator ) startStage (stage database.ProvisionerJobTimingStage ) (end func (err error )) {
188+ ts := timingSpan {
189+ kind : timingStageStart ,
190+ stage : stage ,
191+ resource : "coder_stage_" + string (stage ),
192+ action : "terraform" ,
193+ provider : "coder" ,
194+ }
195+ endTs := ts
196+ t .ingest (dbtime .Now (), & ts )
197+
198+ return func (err error ) {
199+ endTs .kind = timingStageEnd
200+ if err != nil {
201+ endTs .kind = timingStageError
202+ }
203+ t .ingest (dbtime .Now (), & endTs )
204+ }
205+ }
206+
179207func (l timingKind ) Valid () bool {
180208 return slices .Contains ([]timingKind {
209+ timingStageStart ,
210+ timingStageEnd ,
211+ timingStageError ,
181212 timingApplyStart ,
182213 timingApplyProgress ,
183214 timingApplyComplete ,
@@ -194,9 +225,6 @@ func (l timingKind) Valid() bool {
194225 timingOutputs ,
195226 timingResourceDrift ,
196227 timingVersion ,
197- timingInitStart ,
198- timingInitComplete ,
199- timingInitErrored ,
200228 timingGraphStart ,
201229 timingGraphComplete ,
202230 timingGraphErrored ,
@@ -210,7 +238,9 @@ func (l timingKind) Valid() bool {
210238// if all other attributes are identical.
211239func (l timingKind ) Category () string {
212240 switch l {
213- case timingInitStart , timingInitComplete , timingInitErrored , timingInitOutput :
241+ case timingStageStart , timingStageEnd , timingStageError :
242+ return "stage"
243+ case timingInitOutput :
214244 return "init"
215245 case timingGraphStart , timingGraphComplete , timingGraphErrored :
216246 return "graph"
@@ -252,15 +282,6 @@ func (e *timingSpan) toProto() *proto.Timing {
252282 }
253283}
254284
255- func createInitTimingsEvent (event timingKind ) (time.Time , * timingSpan ) {
256- return dbtime .Now (), & timingSpan {
257- kind : event ,
258- action : "initializing terraform" ,
259- provider : "terraform" ,
260- resource : "init" ,
261- }
262- }
263-
264285func createGraphTimingsEvent (event timingKind ) (time.Time , * timingSpan ) {
265286 return dbtime .Now (), & timingSpan {
266287 kind : event ,
0 commit comments