@@ -15,6 +15,7 @@ import { withTelemetryContext } from '../../../shared/telemetry/util'
1515import { SinonSandbox } from 'sinon'
1616import sinon from 'sinon'
1717import { stubPerformance } from '../../utilities/performance'
18+ import * as crypto from '../../../shared/crypto'
1819
1920describe ( 'TelemetrySpan' , function ( ) {
2021 let clock : ReturnType < typeof installFakeClock >
@@ -291,7 +292,17 @@ describe('TelemetryTracer', function () {
291292 } )
292293
293294 describe ( 'nested run()' , function ( ) {
295+ let uuidStub : sinon . SinonStub
294296 const nestedName = 'nested_metric' as MetricName
297+ const testId = 'foo-foo-foo-foo-foo'
298+ const flowName = 'testTraceFlow'
299+
300+ beforeEach ( ( ) => {
301+ uuidStub = sandbox . stub ( crypto , 'randomUUID' )
302+
303+ // in the first call we set the trace id in subsequent calls we get the span ids
304+ uuidStub . returns ( testId )
305+ } )
295306
296307 it ( 'can record metadata in nested spans' , function ( ) {
297308 tracer . run ( metricName , ( span1 ) => {
@@ -310,18 +321,18 @@ describe('TelemetryTracer', function () {
310321 it ( 'removes spans when exiting an execution context' , function ( ) {
311322 tracer . run ( metricName , ( ) => {
312323 tracer . run ( nestedName , ( ) => {
313- assert . strictEqual ( tracer . spans . length , 2 )
324+ assert . strictEqual ( tracer . spans . length , 3 )
314325 } )
315326
316- assert . strictEqual ( tracer . spans . length , 1 )
327+ assert . strictEqual ( tracer . spans . length , 2 )
317328 } )
318329 } )
319330
320331 it ( 'adds spans during a nested execution, closing them when after' , function ( ) {
321332 tracer . run ( metricName , ( ) => {
322- tracer . run ( nestedName , ( ) => assert . strictEqual ( tracer . spans . length , 2 ) )
323- tracer . run ( nestedName , ( ) => assert . strictEqual ( tracer . spans . length , 2 ) )
324- assert . strictEqual ( tracer . spans . length , 1 )
333+ tracer . run ( nestedName , ( ) => assert . strictEqual ( tracer . spans . length , 3 ) )
334+ tracer . run ( nestedName , ( ) => assert . strictEqual ( tracer . spans . length , 3 ) )
335+ assert . strictEqual ( tracer . spans . length , 2 )
325336 } )
326337
327338 assert . strictEqual ( tracer . spans . length , 0 )
@@ -330,16 +341,102 @@ describe('TelemetryTracer', function () {
330341 it ( 'supports nesting the same event name' , function ( ) {
331342 tracer . run ( metricName , ( ) => {
332343 tracer . run ( metricName , ( ) => {
333- assert . strictEqual ( tracer . spans . length , 2 )
334- assert . ok ( tracer . spans . every ( ( s ) => s . name === metricName ) )
344+ assert . strictEqual ( tracer . spans . length , 3 )
345+ assert . ok ( tracer . spans . filter ( ( m ) => m . name !== 'root' ) . every ( ( s ) => s . name === metricName ) )
335346 } )
336347 } )
337348 } )
338349
339- it ( 'attaches the parent event name to the child span' , function ( ) {
350+ it ( 'attaches the parent id to the child span' , function ( ) {
340351 tracer . run ( metricName , ( ) => tracer . run ( nestedName , ( ) => { } ) )
341352 assertTelemetry ( metricName , { result : 'Succeeded' } )
342- assertTelemetry ( nestedName , { result : 'Succeeded' , parentMetric : metricName } as any )
353+ assertTelemetry ( nestedName , { result : 'Succeeded' , parentId : testId } as any )
354+ } )
355+
356+ it ( 'should set trace id' , function ( ) {
357+ telemetry . trace_event . run ( ( span ) => {
358+ span . record ( { name : flowName } )
359+ assert . deepStrictEqual ( telemetry . activeSpan ?. getMetricId ( ) , testId )
360+ } )
361+ const event = getMetrics ( 'trace_event' )
362+ assert . deepStrictEqual ( event [ 0 ] . traceId , testId )
363+ assert . deepStrictEqual ( event [ 0 ] . name , 'testTraceFlow' )
364+ } )
365+
366+ it ( 'trace id is propogated to children' , function ( ) {
367+ const metricsIds = {
368+ trace_event : {
369+ metricId : 'traceEvent' ,
370+ traceId : testId ,
371+ parentId : undefined ,
372+ } ,
373+ amazonq_startConversation : {
374+ metricId : 'amazonq_startConversation' ,
375+ traceId : testId ,
376+ parentId : 'traceEvent' ,
377+ } ,
378+ amazonq_addMessage : {
379+ metricId : 'amazonq_addMessage' ,
380+ traceId : testId ,
381+ parentId : 'amazonq_startConversation' ,
382+ } ,
383+ vscode_executeCommand : {
384+ metricId : 'vscode_executeCommand' ,
385+ traceId : testId ,
386+ parentId : 'traceEvent' ,
387+ } ,
388+ amazonq_enterFocusConversation : {
389+ metricId : 'amazonq_enterFocusConversation' ,
390+ traceId : testId ,
391+ parentId : 'vscode_executeCommand' ,
392+ } ,
393+ amazonq_exitFocusConversation : {
394+ metricId : 'amazonq_exitFocusConversation' ,
395+ traceId : testId ,
396+ parentId : 'amazonq_enterFocusConversation' ,
397+ } ,
398+ amazonq_closeChat : {
399+ metricId : 'amazonq_closeChat' ,
400+ traceId : testId ,
401+ parentId : 'traceEvent' ,
402+ } ,
403+ }
404+
405+ /**
406+ * randomUUID calls:
407+ * The first is called on the root event that never gets emitted
408+ * The second is called when generating the traceId
409+ * The rest are called when generating the spanIds
410+ */
411+ uuidStub . onCall ( 1 ) . returns ( testId )
412+ let index = 2
413+ for ( const v of Object . values ( metricsIds ) ) {
414+ uuidStub . onCall ( index ) . returns ( v . metricId )
415+ index ++
416+ }
417+
418+ telemetry . trace_event . run ( ( ) => {
419+ telemetry . amazonq_startConversation . run ( ( ) => {
420+ telemetry . amazonq_addMessage . run ( ( ) => { } )
421+ } )
422+ telemetry . vscode_executeCommand . run ( ( ) => {
423+ telemetry . amazonq_enterFocusConversation . run ( ( ) => {
424+ telemetry . amazonq_exitFocusConversation . run ( ( ) => { } )
425+ } )
426+ } )
427+ telemetry . amazonq_closeChat . emit ( {
428+ result : 'Succeeded' ,
429+ } )
430+ } )
431+
432+ const spanEntries = Object . entries ( metricsIds )
433+ for ( let x = 0 ; x < spanEntries . length ; x ++ ) {
434+ const [ metricName , { metricId, traceId, parentId } ] = spanEntries [ x ]
435+ const metric = getMetrics ( metricName as keyof MetricShapes ) [ 0 ] as any
436+ assert . deepStrictEqual ( metric . traceId , traceId )
437+ assert . deepStrictEqual ( metric . metricId , metricId )
438+ assert . deepStrictEqual ( metric . parentId , parentId )
439+ }
343440 } )
344441 } )
345442
0 commit comments