diff --git a/integration-tests/profiler/profiler.spec.js b/integration-tests/profiler/profiler.spec.js index 990d3e3aaa5..a3a02d69806 100644 --- a/integration-tests/profiler/profiler.spec.js +++ b/integration-tests/profiler/profiler.spec.js @@ -749,11 +749,13 @@ describe('profiler', () => { const checkMetrics = agent.assertTelemetryReceived(({ _, payload }) => { const pp = payload.payload - assert.equal(pp.namespace, 'profilers') - const sampleContexts = pp.series.find(s => s.metric === 'wall.sample_contexts') - assert.isDefined(sampleContexts) - assert.equal(sampleContexts.type, 'gauge') - assert.isAtLeast(sampleContexts.points[0][1], 1) + assert.equal(pp.namespace, 'profilers'); + ['live', 'used'].forEach(metricName => { + const sampleContexts = pp.series.find(s => s.metric === `wall.async_contexts_${metricName}`) + assert.isDefined(sampleContexts) + assert.equal(sampleContexts.type, 'gauge') + assert.isAtLeast(sampleContexts.points[0][1], 1) + }) }, 'generate-metrics', timeout) await Promise.all([checkProfiles(agent, proc, timeout), checkMetrics]) diff --git a/package.json b/package.json index 9fe3485ff80..6d191f62be4 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "@datadog/native-iast-taint-tracking": "4.0.0", "@datadog/native-metrics": "3.1.1", "@datadog/openfeature-node-server": "0.1.0-preview.10", - "@datadog/pprof": "5.10.0", + "@datadog/pprof": "5.11.1", "@datadog/sketches-js": "2.1.1", "@datadog/wasm-js-rewriter": "4.0.1", "@isaacs/ttlcache": "^1.4.1", diff --git a/packages/dd-trace/src/profiling/config.js b/packages/dd-trace/src/profiling/config.js index 2dec4a12abf..b407c4e8ec4 100644 --- a/packages/dd-trace/src/profiling/config.js +++ b/packages/dd-trace/src/profiling/config.js @@ -25,6 +25,7 @@ class Config { DD_AGENT_HOST, DD_ENV, DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing + DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED, DD_PROFILING_CODEHOTSPOTS_ENABLED, DD_PROFILING_CPU_ENABLED, DD_PROFILING_DEBUG_SOURCE_MAPS, @@ -42,7 +43,6 @@ class Config { DD_PROFILING_TIMELINE_ENABLED, DD_PROFILING_UPLOAD_PERIOD, DD_PROFILING_UPLOAD_TIMEOUT, - DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED, DD_PROFILING_V8_PROFILER_BUG_WORKAROUND, DD_PROFILING_WALLTIME_ENABLED, DD_SERVICE, @@ -242,6 +242,26 @@ class Config { this.profilers = ensureProfilers(profilers, this) } + + get systemInfoReport () { + const report = { + asyncContextFrameEnabled: this.asyncContextFrameEnabled, + codeHotspotsEnabled: this.codeHotspotsEnabled, + cpuProfilingEnabled: this.cpuProfilingEnabled, + debugSourceMaps: this.debugSourceMaps, + endpointCollectionEnabled: this.endpointCollectionEnabled, + heapSamplingInterval: this.heapSamplingInterval, + oomMonitoring: { ...this.oomMonitoring }, + profilerTypes: this.profilers.map(p => p.type), + sourceMap: this.sourceMap, + timelineEnabled: this.timelineEnabled, + timelineSamplingEnabled: this.timelineSamplingEnabled, + uploadCompression: { ...this.uploadCompression }, + v8ProfilerBugWorkaroundEnabled: this.v8ProfilerBugWorkaroundEnabled + } + delete report.oomMonitoring.exportCommand + return report + } } module.exports = { Config } diff --git a/packages/dd-trace/src/profiling/exporters/event_serializer.js b/packages/dd-trace/src/profiling/exporters/event_serializer.js index 44c80033bf2..8403aa6f855 100644 --- a/packages/dd-trace/src/profiling/exporters/event_serializer.js +++ b/packages/dd-trace/src/profiling/exporters/event_serializer.js @@ -21,7 +21,7 @@ class EventSerializer { return `${type}.pprof` } - getEventJSON ({ profiles, start, end, tags = {}, endpointCounts }) { + getEventJSON ({ profiles, infos, start, end, tags = {}, endpointCounts }) { return JSON.stringify({ attachments: Object.keys(profiles).map(t => this.typeToFile(t)), start: start.toISOString(), @@ -58,7 +58,8 @@ class EventSerializer { ssi: { mechanism: this._libraryInjected ? 'injected_agent' : 'none' }, - version + version, + ...infos }, runtime: { available_processors: availableParallelism(), diff --git a/packages/dd-trace/src/profiling/profiler.js b/packages/dd-trace/src/profiling/profiler.js index 70e96501c81..8cdb55556be 100644 --- a/packages/dd-trace/src/profiling/profiler.js +++ b/packages/dd-trace/src/profiling/profiler.js @@ -41,9 +41,16 @@ function findWebSpan (startedSpans, spanId) { return false } +function processInfo (infos, info, type) { + if (Object.keys(info).length > 0) { + infos[type] = info + } +} + class Profiler extends EventEmitter { #compressionFn #compressionOptions + #config #enabled = false #endpointCounts = new Map() #lastStart @@ -54,10 +61,13 @@ class Profiler extends EventEmitter { constructor () { super() - this._config = undefined this._timeoutInterval = undefined } + get flushInterval () { + return this.#config?.flushInterval + } + start (options) { return this._start(options).catch((err) => { logError(options.logger, 'Error starting profiler. For troubleshooting tips, see ' + @@ -77,7 +87,7 @@ class Profiler extends EventEmitter { async _start (options) { if (this.enabled) return true - const config = this._config = new Config(options) + const config = this.#config = new Config(options) this.#logger = config.logger this.#enabled = true @@ -158,16 +168,18 @@ class Profiler extends EventEmitter { } } - #nearOOMExport (profileType, encodedProfile) { + #nearOOMExport (profileType, encodedProfile, info) { const start = this.#lastStart const end = new Date() + const infos = this.#createInitialInfos() + processInfo(infos, info, profileType) this.#submit({ [profileType]: encodedProfile - }, start, end, snapshotKinds.ON_OUT_OF_MEMORY) + }, infos, start, end, snapshotKinds.ON_OUT_OF_MEMORY) } _setInterval () { - this._timeoutInterval = this._config.flushInterval + this._timeoutInterval = this.#config.flushInterval } stop () { @@ -189,7 +201,7 @@ class Profiler extends EventEmitter { this.#spanFinishListener = undefined } - for (const profiler of this._config.profilers) { + for (const profiler of this.#config.profilers) { profiler.stop() this.#logger.debug(`Stopped ${profiler.type} profiler in ${threadNamePrefix} thread`) } @@ -229,28 +241,34 @@ class Profiler extends EventEmitter { } } + #createInitialInfos () { + return { + settings: this.#config.systemInfoReport + } + } + async _collect (snapshotKind, restart = true) { if (!this.enabled) return - const startDate = this.#lastStart - const endDate = new Date() - const profiles = [] - const encodedProfiles = {} - try { - if (this._config.profilers.length === 0) { + if (this.#config.profilers.length === 0) { throw new Error('No profile types configured.') } + const startDate = this.#lastStart + const endDate = new Date() + const profiles = [] + crashtracker.withProfilerSerializing(() => { // collect profiles synchronously so that profilers can be safely stopped asynchronously - for (const profiler of this._config.profilers) { + for (const profiler of this.#config.profilers) { + const info = profiler.getInfo() const profile = profiler.profile(restart, startDate, endDate) if (!restart) { this.#logger.debug(`Stopped ${profiler.type} profiler in ${threadNamePrefix} thread`) } if (!profile) continue - profiles.push({ profiler, profile }) + profiles.push({ profiler, profile, info }) } }) @@ -260,16 +278,20 @@ class Profiler extends EventEmitter { let hasEncoded = false + const encodedProfiles = {} + const infos = this.#createInitialInfos() + // encode and export asynchronously - await Promise.all(profiles.map(async ({ profiler, profile }) => { + await Promise.all(profiles.map(async ({ profiler, profile, info }) => { try { const encoded = await profiler.encode(profile) const compressed = encoded instanceof Buffer && this.#compressionFn !== undefined ? await this.#compressionFn(encoded, this.#compressionOptions) : encoded encodedProfiles[profiler.type] = compressed + processInfo(infos, info, profiler.type) this.#logger.debug(() => { - const profileJson = JSON.stringify(profile, (key, value) => { + const profileJson = JSON.stringify(profile, (_, value) => { return typeof value === 'bigint' ? value.toString() : value }) return `Collected ${profiler.type} profile: ` + profileJson @@ -283,7 +305,7 @@ class Profiler extends EventEmitter { })) if (hasEncoded) { - await this.#submit(encodedProfiles, startDate, endDate, snapshotKind) + await this.#submit(encodedProfiles, infos, startDate, endDate, snapshotKind) profileSubmittedChannel.publish() this.#logger.debug('Submitted profiles') } @@ -293,8 +315,8 @@ class Profiler extends EventEmitter { } } - #submit (profiles, start, end, snapshotKind) { - const { tags } = this._config + #submit (profiles, infos, start, end, snapshotKind) { + const { tags } = this.#config // Flatten endpoint counts const endpointCounts = {} @@ -305,8 +327,8 @@ class Profiler extends EventEmitter { tags.snapshot = snapshotKind tags.profile_seq = this.#profileSeq++ - const exportSpec = { profiles, start, end, tags, endpointCounts } - const tasks = this._config.exporters.map(exporter => + const exportSpec = { profiles, infos, start, end, tags, endpointCounts } + const tasks = this.#config.exporters.map(exporter => exporter.export(exportSpec).catch(err => { if (this.#logger) { this.#logger.warn(err) @@ -336,7 +358,7 @@ class ServerlessProfiler extends Profiler { _setInterval () { this._timeoutInterval = this.#interval * 1000 - this.#flushAfterIntervals = this._config.flushInterval / 1000 + this.#flushAfterIntervals = this.flushInterval / 1000 } async _collect (snapshotKind, restart = true) { diff --git a/packages/dd-trace/src/profiling/profilers/events.js b/packages/dd-trace/src/profiling/profilers/events.js index 247aec39523..51a6c78e097 100644 --- a/packages/dd-trace/src/profiling/profilers/events.js +++ b/packages/dd-trace/src/profiling/profilers/events.js @@ -383,17 +383,20 @@ function createPoissonProcessSamplingFilter (samplingIntervalMillis) { * source with a sampling event filter and an event serializer. */ class EventsProfiler { - type = 'events' - #maxSamples + #maxSamples = 0 + #timelineSamplingEnabled = false #eventSerializer #eventSources + get type () { return 'events' } + constructor (options = {}) { this.#maxSamples = getMaxSamples(options) + this.#timelineSamplingEnabled = !!options.timelineSamplingEnabled this.#eventSerializer = new EventSerializer(this.#maxSamples) const eventHandler = event => this.#eventSerializer.addEvent(event) - const eventFilter = options.timelineSamplingEnabled + const eventFilter = this.#timelineSamplingEnabled ? createPoissonProcessSamplingFilter(options.samplingInterval) : () => true const filteringEventHandler = event => { @@ -432,6 +435,12 @@ class EventsProfiler { return () => thatEventSerializer.createProfile(startDate, endDate) } + getInfo () { + return { + maxSamples: this.#maxSamples + } + } + encode (profile) { return encodeProfileAsync(profile()) } diff --git a/packages/dd-trace/src/profiling/profilers/space.js b/packages/dd-trace/src/profiling/profilers/space.js index 36b560d0819..bd20d90f2ad 100644 --- a/packages/dd-trace/src/profiling/profilers/space.js +++ b/packages/dd-trace/src/profiling/profilers/space.js @@ -7,59 +7,70 @@ function strategiesToCallbackMode (strategies, callbackMode) { return strategies.includes(oomExportStrategies.ASYNC_CALLBACK) ? callbackMode.Async : 0 } +const STACK_DEPTH = 64 + class NativeSpaceProfiler { - type = 'space' - _pprof - _started = false + #mapper + #oomMonitoring + #pprof + #samplingInterval = 512 * 1024 + #started = false constructor (options = {}) { // TODO: Remove default value. It is only used in testing. - this._samplingInterval = options.heapSamplingInterval || 512 * 1024 - this._stackDepth = options.stackDepth || 64 - this._oomMonitoring = options.oomMonitoring || {} + this.#samplingInterval = options.heapSamplingInterval || 512 * 1024 + this.#oomMonitoring = options.oomMonitoring || {} + } + + get type () { + return 'space' } start ({ mapper, nearOOMCallback } = {}) { - if (this._started) return + if (this.#started) return - this._mapper = mapper - this._pprof = require('@datadog/pprof') - this._pprof.heap.start(this._samplingInterval, this._stackDepth) - if (this._oomMonitoring.enabled) { - const strategies = this._oomMonitoring.exportStrategies - this._pprof.heap.monitorOutOfMemory( - this._oomMonitoring.heapLimitExtensionSize, - this._oomMonitoring.maxHeapExtensionCount, + this.#mapper = mapper + this.#pprof = require('@datadog/pprof') + this.#pprof.heap.start(this.#samplingInterval, STACK_DEPTH) + if (this.#oomMonitoring.enabled) { + const strategies = this.#oomMonitoring.exportStrategies + this.#pprof.heap.monitorOutOfMemory( + this.#oomMonitoring.heapLimitExtensionSize, + this.#oomMonitoring.maxHeapExtensionCount, strategies.includes(oomExportStrategies.LOGS), - strategies.includes(oomExportStrategies.PROCESS) ? this._oomMonitoring.exportCommand : [], - (profile) => nearOOMCallback(this.type, this._pprof.encodeSync(profile)), - strategiesToCallbackMode(strategies, this._pprof.heap.CallbackMode) + strategies.includes(oomExportStrategies.PROCESS) ? this.#oomMonitoring.exportCommand : [], + (profile) => nearOOMCallback(this.type, this.#pprof.encodeSync(profile), this.getInfo()), + strategiesToCallbackMode(strategies, this.#pprof.heap.CallbackMode) ) } - this._started = true + this.#started = true } profile (restart) { - const profile = this._pprof.heap.profile(undefined, this._mapper, getThreadLabels) + const profile = this.#pprof.heap.profile(undefined, this.#mapper, getThreadLabels) if (!restart) { this.stop() } return profile } + getInfo () { + return {} + } + encode (profile) { return encodeProfileAsync(profile) } stop () { - if (!this._started) return - this._pprof.heap.stop() - this._started = false + if (!this.#started) return + this.#pprof.heap.stop() + this.#started = false } isStarted () { - return this._started + return this.#started } } diff --git a/packages/dd-trace/src/profiling/profilers/wall.js b/packages/dd-trace/src/profiling/profilers/wall.js index 41d77fa6e03..859d5686867 100644 --- a/packages/dd-trace/src/profiling/profilers/wall.js +++ b/packages/dd-trace/src/profiling/profilers/wall.js @@ -25,7 +25,6 @@ const profilerTelemetryMetrics = telemetryMetrics.manager.namespace('profilers') const ProfilingContext = Symbol('NativeWallProfiler.ProfilingContext') let kSampleCount -let kCPEDContextCount function getActiveSpan () { const store = storage('legacy').getStore() @@ -167,7 +166,6 @@ class NativeWallProfiler { this.#mapper = mapper this.#pprof = require('@datadog/pprof') kSampleCount = this.#pprof.time.constants.kSampleCount - kCPEDContextCount = this.#pprof.time.constants.kCPEDContextCount // pprof otherwise crashes in worker threads if (!process._startProfilerIdleNotifier) { @@ -213,12 +211,14 @@ class NativeWallProfiler { } #setupTelemetryMetrics () { - const contextCountGauge = profilerTelemetryMetrics.gauge('wall.sample_contexts') + const asyncContextsLiveGauge = profilerTelemetryMetrics.gauge('wall.async_contexts_live') + const asyncContextsUsedGauge = profilerTelemetryMetrics.gauge('wall.async_contexts_used') - const that = this this._contextCountGaugeUpdater = setInterval(() => { - contextCountGauge.mark(that._profilerState[kCPEDContextCount]) - }, that.#telemetryHeartbeatIntervalMillis) + const { totalAsyncContextCount, usedAsyncContextCount } = this.#pprof.time.getMetrics() + asyncContextsLiveGauge.mark(totalAsyncContextCount) + asyncContextsUsedGauge.mark(usedAsyncContextCount) + }, this.#telemetryHeartbeatIntervalMillis) this._contextCountGaugeUpdater.unref() } @@ -410,6 +410,14 @@ class NativeWallProfiler { return this.#stop(restart) } + getInfo () { + const { totalAsyncContextCount, usedAsyncContextCount } = this.#pprof.time.getMetrics() + return { + totalAsyncContextCount, + usedAsyncContextCount + } + } + encode (profile) { return encodeProfileAsync(profile) } diff --git a/packages/dd-trace/test/profiling/config.spec.js b/packages/dd-trace/test/profiling/config.spec.js index 13758a5c3fa..ff9579a6f78 100644 --- a/packages/dd-trace/test/profiling/config.spec.js +++ b/packages/dd-trace/test/profiling/config.spec.js @@ -406,6 +406,45 @@ describe('config', () => { } }) + it('should allow configuring exporters by string or string array', async () => { + const checks = [ + 'agent', + ['agent'] + ] + + for (const exporters of checks) { + const config = new Config({ + sourceMap: false, + exporters + }) + + expect(config.exporters[0].export).to.be.a('function') + } + }) + + it('should allow configuring profilers by string or string arrays', async () => { + const checks = [ + ['space', SpaceProfiler], + ['wall', WallProfiler, EventsProfiler], + ['space,wall', SpaceProfiler, WallProfiler, EventsProfiler], + ['wall,space', WallProfiler, SpaceProfiler, EventsProfiler], + [['space', 'wall'], SpaceProfiler, WallProfiler, EventsProfiler], + [['wall', 'space'], WallProfiler, SpaceProfiler, EventsProfiler] + ].map(profilers => profilers.filter(profiler => samplingContextsAvailable || profiler !== EventsProfiler)) + + for (const [profilers, ...expected] of checks) { + const config = new Config({ + sourceMap: false, + profilers + }) + + expect(config.profilers.length).to.equal(expected.length) + for (let i = 0; i < expected.length; i++) { + expect(config.profilers[i]).to.be.instanceOf(expected[i]) + } + } + }) + if (oomMonitoringSupported) { it('should support OOM heap profiler configuration', function () { process.env = { diff --git a/packages/dd-trace/test/profiling/profiler.spec.js b/packages/dd-trace/test/profiling/profiler.spec.js index 0bb5cd24b93..9a8dc62dc76 100644 --- a/packages/dd-trace/test/profiling/profiler.spec.js +++ b/packages/dd-trace/test/profiling/profiler.spec.js @@ -7,12 +7,6 @@ const proxyquire = require('proxyquire') require('../setup/core') -const SpaceProfiler = require('../../src/profiling/profilers/space') -const WallProfiler = require('../../src/profiling/profilers/wall') -const EventsProfiler = require('../../src/profiling/profilers/events') - -const samplingContextsAvailable = process.platform !== 'win32' - describe('profiler', function () { let Profiler let profiler @@ -65,6 +59,7 @@ describe('profiler', function () { start: sinon.stub(), stop: sinon.stub(), profile: sinon.stub().returns('profile'), + getInfo: sinon.stub().returns({}), encode: sinon.stub().returns(wallProfilePromise) } @@ -75,6 +70,7 @@ describe('profiler', function () { start: sinon.stub(), stop: sinon.stub(), profile: sinon.stub().returns('profile'), + getInfo: sinon.stub().returns({}), encode: sinon.stub().returns(spaceProfilePromise) } @@ -123,49 +119,6 @@ describe('profiler', function () { sinon.assert.calledOnce(spaceProfiler.start) }) - it('should allow configuring exporters by string or string array', async () => { - const checks = [ - 'agent', - ['agent'] - ] - - for (const exporters of checks) { - await profiler._start({ - sourceMap: false, - exporters - }) - - expect(profiler._config.exporters[0].export).to.be.a('function') - - profiler.stop() - } - }) - - it('should allow configuring profilers by string or string arrays', async () => { - const checks = [ - ['space', SpaceProfiler], - ['wall', WallProfiler, EventsProfiler], - ['space,wall', SpaceProfiler, WallProfiler, EventsProfiler], - ['wall,space', WallProfiler, SpaceProfiler, EventsProfiler], - [['space', 'wall'], SpaceProfiler, WallProfiler, EventsProfiler], - [['wall', 'space'], WallProfiler, SpaceProfiler, EventsProfiler] - ].map(profilers => profilers.filter(profiler => samplingContextsAvailable || profiler !== EventsProfiler)) - - for (const [profilers, ...expected] of checks) { - await profiler._start({ - sourceMap: false, - profilers - }) - - expect(profiler._config.profilers.length).to.equal(expected.length) - for (let i = 0; i < expected.length; i++) { - expect(profiler._config.profilers[i]).to.be.instanceOf(expected[i]) - } - - profiler.stop() - } - }) - it('should stop the internal profilers', async () => { await profiler._start({ profilers, exporters }) profiler.stop() diff --git a/packages/dd-trace/test/profiling/profilers/events.spec.js b/packages/dd-trace/test/profiling/profilers/events.spec.js index cae791b0d25..7278c327f76 100644 --- a/packages/dd-trace/test/profiling/profilers/events.spec.js +++ b/packages/dd-trace/test/profiling/profilers/events.spec.js @@ -14,6 +14,11 @@ const startCh = dc.channel('apm:dns:lookup:start') const finishCh = dc.channel('apm:dns:lookup:finish') describe('profilers/events', () => { + it('should provide info', () => { + const info = new EventsProfiler({ samplingInterval: 1 }).getInfo() + assert(info.maxSamples > 0) + }) + it('should limit the number of events', async () => { const samplingInterval = 1 const flushInterval = 2 diff --git a/packages/dd-trace/test/profiling/profilers/space.spec.js b/packages/dd-trace/test/profiling/profilers/space.spec.js index 2361e3ecea6..db5fedd2073 100644 --- a/packages/dd-trace/test/profiling/profilers/space.spec.js +++ b/packages/dd-trace/test/profiling/profilers/space.spec.js @@ -39,13 +39,12 @@ describe('profilers/native/space', () => { it('should use the provided configuration options', () => { const heapSamplingInterval = 1024 - const stackDepth = 10 - const profiler = new NativeSpaceProfiler({ heapSamplingInterval, stackDepth }) + const profiler = new NativeSpaceProfiler({ heapSamplingInterval }) profiler.start() sinon.assert.calledOnce(pprof.heap.start) - sinon.assert.calledWith(pprof.heap.start, heapSamplingInterval, stackDepth) + sinon.assert.calledWith(pprof.heap.start, heapSamplingInterval, 64) }) it('should stop the internal space profiler', () => { @@ -60,6 +59,13 @@ describe('profilers/native/space', () => { sinon.assert.calledOnce(pprof.heap.stop) }) + it('should provide info', () => { + const profiler = new NativeSpaceProfiler() + + const info = profiler.getInfo() + expect(Object.keys(info)).to.be.empty + }) + it('should collect profiles from the pprof space profiler', () => { const profiler = new NativeSpaceProfiler() diff --git a/packages/dd-trace/test/profiling/profilers/wall.spec.js b/packages/dd-trace/test/profiling/profilers/wall.spec.js index 925d8da12af..d356f9d3c35 100644 --- a/packages/dd-trace/test/profiling/profilers/wall.spec.js +++ b/packages/dd-trace/test/profiling/profilers/wall.spec.js @@ -25,7 +25,11 @@ describe('profilers/native/wall', () => { constants: { kSampleCount: 0, NON_JS_THREADS_FUNCTION_NAME: 'Non JS threads activity' - } + }, + getMetrics: sinon.stub().returns({ + totalAsyncContextCount: 0, + usedAsyncContextCount: 0 + }) } } @@ -122,6 +126,16 @@ describe('profilers/native/wall', () => { sinon.assert.calledOnce(pprof.time.stop) }) + it('should provide info', () => { + const profiler = new NativeWallProfiler() + profiler.start() + const info = profiler.getInfo() + profiler.stop() + + expect(info.totalAsyncContextCount).to.not.be.undefined + expect(info.usedAsyncContextCount).to.not.be.undefined + }) + it('should collect profiles from the internal time profiler', () => { const profiler = new NativeWallProfiler() diff --git a/yarn.lock b/yarn.lock index ed850182d91..c5a1ff50344 100644 --- a/yarn.lock +++ b/yarn.lock @@ -254,10 +254,10 @@ "@datadog/flagging-core" "0.1.0-preview.10" "@openfeature/server-sdk" "~1.18.0" -"@datadog/pprof@5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-5.10.0.tgz#47e9589c6d9c423470e312e00def06e249672571" - integrity sha512-tEMhLeOM78FHC/rTltDd7pQN8WPAUZ1b0BPadYsKWqo/v6jWTbF6xeIMojdJa5yIW2vHjDU4LFJpkFFNacHpQw== +"@datadog/pprof@5.11.1": + version "5.11.1" + resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-5.11.1.tgz#3eea3fb815b2d06111954d66dfaf6197fd874576" + integrity sha512-DX3F0v0BVOuP7RUBiu7bDhuGfFfICJRcElB+ZrEykMvkvBXe7FdVXoybYFviLH177hulwYTtW9Rcly7NXGarTw== dependencies: delay "^5.0.0" node-gyp-build "<4.0"