cluster: make --prof work for workers
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 18 Jan 2013 11:44:10 +0000 (12:44 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Fri, 18 Jan 2013 11:56:40 +0000 (12:56 +0100)
Profiling in clustered environments doesn't work out of the box.

By default, V8 writes the profile data of all processes to a single
v8.log.

Running that log file through a tick processor produces bogus numbers
because many events won't match up with the recorded memory mappings
and you end up with graphs where 80+% of ticks is unaccounted for.

Fixing the tick processor to deal with multi-process output is not very
useful because the processes may be running wildly disparate workloads.

That's why we fix up the command line arguments to include
a "--logfile=v8-%p.log" argument (where %p is expanded to the PID)
unless it already contains a --logfile argument.

Fixes #4617.

lib/cluster.js

index 4bece2d..b2e7625 100644 (file)
@@ -105,10 +105,31 @@ cluster.setupMaster = function(options) {
   // Get filename and arguments
   options = options || {};
 
+  // By default, V8 writes the profile data of all processes to a single
+  // v8.log.
+  //
+  // Running that log file through a tick processor produces bogus numbers
+  // because many events won't match up with the recorded memory mappings
+  // and you end up with graphs where 80+% of ticks is unaccounted for.
+  //
+  // Fixing the tick processor to deal with multi-process output is not very
+  // useful because the processes may be running wildly disparate workloads.
+  //
+  // That's why we fix up the command line arguments to include
+  // a "--logfile=v8-%p.log" argument (where %p is expanded to the PID)
+  // unless it already contains a --logfile argument.
+  var execArgv = options.execArgv || process.execArgv;
+  if (execArgv.some(function(s) { return /^--prof/.test(s); }) &&
+      !execArgv.some(function(s) { return /^--logfile=/.test(s); }))
+  {
+    execArgv = execArgv.slice();
+    execArgv.push('--logfile=v8-%p.log');
+  }
+
   // Set settings object
   settings = cluster.settings = {
     exec: options.exec || process.argv[1],
-    execArgv: options.execArgv || process.execArgv,
+    execArgv: execArgv,
     args: options.args || process.argv.slice(2),
     silent: options.silent || false
   };