@@ -40,7 +40,6 @@ func RunActions(ctx context.Context, cfg *config.GitteConfig, st *state.GitteSta
4040 view := newView (mode , infos , actionOrder , runCancel , retryCh , cfg .QuickSolve .GitClean .Exclude )
4141
4242 tracker := telemetry .NewActionTracker (ctx )
43- reg := telemetry .NewSpanRegistry ()
4443
4544 onStart := func (name string ) {
4645 tracker .OnStart (name )
@@ -72,7 +71,7 @@ func RunActions(ctx context.Context, cfg *config.GitteConfig, st *state.GitteSta
7271 var retrySet map [string ]struct {} // nil on first run
7372 var runErr error
7473 for {
75- tasks := buildExecutorTasks (cfg , st , cwd , keys , tracker , reg )
74+ tasks := buildExecutorTasks (cfg , st , cwd , keys , tracker )
7675
7776 // Strip needs from explicitly retried tasks so they run immediately.
7877 if retrySet != nil {
@@ -114,7 +113,7 @@ func RunActions(ctx context.Context, cfg *config.GitteConfig, st *state.GitteSta
114113 exec .WithPreCompleted (succeeded , failed )
115114 }
116115
117- exec .WithOutputHandler (telemetry . LogOutputHandler ( view .Handler (), reg ))
116+ exec .WithOutputHandler (view .Handler ())
118117 exec .WithRetryChannel (retryCh )
119118
120119 runErr = exec .Execute (runCtx )
@@ -208,7 +207,7 @@ func buildTaskInfos(cfg *config.GitteConfig, st *state.GitteState, cwd string, k
208207}
209208
210209// buildExecutorTasks constructs executor.Task list from keys.
211- func buildExecutorTasks (cfg * config.GitteConfig , st * state.GitteState , cwd string , keys []GroupKeyWithDeps , tracker * telemetry.ActionTracker , reg * telemetry. SpanRegistry ) []executor.Task {
210+ func buildExecutorTasks (cfg * config.GitteConfig , st * state.GitteState , cwd string , keys []GroupKeyWithDeps , tracker * telemetry.ActionTracker ) []executor.Task {
212211 tasks := make ([]executor.Task , 0 , len (keys ))
213212 searchFors := cfg .SearchFor
214213
@@ -253,7 +252,7 @@ func buildExecutorTasks(cfg *config.GitteConfig, st *state.GitteState, cwd strin
253252 Needs : needNames ,
254253 Retry : retryConfig ,
255254 ExecuteFn : func (ctx context.Context , tName string , handler executor.OutputHandler ) error {
256- return runGroupTask (ctx , cfg , st , cwd , proj , key .Project , tName , cmds , allSearchFors , handler , tracker , reg )
255+ return runGroupTask (ctx , cfg , st , cwd , proj , key .Project , tName , cmds , allSearchFors , handler , tracker )
257256 },
258257 })
259258 }
@@ -285,38 +284,28 @@ func runGroupTask(
285284 searchFors []config.SearchFor ,
286285 handler executor.OutputHandler ,
287286 tracker * telemetry.ActionTracker ,
288- reg * telemetry.SpanRegistry ,
289287) (err error ) {
290288 actionCtx := tracker .ActionContext (telemetry .ActionOf (taskName ))
291289 // Parent the task span under the action span, but keep running under the
292290 // executor's incoming (cancellable) context so cancellation still propagates
293291 // to the command — attach the span to ctx rather than replacing ctx.
294292 _ , span := telemetry .Tracer ().Start (actionCtx , "action.run " + taskName )
295293 ctx = trace .ContextWithSpan (ctx , span )
296- reg .Set (taskName , span .SpanContext ())
297- setActionAttrs (span , taskName , projName , strings .Join (cmds , " " ))
298- if feats := enabledFeaturesForProject (cfg , st , projName , proj ); len (feats ) > 0 {
299- span .SetAttributes (attribute .StringSlice ("gitte.features" , feats ))
300- }
301- if env := injectedEnv (cfg , st , projName , proj ); len (env ) > 0 {
302- keys := make ([]string , 0 , len (env ))
303- for k := range env {
304- keys = append (keys , k )
305- }
306- sort .Strings (keys )
307- kvs := make ([]string , 0 , len (keys ))
308- for _ , k := range keys {
309- kvs = append (kvs , k + "=" + env [k ])
310- }
311- span .SetAttributes (attribute .StringSlice ("gitte.env" , kvs ))
312- }
294+ handler = telemetry .LogOutputHandler (handler )
295+ setTaskTelemetryAttrs (span , cfg , st , projName , proj , taskName , cmds )
313296 defer func () {
297+ if recovered := recover (); recovered != nil {
298+ panicErr := fmt .Errorf ("panic: %v" , recovered )
299+ span .RecordError (panicErr )
300+ span .SetStatus (codes .Error , panicErr .Error ())
301+ span .End ()
302+ panic (recovered )
303+ }
314304 if err != nil {
315305 span .RecordError (err )
316306 span .SetStatus (codes .Error , err .Error ())
317307 }
318308 span .End ()
319- reg .Delete (taskName )
320309 }()
321310
322311 if len (cmds ) == 0 {
@@ -348,18 +337,51 @@ func runGroupTask(
348337 return err
349338 }
350339
351- span .SetAttributes (attribute .Int ("gitte.exit_code" , res .ExitCode ))
340+ if span .IsRecording () {
341+ span .SetAttributes (attribute .Int ("gitte.exit_code" , res .ExitCode ))
342+ if res .ExitCode != 0 {
343+ if tail := outputTail (res .Stderr , res .Stdout ); tail != "" {
344+ span .SetAttributes (attribute .String ("gitte.error_tail" , tail ))
345+ }
346+ }
347+ }
352348
353349 if res .ExitCode != 0 {
354- if tail := outputTail (res .Stderr , res .Stdout ); tail != "" {
355- span .SetAttributes (attribute .String ("gitte.error_tail" , tail ))
356- }
357350 return fmt .Errorf ("command exited with code %d" , res .ExitCode )
358351 }
359352
360353 return nil
361354}
362355
356+ func setTaskTelemetryAttrs (
357+ span trace.Span ,
358+ cfg * config.GitteConfig ,
359+ st * state.GitteState ,
360+ projName string ,
361+ proj config.ProjectConfig ,
362+ taskName string ,
363+ cmds []string ,
364+ ) {
365+ if span .IsRecording () {
366+ setActionAttrs (span , taskName , projName , strings .Join (cmds , " " ))
367+ if feats := enabledFeaturesForProject (cfg , st , projName , proj ); len (feats ) > 0 {
368+ span .SetAttributes (attribute .StringSlice ("gitte.features" , feats ))
369+ }
370+ if env := injectedEnv (cfg , st , projName , proj ); len (env ) > 0 {
371+ keys := make ([]string , 0 , len (env ))
372+ for k := range env {
373+ keys = append (keys , k )
374+ }
375+ sort .Strings (keys )
376+ kvs := make ([]string , 0 , len (keys ))
377+ for _ , k := range keys {
378+ kvs = append (kvs , k + "=" + env [k ])
379+ }
380+ span .SetAttributes (attribute .StringSlice ("gitte.env" , kvs ))
381+ }
382+ }
383+ }
384+
363385// errorTailBytes caps how much trailing command output is attached to a failed
364386// task span via the gitte.error_tail attribute.
365387const errorTailBytes = 4096
0 commit comments