Skip to content

Commit d5640ca

Browse files
haramjaduh95
authored andcommitted
cli: support ${pid} placeholder in --cpu-prof-name
PR-URL: #59072 Fixes: #57418 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 51f578a commit d5640ca

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed

doc/api/cli.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,13 +504,16 @@ $ ls *.cpuprofile
504504
CPU.20190409.202950.15293.0.0.cpuprofile
505505
```
506506

507-
If `--cpu-prof-name` is specified, the provided value will be used as-is; patterns such as
508-
`${hhmmss}` or `${pid}` are not supported.
507+
If `--cpu-prof-name` is specified, the provided value is used as a template
508+
for the file name. The following placeholder is supported and will be
509+
substituted at runtime:
510+
511+
* `${pid}` — the current process ID
509512

510513
```console
511514
$ node --cpu-prof --cpu-prof-name 'CPU.${pid}.cpuprofile' index.js
512515
$ ls *.cpuprofile
513-
'CPU.${pid}.cpuprofile'
516+
CPU.15293.cpuprofile
514517
```
515518

516519
### `--cpu-prof-dir`

src/inspector_profiler.cc

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "node_file.h"
99
#include "node_internals.h"
1010
#include "util-inl.h"
11+
#include "uv.h"
1112
#include "v8-inspector.h"
1213

1314
#include <cinttypes>
@@ -465,6 +466,27 @@ static void EndStartedProfilers(Environment* env) {
465466
}
466467
}
467468

469+
static std::string ReplacePlaceholders(const std::string& pattern) {
470+
std::string result = pattern;
471+
472+
static const std::unordered_map<std::string, std::function<std::string()>>
473+
kPlaceholderMap = {
474+
{"${pid}", []() { return std::to_string(uv_os_getpid()); }},
475+
// TODO(haramj): Add more placeholders as needed.
476+
};
477+
478+
for (const auto& [placeholder, getter] : kPlaceholderMap) {
479+
size_t pos = 0;
480+
while ((pos = result.find(placeholder, pos)) != std::string::npos) {
481+
const std::string value = getter();
482+
result.replace(pos, placeholder.length(), value);
483+
pos += value.length();
484+
}
485+
}
486+
487+
return result;
488+
}
489+
468490
void StartProfilers(Environment* env) {
469491
AtExit(env, [](void* env) {
470492
EndStartedProfilers(static_cast<Environment*>(env));
@@ -486,7 +508,9 @@ void StartProfilers(Environment* env) {
486508
DiagnosticFilename filename(env, "CPU", "cpuprofile");
487509
env->set_cpu_prof_name(*filename);
488510
} else {
489-
env->set_cpu_prof_name(env->options()->cpu_prof_name);
511+
std::string resolved_name =
512+
ReplacePlaceholders(env->options()->cpu_prof_name);
513+
env->set_cpu_prof_name(resolved_name);
490514
}
491515
CHECK_NULL(env->cpu_profiler_connection());
492516
env->set_cpu_profiler_connection(

test/sequential/test-cpu-prof-name.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const fixtures = require('../common/fixtures');
88
common.skipIfInspectorDisabled();
99

1010
const assert = require('assert');
11+
const fs = require('fs');
12+
const path = require('path');
1113
const { spawnSync } = require('child_process');
1214

1315
const tmpdir = require('../common/tmpdir');
@@ -41,3 +43,36 @@ const {
4143
assert.deepStrictEqual(profiles, [file]);
4244
verifyFrames(output, file, 'fibonacci.js');
4345
}
46+
47+
// --cpu-prof-name with ${pid} placeholder
48+
{
49+
tmpdir.refresh();
50+
// eslint-disable-next-line no-template-curly-in-string
51+
const profName = 'CPU.${pid}.cpuprofile';
52+
const dir = tmpdir.path;
53+
54+
const output = spawnSync(process.execPath, [
55+
'--cpu-prof',
56+
'--cpu-prof-interval',
57+
kCpuProfInterval,
58+
'--cpu-prof-name',
59+
profName,
60+
fixtures.path('workload', 'fibonacci.js'),
61+
], {
62+
cwd: dir,
63+
env
64+
});
65+
66+
if (output.status !== 0) {
67+
console.error(output.stderr.toString());
68+
}
69+
70+
assert.strictEqual(output.status, 0);
71+
72+
const expectedFile = path.join(dir, `CPU.${output.pid}.cpuprofile`);
73+
assert.ok(fs.existsSync(expectedFile), `Expected file ${expectedFile} not found.`);
74+
75+
verifyFrames(output, expectedFile, 'fibonacci.js');
76+
77+
fs.unlinkSync(expectedFile);
78+
}

0 commit comments

Comments
 (0)