@datadog/pprof 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bindings/profiler.cc +39 -17
- package/out/src/time-profiler.d.ts +1 -1
- package/out/src/time-profiler.js +36 -19
- package/out/src/time-profiler.js.map +1 -1
- package/package.json +1 -1
- package/prebuilds/darwin-ia32/node-102.node +0 -0
- package/prebuilds/darwin-ia32/node-72.node +0 -0
- package/prebuilds/darwin-ia32/node-79.node +0 -0
- package/prebuilds/darwin-ia32/node-83.node +0 -0
- package/prebuilds/darwin-ia32/node-88.node +0 -0
- package/prebuilds/darwin-ia32/node-93.node +0 -0
- package/prebuilds/darwin-x64/node-102.node +0 -0
- package/prebuilds/darwin-x64/node-72.node +0 -0
- package/prebuilds/darwin-x64/node-79.node +0 -0
- package/prebuilds/darwin-x64/node-83.node +0 -0
- package/prebuilds/darwin-x64/node-88.node +0 -0
- package/prebuilds/darwin-x64/node-93.node +0 -0
- package/prebuilds/linux-ia32/node-72.node +0 -0
- package/prebuilds/linux-ia32/node-79.node +0 -0
- package/prebuilds/linux-x64/node-102.node +0 -0
- package/prebuilds/linux-x64/node-72.node +0 -0
- package/prebuilds/linux-x64/node-79.node +0 -0
- package/prebuilds/linux-x64/node-83.node +0 -0
- package/prebuilds/linux-x64/node-88.node +0 -0
- package/prebuilds/linux-x64/node-93.node +0 -0
- package/prebuilds/win32-ia32/node-102.node +0 -0
- package/prebuilds/win32-ia32/node-72.node +0 -0
- package/prebuilds/win32-ia32/node-79.node +0 -0
- package/prebuilds/win32-ia32/node-83.node +0 -0
- package/prebuilds/win32-ia32/node-88.node +0 -0
- package/prebuilds/win32-ia32/node-93.node +0 -0
- package/prebuilds/win32-x64/node-102.node +0 -0
- package/prebuilds/win32-x64/node-72.node +0 -0
- package/prebuilds/win32-x64/node-79.node +0 -0
- package/prebuilds/win32-x64/node-83.node +0 -0
- package/prebuilds/win32-x64/node-88.node +0 -0
- package/prebuilds/win32-x64/node-93.node +0 -0
package/bindings/profiler.cc
CHANGED
|
@@ -242,18 +242,21 @@ Local<Value> TranslateTimeProfile(const CpuProfile* profile,
|
|
|
242
242
|
|
|
243
243
|
class TimeProfiler : public Nan::ObjectWrap {
|
|
244
244
|
public:
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
245
|
+
explicit TimeProfiler(int interval)
|
|
246
|
+
: samplingInterval(interval) {}
|
|
247
|
+
|
|
248
|
+
void Dispose() {
|
|
249
|
+
if (cpuProfiler != nullptr) {
|
|
250
|
+
cpuProfiler->Dispose();
|
|
251
|
+
cpuProfiler = nullptr;
|
|
252
|
+
}
|
|
248
253
|
}
|
|
249
254
|
|
|
250
|
-
|
|
251
|
-
|
|
255
|
+
static NAN_METHOD(Dispose) {
|
|
256
|
+
TimeProfiler* timeProfiler =
|
|
257
|
+
Nan::ObjectWrap::Unwrap<TimeProfiler>(info.Holder());
|
|
252
258
|
|
|
253
|
-
|
|
254
|
-
// to work around https://bugs.chromium.org/p/v8/issues/detail?id=11051.
|
|
255
|
-
cpuProfiler = CpuProfiler::New(isolate);
|
|
256
|
-
cpuProfiler->SetSamplingInterval(interval);
|
|
259
|
+
timeProfiler->Dispose();
|
|
257
260
|
}
|
|
258
261
|
|
|
259
262
|
static NAN_METHOD(New) {
|
|
@@ -285,10 +288,10 @@ class TimeProfiler : public Nan::ObjectWrap {
|
|
|
285
288
|
const bool recordSamples = false;
|
|
286
289
|
|
|
287
290
|
if (includeLines) {
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
GetProfiler()->StartProfiling(name, CpuProfilingMode::kCallerLineNumbers,
|
|
292
|
+
recordSamples);
|
|
290
293
|
} else {
|
|
291
|
-
|
|
294
|
+
GetProfiler()->StartProfiling(name, recordSamples);
|
|
292
295
|
}
|
|
293
296
|
}
|
|
294
297
|
|
|
@@ -316,13 +319,10 @@ class TimeProfiler : public Nan::ObjectWrap {
|
|
|
316
319
|
}
|
|
317
320
|
|
|
318
321
|
Local<Value> StopProfiling(Local<String> name, bool includeLines) {
|
|
319
|
-
CpuProfile* profile =
|
|
322
|
+
CpuProfile* profile = GetProfiler()->StopProfiling(name);
|
|
320
323
|
Local<Value> translated_profile =
|
|
321
324
|
TranslateTimeProfile(profile, includeLines);
|
|
322
325
|
profile->Delete();
|
|
323
|
-
// Dispose of CPU profiler to work around memory leak.
|
|
324
|
-
cpuProfiler->Dispose();
|
|
325
|
-
cpuProfiler = NULL;
|
|
326
326
|
return translated_profile;
|
|
327
327
|
}
|
|
328
328
|
|
|
@@ -357,13 +357,35 @@ class TimeProfiler : public Nan::ObjectWrap {
|
|
|
357
357
|
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
|
358
358
|
|
|
359
359
|
Nan::SetPrototypeMethod(tpl, "start", Start);
|
|
360
|
+
Nan::SetPrototypeMethod(tpl, "dispose", Dispose);
|
|
360
361
|
Nan::SetPrototypeMethod(tpl, "stop", Stop);
|
|
361
362
|
|
|
362
363
|
constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
|
|
363
364
|
Nan::Set(target, className, Nan::GetFunction(tpl).ToLocalChecked());
|
|
364
365
|
}
|
|
365
366
|
private:
|
|
366
|
-
|
|
367
|
+
int samplingInterval = 0;
|
|
368
|
+
CpuProfiler* cpuProfiler = nullptr;
|
|
369
|
+
|
|
370
|
+
static inline Nan::Persistent<v8::Function> & constructor() {
|
|
371
|
+
static Nan::Persistent<v8::Function> my_constructor;
|
|
372
|
+
return my_constructor;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
~TimeProfiler() {
|
|
376
|
+
Dispose();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// A new CPU profiler object will be created each time profiling is started
|
|
380
|
+
// to work around https://bugs.chromium.org/p/v8/issues/detail?id=11051.
|
|
381
|
+
CpuProfiler* GetProfiler() {
|
|
382
|
+
if (cpuProfiler == nullptr) {
|
|
383
|
+
Isolate* isolate = Isolate::GetCurrent();
|
|
384
|
+
cpuProfiler = CpuProfiler::New(isolate);
|
|
385
|
+
cpuProfiler->SetSamplingInterval(samplingInterval);
|
|
386
|
+
}
|
|
387
|
+
return cpuProfiler;
|
|
388
|
+
}
|
|
367
389
|
};
|
|
368
390
|
|
|
369
391
|
extern "C" NODE_MODULE_EXPORT void
|
|
@@ -32,5 +32,5 @@ export interface TimeProfilerOptions {
|
|
|
32
32
|
lineNumbers?: boolean;
|
|
33
33
|
}
|
|
34
34
|
export declare function profile(options: TimeProfilerOptions): Promise<import("../../proto/profile").perftools.profiles.IProfile>;
|
|
35
|
-
export declare function start(intervalMicros?: Microseconds, name?: string, sourceMapper?: SourceMapper, lineNumbers?: boolean): () => import("../../proto/profile").perftools.profiles.IProfile;
|
|
35
|
+
export declare function start(intervalMicros?: Microseconds, name?: string, sourceMapper?: SourceMapper, lineNumbers?: boolean): (restart?: boolean) => import("../../proto/profile").perftools.profiles.IProfile;
|
|
36
36
|
export {};
|
package/out/src/time-profiler.js
CHANGED
|
@@ -29,6 +29,7 @@ const delay_1 = require("delay");
|
|
|
29
29
|
const profile_serializer_1 = require("./profile-serializer");
|
|
30
30
|
const time_profiler_bindings_1 = require("./time-profiler-bindings");
|
|
31
31
|
const DEFAULT_INTERVAL_MICROS = 1000;
|
|
32
|
+
const majorVersion = process.version.slice(1).split('.').map(Number)[0];
|
|
32
33
|
function profile(options) {
|
|
33
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
35
|
const stop = start(options.intervalMicros || DEFAULT_INTERVAL_MICROS, options.name, options.sourceMapper, options.lineNumbers);
|
|
@@ -37,30 +38,46 @@ function profile(options) {
|
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
exports.profile = profile;
|
|
41
|
+
function ensureRunName(name) {
|
|
42
|
+
return name || `pprof-${Date.now()}-${Math.random()}`;
|
|
43
|
+
}
|
|
44
|
+
// NOTE: refreshing doesn't work if giving a profile name.
|
|
40
45
|
function start(intervalMicros = DEFAULT_INTERVAL_MICROS, name, sourceMapper, lineNumbers = true) {
|
|
41
|
-
const runName = name || `pprof-${Date.now()}-${Math.random()}`;
|
|
42
46
|
const profiler = new time_profiler_bindings_1.TimeProfiler(intervalMicros);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
let runName = start();
|
|
48
|
+
return majorVersion < 16 ? stopOld : stop;
|
|
49
|
+
function start() {
|
|
50
|
+
const runName = ensureRunName(name);
|
|
51
|
+
profiler.start(runName, lineNumbers);
|
|
52
|
+
return runName;
|
|
53
|
+
}
|
|
54
|
+
// Node.js versions prior to v16 leak memory if not disposed and recreated
|
|
55
|
+
// between each profile. As disposing deletes current profile data too,
|
|
56
|
+
// we must stop then dispose then start.
|
|
57
|
+
function stopOld(restart = false) {
|
|
58
|
+
const result = profiler.stop(runName, lineNumbers);
|
|
59
|
+
profiler.dispose();
|
|
60
|
+
if (restart) {
|
|
61
|
+
runName = start();
|
|
62
|
+
}
|
|
63
|
+
return profile_serializer_1.serializeTimeProfile(result, intervalMicros, sourceMapper);
|
|
53
64
|
}
|
|
54
|
-
|
|
65
|
+
// For Node.js v16+, we want to start the next profile before we stop the
|
|
66
|
+
// current one as otherwise the active profile count could reach zero which
|
|
67
|
+
// means V8 might tear down the symbolizer thread and need to start it again.
|
|
68
|
+
function stop(restart = false) {
|
|
69
|
+
let nextRunName;
|
|
70
|
+
if (restart) {
|
|
71
|
+
nextRunName = start();
|
|
72
|
+
}
|
|
55
73
|
const result = profiler.stop(runName, lineNumbers);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
-
process._stopProfilerIdleNotifier();
|
|
74
|
+
if (nextRunName) {
|
|
75
|
+
runName = nextRunName;
|
|
60
76
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
77
|
+
if (!restart)
|
|
78
|
+
profiler.dispose();
|
|
79
|
+
return profile_serializer_1.serializeTimeProfile(result, intervalMicros, sourceMapper);
|
|
80
|
+
}
|
|
64
81
|
}
|
|
65
82
|
exports.start = start;
|
|
66
83
|
//# sourceMappingURL=time-profiler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-profiler.js","sourceRoot":"","sources":["../../ts/src/time-profiler.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;AAEH,iCAA0B;AAE1B,6DAA0D;AAE1D,qEAAsD;AAEtD,MAAM,uBAAuB,GAAiB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"time-profiler.js","sourceRoot":"","sources":["../../ts/src/time-profiler.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;AAEH,iCAA0B;AAE1B,6DAA0D;AAE1D,qEAAsD;AAEtD,MAAM,uBAAuB,GAAiB,IAAI,CAAC;AAEnD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAsBxE,SAAsB,OAAO,CAAC,OAA4B;;QACxD,MAAM,IAAI,GAAG,KAAK,CAChB,OAAO,CAAC,cAAc,IAAI,uBAAuB,EACjD,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,WAAW,CACpB,CAAC;QACF,MAAM,eAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;CAAA;AATD,0BASC;AAED,SAAS,aAAa,CAAC,IAAa;IAClC,OAAO,IAAI,IAAI,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACxD,CAAC;AAED,0DAA0D;AAC1D,SAAgB,KAAK,CACnB,iBAA+B,uBAAuB,EACtD,IAAa,EACb,YAA2B,EAC3B,WAAW,GAAG,IAAI;IAElB,MAAM,QAAQ,GAAG,IAAI,qCAAY,CAAC,cAAc,CAAC,CAAC;IAClD,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;IACtB,OAAO,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAE1C,SAAS,KAAK;QACZ,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACpC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACrC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,0EAA0E;IAC1E,uEAAuE;IACvE,wCAAwC;IACxC,SAAS,OAAO,CAAC,OAAO,GAAG,KAAK;QAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnD,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,OAAO,EAAE;YACX,OAAO,GAAG,KAAK,EAAE,CAAC;SACnB;QACD,OAAO,yCAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACpE,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,6EAA6E;IAC7E,SAAS,IAAI,CAAC,OAAO,GAAG,KAAK;QAC3B,IAAI,WAAW,CAAC;QAChB,IAAI,OAAO,EAAE;YACX,WAAW,GAAG,KAAK,EAAE,CAAC;SACvB;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnD,IAAI,WAAW,EAAE;YACf,OAAO,GAAG,WAAW,CAAC;SACvB;QACD,IAAI,CAAC,OAAO;YAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,yCAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AA3CD,sBA2CC"}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|