@@ -54,13 +54,17 @@ const COMMAND_SPAN_TARGET: &str = "COMMAND";
5454#[ cfg( feature = "tracing" ) ]
5555pub fn trace_cmd ( command : & crate :: BootstrapCommand ) -> tracing:: span:: EnteredSpan {
5656 let fingerprint = command. fingerprint ( ) ;
57+ let location = command. get_created_location ( ) ;
58+ let location = format ! ( "{}:{}" , location. file( ) , location. line( ) ) ;
59+
5760 tracing:: span!(
5861 target: COMMAND_SPAN_TARGET ,
5962 tracing:: Level :: TRACE ,
6063 "cmd" ,
6164 cmd_name = fingerprint. program_name( ) . to_string( ) ,
6265 cmd = fingerprint. format_short_cmd( ) ,
63- full_cmd = ?command
66+ full_cmd = ?command,
67+ location
6468 )
6569 . entered ( )
6670}
@@ -269,33 +273,66 @@ mod inner {
269273 }
270274 }
271275
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 ( ) {
287282 write ! ( writer, " [" ) ?;
288- for ( index, ( name, value) ) in values . fields . iter ( ) . enumerate ( ) {
283+ for ( index, ( name, value) ) in items . iter ( ) . enumerate ( ) {
289284 write ! ( writer, "{name} = {value}" ) ?;
290- if index < values . fields . len ( ) - 1 {
285+ if index < items . len ( ) - 1 {
291286 write ! ( writer, ", " ) ?;
292287 }
293288 }
294289 write ! ( writer, "]" ) ?;
295290 }
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+ }
297335
298- write_location ( writer, span. metadata ( ) ) ?;
299336 writeln ! ( writer) ?;
300337 Ok ( ( ) )
301338 }
0 commit comments