diff --git a/cmd.js b/cmd.js index d632e58..51c615b 100755 --- a/cmd.js +++ b/cmd.js @@ -60,6 +60,7 @@ async function cmd (argv, banner = defaultBanner) { visualizeOnly: 'visualize-only', visualizeCpuProfile: 'visualize-cpu-profile', collectOnly: 'collect-only', + collectDelay: 'collect-delay', kernelTracing: 'kernel-tracing', kernelTracingDebug: 'kernel-tracing-debug', treeDebug: 'tree-debug', diff --git a/docs/api.md b/docs/api.md index f1c957d..b34fb2a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -59,6 +59,12 @@ with relevant outputs. Default: false +#### `collectDelay` (number) + +Specify a delay(ms) before collecting data. + +Default: 0 + #### `mapFrames` (function) A custom mapping function that receives diff --git a/index.js b/index.js index b5e3443..82e9b89 100644 --- a/index.js +++ b/index.js @@ -25,8 +25,10 @@ async function zeroEks (args) { args.pathToNodeBinary = pathTo('node') } + args.collectDelay = args.collectDelay || 0 + validate(args) - const { collectOnly, visualizeOnly, writeTicks, treeDebug, mapFrames, visualizeCpuProfile } = args + const { collectOnly, visualizeOnly, writeTicks, treeDebug, mapFrames, visualizeCpuProfile, collectDelay } = args let incompatibleOptions = 0 if (collectOnly) incompatibleOptions += 1 @@ -63,6 +65,10 @@ async function zeroEks (args) { return folder } + if (collectDelay) { + debug('data collection will be delayed by ' + collectDelay + ' ms') + } + try { const file = generateFlamegraph({ ...args, ticks, inlined, pid, folder }) return file @@ -145,7 +151,7 @@ async function visualize ({ visualizeOnly, treeDebug, workingDir, title, mapFram name = name || meta.name const ticks = (srcType === 'v8') - ? await v8LogToTicks(src, pathToNodeBinary) + ? await v8LogToTicks(src, { pathToNodeBinary }) : traceStacksToTicks(src) if (treeDebug === true) { diff --git a/lib/v8-log-to-ticks.js b/lib/v8-log-to-ticks.js index 91b96fb..6c49ed8 100644 --- a/lib/v8-log-to-ticks.js +++ b/lib/v8-log-to-ticks.js @@ -15,9 +15,9 @@ const nodeMajorV = Number(process.versions.node.split('.')[0]) module.exports = wrapper -async function wrapper (isolateLogPath, node) { +async function wrapper (isolateLogPath, options) { const normalised = await prepareForPreprocess(isolateLogPath) - return v8LogToTicks(normalised, node) + return v8LogToTicks(normalised, options) } // 1. Filter because long lines make the --preprocess crash. Filter them beforehand, @@ -67,9 +67,9 @@ function fixLines (line) { } } -function v8LogToTicks (isolateLogPath, node) { +function v8LogToTicks (isolateLogPath, options) { const isJson = extname(isolateLogPath) === '.json' - const sp = isJson || spawn(node, [ + const sp = isJson || spawn(options.pathToNodeBinary, [ '--prof-process', '--preprocess', '-j', isolateLogPath ], { stdio: ['ignore', 'pipe', 'pipe'] }) @@ -119,10 +119,18 @@ function v8LogToTicks (isolateLogPath, node) { close() }) + const firstTick = [] const tickStream = parse('ticks.*', (tick) => { const addr = tick.s.filter((n, i) => i % 2 === 0) var stack = addr.map((n) => codes[n]).filter(Boolean) - ticks.push(stack.reverse()) + const delayMs = options.collectDelay * 1000 + if (firstTick.length === 0) { + firstTick.push(tick.tm) + } + // Compare ticks to first for collectDelay + if (tick.tm > (firstTick[0] + delayMs)) { + ticks.push(stack.reverse()) + } }) pump(srcStream, tickStream, (err) => { diff --git a/platform/v8.js b/platform/v8.js index fb30999..052fc97 100644 --- a/platform/v8.js +++ b/platform/v8.js @@ -21,7 +21,7 @@ const { module.exports = v8 async function v8 (args) { - const { status, outputDir, workingDir, name, onPort, pathToNodeBinary } = args + const { status, outputDir, workingDir, name, onPort, pathToNodeBinary, collectDelay } = args let proc = spawn(pathToNodeBinary, [ '--prof', @@ -114,7 +114,7 @@ async function v8 (args) { const isolateLogPath = path.join(folder, isolateLog) await renameSafe(path.join(args.workingDir, isolateLog), isolateLogPath) return { - ticks: await v8LogToTicks(isolateLogPath, pathToNodeBinary), + ticks: await v8LogToTicks(isolateLogPath, { pathToNodeBinary, collectDelay }), inlined: inlined, pid: proc.pid, folder: folder diff --git a/readme.md b/readme.md index b70281f..ff8e9aa 100644 --- a/readme.md +++ b/readme.md @@ -226,6 +226,12 @@ with relevant outputs. Default: false +### --collect-delay + +Delay the collection of stacks by a specified time(ms) relative to the first entry. + +Default: 0 + ### --visualize-only Supply a path to a profile folder to build or rebuild visualization diff --git a/schema.json b/schema.json index a0371cd..e17fbeb 100644 --- a/schema.json +++ b/schema.json @@ -100,6 +100,12 @@ }, "P": { "type": "string" + }, + "collect-delay": { + "type": "number" + }, + "collectDelay": { + "type": "number" }, "kernelTracing": { "type": "boolean"