@@ -54,13 +54,17 @@ const COMMAND_SPAN_TARGET: &str = "COMMAND";
54
54
#[ cfg( feature = "tracing" ) ]
55
55
pub fn trace_cmd ( command : & crate :: BootstrapCommand ) -> tracing:: span:: EnteredSpan {
56
56
let fingerprint = command. fingerprint ( ) ;
57
+ let location = command. get_created_location ( ) ;
58
+ let location = format ! ( "{}:{}" , location. file( ) , location. line( ) ) ;
59
+
57
60
tracing:: span!(
58
61
target: COMMAND_SPAN_TARGET ,
59
62
tracing:: Level :: TRACE ,
60
63
"cmd" ,
61
64
cmd_name = fingerprint. program_name( ) . to_string( ) ,
62
65
cmd = fingerprint. format_short_cmd( ) ,
63
- full_cmd = ?command
66
+ full_cmd = ?command,
67
+ location
64
68
)
65
69
. entered ( )
66
70
}
@@ -269,33 +273,66 @@ mod inner {
269
273
}
270
274
}
271
275
272
- // We handle steps specially. We instrument them dynamically in `Builder::ensure`,
273
- // and we want to have custom name for each step span. But tracing doesn't allow setting
274
- // dynamic span names. So we detect step spans here and override their name.
275
- if span. metadata ( ) . target ( ) == STEP_SPAN_TARGET {
276
- let name = field_values. and_then ( |v| v. step_name . as_deref ( ) ) . unwrap_or ( span. name ( ) ) ;
277
- write ! ( writer, "{name}" ) ?;
278
-
279
- // There should be only one more field called `args`
280
- if let Some ( values) = field_values {
281
- let field = & values. fields [ 0 ] ;
282
- write ! ( writer, " {{{}}}" , field. 1 ) ?;
283
- }
284
- } else {
285
- write ! ( writer, "{}" , span. name( ) ) ?;
286
- if let Some ( values) = field_values. filter ( |v| !v. fields . is_empty ( ) ) {
276
+ fn write_fields < ' a , I : IntoIterator < Item = & ' a ( & ' a str , String ) > , W : Write > (
277
+ writer : & mut W ,
278
+ iter : I ,
279
+ ) -> std:: io:: Result < ( ) > {
280
+ let items = iter. into_iter ( ) . collect :: < Vec < _ > > ( ) ;
281
+ if !items. is_empty ( ) {
287
282
write ! ( writer, " [" ) ?;
288
- for ( index, ( name, value) ) in values . fields . iter ( ) . enumerate ( ) {
283
+ for ( index, ( name, value) ) in items . iter ( ) . enumerate ( ) {
289
284
write ! ( writer, "{name} = {value}" ) ?;
290
- if index < values . fields . len ( ) - 1 {
285
+ if index < items . len ( ) - 1 {
291
286
write ! ( writer, ", " ) ?;
292
287
}
293
288
}
294
289
write ! ( writer, "]" ) ?;
295
290
}
296
- } ;
291
+ Ok ( ( ) )
292
+ }
293
+
294
+ // We handle steps specially. We instrument them dynamically in `Builder::ensure`,
295
+ // and we want to have custom name for each step span. But tracing doesn't allow setting
296
+ // dynamic span names. So we detect step spans here and override their name.
297
+ match span. metadata ( ) . target ( ) {
298
+ // Executed step
299
+ STEP_SPAN_TARGET => {
300
+ let name =
301
+ field_values. and_then ( |v| v. step_name . as_deref ( ) ) . unwrap_or ( span. name ( ) ) ;
302
+ write ! ( writer, "{name}" ) ?;
303
+
304
+ // There should be only one more field called `args`
305
+ if let Some ( values) = field_values {
306
+ let field = & values. fields [ 0 ] ;
307
+ write ! ( writer, " {{{}}}" , field. 1 ) ?;
308
+ }
309
+ write_location ( writer, span. metadata ( ) ) ?;
310
+ }
311
+ // Executed command
312
+ COMMAND_SPAN_TARGET => {
313
+ write ! ( writer, "{}" , span. name( ) ) ?;
314
+ if let Some ( values) = field_values {
315
+ write_fields (
316
+ writer,
317
+ values. fields . iter ( ) . filter ( |( name, _) | * name != "location" ) ,
318
+ ) ?;
319
+ write ! (
320
+ writer,
321
+ " ({})" ,
322
+ values. fields. iter( ) . find( |( name, _) | * name == "location" ) . unwrap( ) . 1
323
+ ) ?;
324
+ }
325
+ }
326
+ // Other span
327
+ _ => {
328
+ write ! ( writer, "{}" , span. name( ) ) ?;
329
+ if let Some ( values) = field_values {
330
+ write_fields ( writer, values. fields . iter ( ) ) ?;
331
+ }
332
+ write_location ( writer, span. metadata ( ) ) ?;
333
+ }
334
+ }
297
335
298
- write_location ( writer, span. metadata ( ) ) ?;
299
336
writeln ! ( writer) ?;
300
337
Ok ( ( ) )
301
338
}
0 commit comments