@@ -4,6 +4,11 @@ const { performance, constants, PerformanceObserver } = require('perf_hooks')
4
4
const { END_TIMESTAMP_LABEL , SPAN_ID_LABEL , LOCAL_ROOT_SPAN_ID_LABEL , encodeProfileAsync } = require ( './shared' )
5
5
const { Function, Label, Line, Location, Profile, Sample, StringTable, ValueType } = require ( 'pprof-format' )
6
6
const { availableParallelism, effectiveLibuvThreadCount } = require ( '../libuv-size' )
7
+ const dc = require ( 'dc-polyfill' )
8
+
9
+ const testEventChannel = [ 'true' , '1' ] . includes ( process . env . TESTING_PROFILING_EVENTS )
10
+ ? dc . channel ( 'dd-trace:profiling:events-test' )
11
+ : undefined
7
12
8
13
// perf_hooks uses millis, with fractional part representing nanos. We emit nanos into the pprof file.
9
14
const MS_TO_NS = 1_000_000
@@ -363,6 +368,27 @@ class DatadogInstrumentationEventSource {
363
368
}
364
369
}
365
370
371
+ class TestEventSource {
372
+ constructor ( eventHandler ) {
373
+ this . eventHandler = eventHandler
374
+ this . started = false
375
+ }
376
+
377
+ start ( ) {
378
+ if ( ! this . started ) {
379
+ testEventChannel . subscribe ( this . eventHandler )
380
+ this . started = true
381
+ }
382
+ }
383
+
384
+ stop ( ) {
385
+ if ( this . started ) {
386
+ testEventChannel . unsubscribe ( this . eventHandler )
387
+ this . started = false
388
+ }
389
+ }
390
+ }
391
+
366
392
class CompositeEventSource {
367
393
constructor ( sources ) {
368
394
this . sources = sources
@@ -430,15 +456,21 @@ class EventsProfiler {
430
456
}
431
457
}
432
458
433
- this . eventSource = options . codeHotspotsEnabled
459
+ const eventSources = options . codeHotspotsEnabled
434
460
// Use Datadog instrumentation to collect events with span IDs. Still use
435
461
// Node API for GC events.
436
- ? new CompositeEventSource ( [
437
- new DatadogInstrumentationEventSource ( eventHandler , eventFilter ) ,
438
- new NodeApiEventSource ( filteringEventHandler , [ 'gc' ] )
439
- ] )
462
+ ? [
463
+ new DatadogInstrumentationEventSource ( eventHandler , eventFilter ) ,
464
+ new NodeApiEventSource ( filteringEventHandler , [ 'gc' ] ) ,
465
+ ]
440
466
// Use Node API instrumentation to collect events without span IDs
441
- : new NodeApiEventSource ( filteringEventHandler )
467
+ : [
468
+ new NodeApiEventSource ( filteringEventHandler )
469
+ ]
470
+ if ( testEventChannel !== undefined ) {
471
+ eventSources . push ( new TestEventSource ( filteringEventHandler ) )
472
+ }
473
+ this . eventSource = new CompositeEventSource ( eventSources )
442
474
}
443
475
444
476
start ( ) {
@@ -461,6 +493,12 @@ class EventsProfiler {
461
493
encode ( profile ) {
462
494
return encodeProfileAsync ( profile ( ) )
463
495
}
496
+
497
+ static emitTestEvent ( event ) {
498
+ if ( testEventChannel !== undefined ) {
499
+ testEventChannel . publish ( event )
500
+ }
501
+ }
464
502
}
465
503
466
504
module . exports = EventsProfiler
0 commit comments