@@ -7,7 +7,7 @@ const { HTTP_METHOD, HTTP_ROUTE, RESOURCE_NAME, SPAN_TYPE } = require('../../../
7
7
const { WEB } = require ( '../../../../../ext/types' )
8
8
const runtimeMetrics = require ( '../../runtime_metrics' )
9
9
const telemetryMetrics = require ( '../../telemetry/metrics' )
10
- const { END_TIMESTAMP_LABEL , getThreadLabels } = require ( './shared' )
10
+ const { END_TIMESTAMP_LABEL , getNonJSThreadsLabels , getThreadLabels } = require ( './shared' )
11
11
12
12
const beforeCh = dc . channel ( 'dd-trace:storage:before' )
13
13
const enterCh = dc . channel ( 'dd-trace:storage:enter' )
@@ -78,13 +78,15 @@ class NativeWallProfiler {
78
78
this . _codeHotspotsEnabled = ! ! options . codeHotspotsEnabled
79
79
this . _endpointCollectionEnabled = ! ! options . endpointCollectionEnabled
80
80
this . _timelineEnabled = ! ! options . timelineEnabled
81
+ this . _cpuProfilingEnabled = ! ! options . cpuProfilingEnabled
81
82
// We need to capture span data into the sample context for either code hotspots
82
83
// or endpoint collection.
83
84
this . _captureSpanData = this . _codeHotspotsEnabled || this . _endpointCollectionEnabled
84
85
// We need to run the pprof wall profiler with sample contexts if we're either
85
86
// capturing span data or timeline is enabled (so we need sample timestamps, and for now
86
- // timestamps require the sample contexts feature in the pprof wall profiler.)
87
- this . _withContexts = this . _captureSpanData || this . _timelineEnabled
87
+ // timestamps require the sample contexts feature in the pprof wall profiler), or
88
+ // cpu profiling is enabled.
89
+ this . _withContexts = this . _captureSpanData || this . _timelineEnabled || this . _cpuProfilingEnabled
88
90
this . _v8ProfilerBugWorkaroundEnabled = ! ! options . v8ProfilerBugWorkaroundEnabled
89
91
this . _mapper = undefined
90
92
this . _pprof = undefined
@@ -131,7 +133,8 @@ class NativeWallProfiler {
131
133
sourceMapper : this . _mapper ,
132
134
withContexts : this . _withContexts ,
133
135
lineNumbers : false ,
134
- workaroundV8Bug : this . _v8ProfilerBugWorkaroundEnabled
136
+ workaroundV8Bug : this . _v8ProfilerBugWorkaroundEnabled ,
137
+ collectCpuTime : this . _cpuProfilingEnabled
135
138
} )
136
139
137
140
if ( this . _withContexts ) {
@@ -220,22 +223,42 @@ class NativeWallProfiler {
220
223
221
224
_stop ( restart ) {
222
225
if ( ! this . _started ) return
226
+
223
227
if ( this . _captureSpanData ) {
224
228
// update last sample context if needed
225
229
this . _enter ( )
226
230
this . _lastSampleCount = 0
227
231
}
228
232
const profile = this . _pprof . time . stop ( restart , this . _generateLabels )
233
+
229
234
if ( restart ) {
230
235
const v8BugDetected = this . _pprof . time . v8ProfilerStuckEventLoopDetected ( )
231
236
if ( v8BugDetected !== 0 ) {
232
237
this . _reportV8bug ( v8BugDetected === 1 )
233
238
}
239
+ } else {
240
+ if ( this . _captureSpanData ) {
241
+ beforeCh . unsubscribe ( this . _enter )
242
+ enterCh . unsubscribe ( this . _enter )
243
+ spanFinishCh . unsubscribe ( this . _spanFinished )
244
+ this . _profilerState = undefined
245
+ this . _lastSpan = undefined
246
+ this . _lastStartedSpans = undefined
247
+ this . _lastWebTags = undefined
248
+ }
249
+ this . _started = false
234
250
}
251
+
235
252
return profile
236
253
}
237
254
238
- _generateLabels ( context ) {
255
+ _generateLabels ( { node, context } ) {
256
+ // check for special node that represents CPU time all non-JS threads.
257
+ // In that case only return a special thread name label since we cannot associate any timestamp/span/endpoint to it.
258
+ if ( node . name === this . _pprof . time . constants . NON_JS_THREADS_FUNCTION_NAME ) {
259
+ return getNonJSThreadsLabels ( )
260
+ }
261
+
239
262
if ( context == null ) {
240
263
// generateLabels is also called for samples without context.
241
264
// In that case just return thread labels.
@@ -267,30 +290,20 @@ class NativeWallProfiler {
267
290
return labels
268
291
}
269
292
270
- profile ( ) {
271
- return this . _stop ( true )
293
+ profile ( restart ) {
294
+ return this . _stop ( restart )
272
295
}
273
296
274
297
encode ( profile ) {
275
298
return this . _pprof . encode ( profile )
276
299
}
277
300
278
301
stop ( ) {
279
- if ( ! this . _started ) return
280
-
281
- const profile = this . _stop ( false )
282
- if ( this . _captureSpanData ) {
283
- beforeCh . unsubscribe ( this . _enter )
284
- enterCh . unsubscribe ( this . _enter )
285
- spanFinishCh . unsubscribe ( this . _spanFinished )
286
- this . _profilerState = undefined
287
- this . _lastSpan = undefined
288
- this . _lastStartedSpans = undefined
289
- this . _lastWebTags = undefined
290
- }
302
+ this . _stop ( false )
303
+ }
291
304
292
- this . _started = false
293
- return profile
305
+ isStarted ( ) {
306
+ return this . _started
294
307
}
295
308
}
296
309
0 commit comments