@sentry/profiling-node 8.30.0 → 8.31.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/cpu_profiler.cc +16 -15
- package/lib/cjs/index.js +73 -34
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/index.js +73 -34
- package/lib/esm/index.js.map +1 -1
- package/lib/sentry_cpu_profiler-darwin-arm64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-127.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-93.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-127.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-glibc-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-arm64-musl-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-glibc-93.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-108.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-115.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-127.node +0 -0
- package/lib/sentry_cpu_profiler-linux-x64-musl-93.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-127.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-93.node +0 -0
- package/lib/types/integration.d.ts.map +1 -1
- package/package.json +5 -5
package/bindings/cpu_profiler.cc
CHANGED
|
@@ -73,7 +73,7 @@ enum class ProfileStatus {
|
|
|
73
73
|
|
|
74
74
|
class MeasurementsTicker {
|
|
75
75
|
private:
|
|
76
|
-
uv_timer_t timer;
|
|
76
|
+
uv_timer_t *timer;
|
|
77
77
|
uint64_t period_ms;
|
|
78
78
|
std::unordered_map<std::string,
|
|
79
79
|
const std::function<bool(uint64_t, v8::HeapStatistics &)>>
|
|
@@ -87,9 +87,10 @@ private:
|
|
|
87
87
|
public:
|
|
88
88
|
MeasurementsTicker(uv_loop_t *loop)
|
|
89
89
|
: period_ms(100), isolate(v8::Isolate::GetCurrent()) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
timer = new uv_timer_t;
|
|
91
|
+
uv_timer_init(loop, timer);
|
|
92
|
+
uv_handle_set_data((uv_handle_t *)timer, this);
|
|
93
|
+
uv_ref((uv_handle_t *)timer);
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
static void ticker(uv_timer_t *);
|
|
@@ -112,13 +113,13 @@ public:
|
|
|
112
113
|
size_t listener_count();
|
|
113
114
|
|
|
114
115
|
~MeasurementsTicker() {
|
|
115
|
-
|
|
116
|
+
uv_handle_t *handle = (uv_handle_t *)timer;
|
|
116
117
|
|
|
117
|
-
|
|
118
|
+
uv_timer_stop(timer);
|
|
119
|
+
uv_unref(handle);
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
uv_close(handle, nullptr);
|
|
121
|
+
if (!uv_is_closing(handle)) {
|
|
122
|
+
uv_close(handle, [](uv_handle_t *handle) { delete handle; });
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
};
|
|
@@ -143,8 +144,8 @@ void MeasurementsTicker::add_heap_listener(
|
|
|
143
144
|
heap_listeners.emplace(profile_id, cb);
|
|
144
145
|
|
|
145
146
|
if (listener_count() == 1) {
|
|
146
|
-
uv_timer_set_repeat(
|
|
147
|
-
uv_timer_start(
|
|
147
|
+
uv_timer_set_repeat(timer, period_ms);
|
|
148
|
+
uv_timer_start(timer, ticker, 0, period_ms);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
|
|
@@ -154,7 +155,7 @@ void MeasurementsTicker::remove_heap_listener(
|
|
|
154
155
|
heap_listeners.erase(profile_id);
|
|
155
156
|
|
|
156
157
|
if (listener_count() == 0) {
|
|
157
|
-
uv_timer_stop(
|
|
158
|
+
uv_timer_stop(timer);
|
|
158
159
|
}
|
|
159
160
|
};
|
|
160
161
|
|
|
@@ -223,8 +224,8 @@ void MeasurementsTicker::add_cpu_listener(
|
|
|
223
224
|
cpu_listeners.emplace(profile_id, cb);
|
|
224
225
|
|
|
225
226
|
if (listener_count() == 1) {
|
|
226
|
-
uv_timer_set_repeat(
|
|
227
|
-
uv_timer_start(
|
|
227
|
+
uv_timer_set_repeat(timer, period_ms);
|
|
228
|
+
uv_timer_start(timer, ticker, 0, period_ms);
|
|
228
229
|
}
|
|
229
230
|
}
|
|
230
231
|
|
|
@@ -233,7 +234,7 @@ void MeasurementsTicker::remove_cpu_listener(
|
|
|
233
234
|
cpu_listeners.erase(profile_id);
|
|
234
235
|
|
|
235
236
|
if (listener_count() == 0) {
|
|
236
|
-
uv_timer_stop(
|
|
237
|
+
uv_timer_stop(timer);
|
|
237
238
|
}
|
|
238
239
|
};
|
|
239
240
|
|
package/lib/cjs/index.js
CHANGED
|
@@ -904,10 +904,10 @@ function setupAutomatedSpanProfiling(client) {
|
|
|
904
904
|
});
|
|
905
905
|
}
|
|
906
906
|
|
|
907
|
-
class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.call(this);ContinuousProfiler.prototype.__init2.call(this);
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
907
|
+
class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.call(this);ContinuousProfiler.prototype.__init2.call(this); }
|
|
908
|
+
|
|
909
|
+
__init() {this._client = undefined;}
|
|
910
|
+
__init2() {this._chunkData = undefined;}
|
|
911
911
|
|
|
912
912
|
/**
|
|
913
913
|
* Called when the profiler is attached to the client (continuous mode is enabled). If of the profiler
|
|
@@ -916,15 +916,48 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
916
916
|
*/
|
|
917
917
|
initialize(client) {
|
|
918
918
|
this._client = client;
|
|
919
|
+
|
|
920
|
+
// Attaches a listener to beforeSend which will add the threadId data to the event being sent.
|
|
921
|
+
// This adds a constant overhead to all events being sent which could be improved to only attach
|
|
922
|
+
// and detach the listener during a profiler session
|
|
923
|
+
this._client.on('beforeSendEvent', this._onBeforeSendThreadContextAssignment.bind(this));
|
|
919
924
|
}
|
|
920
925
|
|
|
921
926
|
/**
|
|
922
|
-
*
|
|
923
|
-
* Once the user calls stop(), the current chunk will be stopped and flushed to Sentry and no new chunks will
|
|
924
|
-
* will be started. To restart continuous mode after calling stop(), the user must call start() again.
|
|
927
|
+
* Initializes a new profilerId session and schedules chunk profiling.
|
|
925
928
|
* @returns void
|
|
926
929
|
*/
|
|
927
930
|
start() {
|
|
931
|
+
if (!this._client) {
|
|
932
|
+
DEBUG_BUILD && utils.logger.log('[Profiling] Failed to start, sentry client was never attached to the profiler.');
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// Flush any existing chunks before starting a new one.
|
|
937
|
+
this._chunkStop();
|
|
938
|
+
|
|
939
|
+
// Restart the profiler session
|
|
940
|
+
this._setupSpanChunkInstrumentation();
|
|
941
|
+
this._chunkStart();
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/**
|
|
945
|
+
* Stops the current chunk and flushes the profile to Sentry.
|
|
946
|
+
* @returns void
|
|
947
|
+
*/
|
|
948
|
+
stop() {
|
|
949
|
+
if (!this._client) {
|
|
950
|
+
DEBUG_BUILD && utils.logger.log('[Profiling] Failed to stop, sentry client was never attached to the profiler.');
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
this._chunkStop();
|
|
954
|
+
this._teardownSpanChunkInstrumentation();
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* Stop profiler and initializes profiling of the next chunk
|
|
959
|
+
*/
|
|
960
|
+
_chunkStart() {
|
|
928
961
|
if (!this._client) {
|
|
929
962
|
// The client is not attached to the profiler if the user has not enabled continuous profiling.
|
|
930
963
|
// In this case, calling start() and stop() is a noop action.The reason this exists is because
|
|
@@ -937,20 +970,16 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
937
970
|
utils.logger.log(
|
|
938
971
|
`[Profiling] Chunk with chunk_id ${this._chunkData.id} is still running, current chunk will be stopped a new chunk will be started.`,
|
|
939
972
|
);
|
|
940
|
-
this.
|
|
973
|
+
this._chunkStop();
|
|
941
974
|
}
|
|
942
975
|
|
|
943
|
-
|
|
944
|
-
core.getCurrentScope().getPropagationContext().traceId || core.getIsolationScope().getPropagationContext().traceId;
|
|
945
|
-
this._initializeChunk(traceId);
|
|
946
|
-
this._startChunkProfiling(this._chunkData);
|
|
976
|
+
this._startChunkProfiling();
|
|
947
977
|
}
|
|
948
978
|
|
|
949
979
|
/**
|
|
950
|
-
* Stops the current
|
|
951
|
-
* @returns void
|
|
980
|
+
* Stops profiling of the current chunks and flushes the profile to Sentry
|
|
952
981
|
*/
|
|
953
|
-
|
|
982
|
+
_chunkStop() {
|
|
954
983
|
if (_optionalChain([this, 'access', _6 => _6._chunkData, 'optionalAccess', _7 => _7.timer])) {
|
|
955
984
|
global.clearTimeout(this._chunkData.timer);
|
|
956
985
|
this._chunkData.timer = undefined;
|
|
@@ -967,12 +996,17 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
967
996
|
return;
|
|
968
997
|
}
|
|
969
998
|
|
|
970
|
-
const profile =
|
|
999
|
+
const profile = CpuProfilerBindings.stopProfiling(this._chunkData.id, ProfileFormat.CHUNK);
|
|
971
1000
|
|
|
972
1001
|
if (!profile) {
|
|
973
1002
|
DEBUG_BUILD && utils.logger.log(`[Profiling] _chunkiledStartTraceID to collect profile for: ${this._chunkData.id}`);
|
|
974
1003
|
return;
|
|
975
1004
|
}
|
|
1005
|
+
if (!this._profilerId) {
|
|
1006
|
+
DEBUG_BUILD &&
|
|
1007
|
+
utils.logger.log('[Profiling] Profile chunk does not contain a valid profiler_id, this is a bug in the SDK');
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
976
1010
|
if (profile) {
|
|
977
1011
|
DEBUG_BUILD && utils.logger.log(`[Profiling] Sending profile chunk ${this._chunkData.id}.`);
|
|
978
1012
|
}
|
|
@@ -992,7 +1026,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
992
1026
|
|
|
993
1027
|
if (!chunk) {
|
|
994
1028
|
DEBUG_BUILD && utils.logger.log(`[Profiling] Failed to create profile chunk for: ${this._chunkData.id}`);
|
|
995
|
-
this.
|
|
1029
|
+
this._resetChunkData();
|
|
996
1030
|
return;
|
|
997
1031
|
}
|
|
998
1032
|
|
|
@@ -1001,7 +1035,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1001
1035
|
// the format may negatively impact the performance of the application. To avoid
|
|
1002
1036
|
// blocking for too long, enqueue the next chunk start inside the next macrotask.
|
|
1003
1037
|
// clear current chunk
|
|
1004
|
-
this.
|
|
1038
|
+
this._resetChunkData();
|
|
1005
1039
|
}
|
|
1006
1040
|
|
|
1007
1041
|
/**
|
|
@@ -1031,29 +1065,23 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1031
1065
|
});
|
|
1032
1066
|
}
|
|
1033
1067
|
|
|
1034
|
-
/**
|
|
1035
|
-
* Stops the profile and clears chunk instrumentation from global scope
|
|
1036
|
-
* @returns void
|
|
1037
|
-
*/
|
|
1038
|
-
_stopChunkProfiling(chunk) {
|
|
1039
|
-
this._teardownSpanChunkInstrumentation();
|
|
1040
|
-
return CpuProfilerBindings.stopProfiling(chunk.id, ProfileFormat.CHUNK);
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
1068
|
/**
|
|
1044
1069
|
* Starts the profiler and registers the flush timer for a given chunk.
|
|
1045
1070
|
* @param chunk
|
|
1046
1071
|
*/
|
|
1047
|
-
_startChunkProfiling(
|
|
1048
|
-
|
|
1072
|
+
_startChunkProfiling() {
|
|
1073
|
+
const traceId =
|
|
1074
|
+
core.getCurrentScope().getPropagationContext().traceId || core.getIsolationScope().getPropagationContext().traceId;
|
|
1075
|
+
const chunk = this._initializeChunk(traceId);
|
|
1076
|
+
|
|
1049
1077
|
CpuProfilerBindings.startProfiling(chunk.id);
|
|
1050
1078
|
DEBUG_BUILD && utils.logger.log(`[Profiling] starting profiling chunk: ${chunk.id}`);
|
|
1051
1079
|
|
|
1052
1080
|
chunk.timer = global.setTimeout(() => {
|
|
1053
1081
|
DEBUG_BUILD && utils.logger.log(`[Profiling] Stopping profiling chunk: ${chunk.id}`);
|
|
1054
|
-
this.
|
|
1082
|
+
this._chunkStop();
|
|
1055
1083
|
DEBUG_BUILD && utils.logger.log('[Profiling] Starting new profiling chunk.');
|
|
1056
|
-
setImmediate(this.
|
|
1084
|
+
setImmediate(this._chunkStart.bind(this));
|
|
1057
1085
|
}, CHUNK_INTERVAL_MS);
|
|
1058
1086
|
|
|
1059
1087
|
// Unref timeout so it doesn't keep the process alive.
|
|
@@ -1067,21 +1095,31 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1067
1095
|
_setupSpanChunkInstrumentation() {
|
|
1068
1096
|
if (!this._client) {
|
|
1069
1097
|
DEBUG_BUILD &&
|
|
1070
|
-
utils.logger.log(
|
|
1098
|
+
utils.logger.log(
|
|
1099
|
+
'[Profiling] Failed to initialize span profiling, sentry client was never attached to the profiler.',
|
|
1100
|
+
);
|
|
1071
1101
|
return;
|
|
1072
1102
|
}
|
|
1073
1103
|
|
|
1104
|
+
this._profilerId = utils.uuid4();
|
|
1074
1105
|
core.getGlobalScope().setContext('profile', {
|
|
1075
1106
|
profiler_id: this._profilerId,
|
|
1076
1107
|
});
|
|
1108
|
+
}
|
|
1077
1109
|
|
|
1078
|
-
|
|
1110
|
+
/**
|
|
1111
|
+
* Assigns thread_id and thread name context to a profiled event if there is an active profiler session
|
|
1112
|
+
*/
|
|
1113
|
+
_onBeforeSendThreadContextAssignment(event) {
|
|
1114
|
+
if (!this._client || !this._profilerId) return;
|
|
1115
|
+
this._assignThreadIdContext(event);
|
|
1079
1116
|
}
|
|
1080
1117
|
|
|
1081
1118
|
/**
|
|
1082
1119
|
* Clear profiling information from global context when a profile is not running.
|
|
1083
1120
|
*/
|
|
1084
1121
|
_teardownSpanChunkInstrumentation() {
|
|
1122
|
+
this._profilerId = undefined;
|
|
1085
1123
|
const globalScope = core.getGlobalScope();
|
|
1086
1124
|
globalScope.setContext('profile', {});
|
|
1087
1125
|
}
|
|
@@ -1095,6 +1133,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1095
1133
|
startTraceID: traceId,
|
|
1096
1134
|
timer: undefined,
|
|
1097
1135
|
};
|
|
1136
|
+
return this._chunkData;
|
|
1098
1137
|
}
|
|
1099
1138
|
|
|
1100
1139
|
/**
|
|
@@ -1124,7 +1163,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1124
1163
|
/**
|
|
1125
1164
|
* Resets the current chunk state.
|
|
1126
1165
|
*/
|
|
1127
|
-
|
|
1166
|
+
_resetChunkData() {
|
|
1128
1167
|
this._chunkData = undefined;
|
|
1129
1168
|
}
|
|
1130
1169
|
}
|
package/lib/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/esm/index.js
CHANGED
|
@@ -912,10 +912,10 @@ function setupAutomatedSpanProfiling(client) {
|
|
|
912
912
|
});
|
|
913
913
|
}
|
|
914
914
|
|
|
915
|
-
class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.call(this);ContinuousProfiler.prototype.__init2.call(this);
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
915
|
+
class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.call(this);ContinuousProfiler.prototype.__init2.call(this); }
|
|
916
|
+
|
|
917
|
+
__init() {this._client = undefined;}
|
|
918
|
+
__init2() {this._chunkData = undefined;}
|
|
919
919
|
|
|
920
920
|
/**
|
|
921
921
|
* Called when the profiler is attached to the client (continuous mode is enabled). If of the profiler
|
|
@@ -924,15 +924,48 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
924
924
|
*/
|
|
925
925
|
initialize(client) {
|
|
926
926
|
this._client = client;
|
|
927
|
+
|
|
928
|
+
// Attaches a listener to beforeSend which will add the threadId data to the event being sent.
|
|
929
|
+
// This adds a constant overhead to all events being sent which could be improved to only attach
|
|
930
|
+
// and detach the listener during a profiler session
|
|
931
|
+
this._client.on('beforeSendEvent', this._onBeforeSendThreadContextAssignment.bind(this));
|
|
927
932
|
}
|
|
928
933
|
|
|
929
934
|
/**
|
|
930
|
-
*
|
|
931
|
-
* Once the user calls stop(), the current chunk will be stopped and flushed to Sentry and no new chunks will
|
|
932
|
-
* will be started. To restart continuous mode after calling stop(), the user must call start() again.
|
|
935
|
+
* Initializes a new profilerId session and schedules chunk profiling.
|
|
933
936
|
* @returns void
|
|
934
937
|
*/
|
|
935
938
|
start() {
|
|
939
|
+
if (!this._client) {
|
|
940
|
+
DEBUG_BUILD && logger.log('[Profiling] Failed to start, sentry client was never attached to the profiler.');
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// Flush any existing chunks before starting a new one.
|
|
945
|
+
this._chunkStop();
|
|
946
|
+
|
|
947
|
+
// Restart the profiler session
|
|
948
|
+
this._setupSpanChunkInstrumentation();
|
|
949
|
+
this._chunkStart();
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Stops the current chunk and flushes the profile to Sentry.
|
|
954
|
+
* @returns void
|
|
955
|
+
*/
|
|
956
|
+
stop() {
|
|
957
|
+
if (!this._client) {
|
|
958
|
+
DEBUG_BUILD && logger.log('[Profiling] Failed to stop, sentry client was never attached to the profiler.');
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
this._chunkStop();
|
|
962
|
+
this._teardownSpanChunkInstrumentation();
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Stop profiler and initializes profiling of the next chunk
|
|
967
|
+
*/
|
|
968
|
+
_chunkStart() {
|
|
936
969
|
if (!this._client) {
|
|
937
970
|
// The client is not attached to the profiler if the user has not enabled continuous profiling.
|
|
938
971
|
// In this case, calling start() and stop() is a noop action.The reason this exists is because
|
|
@@ -945,20 +978,16 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
945
978
|
logger.log(
|
|
946
979
|
`[Profiling] Chunk with chunk_id ${this._chunkData.id} is still running, current chunk will be stopped a new chunk will be started.`,
|
|
947
980
|
);
|
|
948
|
-
this.
|
|
981
|
+
this._chunkStop();
|
|
949
982
|
}
|
|
950
983
|
|
|
951
|
-
|
|
952
|
-
getCurrentScope().getPropagationContext().traceId || getIsolationScope().getPropagationContext().traceId;
|
|
953
|
-
this._initializeChunk(traceId);
|
|
954
|
-
this._startChunkProfiling(this._chunkData);
|
|
984
|
+
this._startChunkProfiling();
|
|
955
985
|
}
|
|
956
986
|
|
|
957
987
|
/**
|
|
958
|
-
* Stops the current
|
|
959
|
-
* @returns void
|
|
988
|
+
* Stops profiling of the current chunks and flushes the profile to Sentry
|
|
960
989
|
*/
|
|
961
|
-
|
|
990
|
+
_chunkStop() {
|
|
962
991
|
if (_optionalChain([this, 'access', _6 => _6._chunkData, 'optionalAccess', _7 => _7.timer])) {
|
|
963
992
|
global.clearTimeout(this._chunkData.timer);
|
|
964
993
|
this._chunkData.timer = undefined;
|
|
@@ -975,12 +1004,17 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
975
1004
|
return;
|
|
976
1005
|
}
|
|
977
1006
|
|
|
978
|
-
const profile =
|
|
1007
|
+
const profile = CpuProfilerBindings.stopProfiling(this._chunkData.id, ProfileFormat.CHUNK);
|
|
979
1008
|
|
|
980
1009
|
if (!profile) {
|
|
981
1010
|
DEBUG_BUILD && logger.log(`[Profiling] _chunkiledStartTraceID to collect profile for: ${this._chunkData.id}`);
|
|
982
1011
|
return;
|
|
983
1012
|
}
|
|
1013
|
+
if (!this._profilerId) {
|
|
1014
|
+
DEBUG_BUILD &&
|
|
1015
|
+
logger.log('[Profiling] Profile chunk does not contain a valid profiler_id, this is a bug in the SDK');
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
984
1018
|
if (profile) {
|
|
985
1019
|
DEBUG_BUILD && logger.log(`[Profiling] Sending profile chunk ${this._chunkData.id}.`);
|
|
986
1020
|
}
|
|
@@ -1000,7 +1034,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1000
1034
|
|
|
1001
1035
|
if (!chunk) {
|
|
1002
1036
|
DEBUG_BUILD && logger.log(`[Profiling] Failed to create profile chunk for: ${this._chunkData.id}`);
|
|
1003
|
-
this.
|
|
1037
|
+
this._resetChunkData();
|
|
1004
1038
|
return;
|
|
1005
1039
|
}
|
|
1006
1040
|
|
|
@@ -1009,7 +1043,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1009
1043
|
// the format may negatively impact the performance of the application. To avoid
|
|
1010
1044
|
// blocking for too long, enqueue the next chunk start inside the next macrotask.
|
|
1011
1045
|
// clear current chunk
|
|
1012
|
-
this.
|
|
1046
|
+
this._resetChunkData();
|
|
1013
1047
|
}
|
|
1014
1048
|
|
|
1015
1049
|
/**
|
|
@@ -1039,29 +1073,23 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1039
1073
|
});
|
|
1040
1074
|
}
|
|
1041
1075
|
|
|
1042
|
-
/**
|
|
1043
|
-
* Stops the profile and clears chunk instrumentation from global scope
|
|
1044
|
-
* @returns void
|
|
1045
|
-
*/
|
|
1046
|
-
_stopChunkProfiling(chunk) {
|
|
1047
|
-
this._teardownSpanChunkInstrumentation();
|
|
1048
|
-
return CpuProfilerBindings.stopProfiling(chunk.id, ProfileFormat.CHUNK);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
1076
|
/**
|
|
1052
1077
|
* Starts the profiler and registers the flush timer for a given chunk.
|
|
1053
1078
|
* @param chunk
|
|
1054
1079
|
*/
|
|
1055
|
-
_startChunkProfiling(
|
|
1056
|
-
|
|
1080
|
+
_startChunkProfiling() {
|
|
1081
|
+
const traceId =
|
|
1082
|
+
getCurrentScope().getPropagationContext().traceId || getIsolationScope().getPropagationContext().traceId;
|
|
1083
|
+
const chunk = this._initializeChunk(traceId);
|
|
1084
|
+
|
|
1057
1085
|
CpuProfilerBindings.startProfiling(chunk.id);
|
|
1058
1086
|
DEBUG_BUILD && logger.log(`[Profiling] starting profiling chunk: ${chunk.id}`);
|
|
1059
1087
|
|
|
1060
1088
|
chunk.timer = global.setTimeout(() => {
|
|
1061
1089
|
DEBUG_BUILD && logger.log(`[Profiling] Stopping profiling chunk: ${chunk.id}`);
|
|
1062
|
-
this.
|
|
1090
|
+
this._chunkStop();
|
|
1063
1091
|
DEBUG_BUILD && logger.log('[Profiling] Starting new profiling chunk.');
|
|
1064
|
-
setImmediate(this.
|
|
1092
|
+
setImmediate(this._chunkStart.bind(this));
|
|
1065
1093
|
}, CHUNK_INTERVAL_MS);
|
|
1066
1094
|
|
|
1067
1095
|
// Unref timeout so it doesn't keep the process alive.
|
|
@@ -1075,21 +1103,31 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1075
1103
|
_setupSpanChunkInstrumentation() {
|
|
1076
1104
|
if (!this._client) {
|
|
1077
1105
|
DEBUG_BUILD &&
|
|
1078
|
-
logger.log(
|
|
1106
|
+
logger.log(
|
|
1107
|
+
'[Profiling] Failed to initialize span profiling, sentry client was never attached to the profiler.',
|
|
1108
|
+
);
|
|
1079
1109
|
return;
|
|
1080
1110
|
}
|
|
1081
1111
|
|
|
1112
|
+
this._profilerId = uuid4();
|
|
1082
1113
|
getGlobalScope().setContext('profile', {
|
|
1083
1114
|
profiler_id: this._profilerId,
|
|
1084
1115
|
});
|
|
1116
|
+
}
|
|
1085
1117
|
|
|
1086
|
-
|
|
1118
|
+
/**
|
|
1119
|
+
* Assigns thread_id and thread name context to a profiled event if there is an active profiler session
|
|
1120
|
+
*/
|
|
1121
|
+
_onBeforeSendThreadContextAssignment(event) {
|
|
1122
|
+
if (!this._client || !this._profilerId) return;
|
|
1123
|
+
this._assignThreadIdContext(event);
|
|
1087
1124
|
}
|
|
1088
1125
|
|
|
1089
1126
|
/**
|
|
1090
1127
|
* Clear profiling information from global context when a profile is not running.
|
|
1091
1128
|
*/
|
|
1092
1129
|
_teardownSpanChunkInstrumentation() {
|
|
1130
|
+
this._profilerId = undefined;
|
|
1093
1131
|
const globalScope = getGlobalScope();
|
|
1094
1132
|
globalScope.setContext('profile', {});
|
|
1095
1133
|
}
|
|
@@ -1103,6 +1141,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1103
1141
|
startTraceID: traceId,
|
|
1104
1142
|
timer: undefined,
|
|
1105
1143
|
};
|
|
1144
|
+
return this._chunkData;
|
|
1106
1145
|
}
|
|
1107
1146
|
|
|
1108
1147
|
/**
|
|
@@ -1132,7 +1171,7 @@ class ContinuousProfiler {constructor() { ContinuousProfiler.prototype.__init.ca
|
|
|
1132
1171
|
/**
|
|
1133
1172
|
* Resets the current chunk state.
|
|
1134
1173
|
*/
|
|
1135
|
-
|
|
1174
|
+
_resetChunkData() {
|
|
1136
1175
|
this._chunkData = undefined;
|
|
1137
1176
|
}
|
|
1138
1177
|
}
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/integration.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAA+C,oBAAoB,EAAQ,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/integration.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAA+C,oBAAoB,EAAQ,MAAM,eAAe,CAAC;AA+Z7G,+BAA+B;AAC/B,eAAO,MAAM,yBAAyB,QAAQ,qBAAqB,UAAU,CA2CnD,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,2CAA+C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/profiling-node",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.31.0",
|
|
4
4
|
"description": "Official Sentry SDK for Node.js Profiling",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/profiling-node",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"test": "cross-env SENTRY_PROFILER_BINARY_DIR=lib jest --config jest.config.js"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@sentry/core": "8.
|
|
79
|
-
"@sentry/node": "8.
|
|
80
|
-
"@sentry/types": "8.
|
|
81
|
-
"@sentry/utils": "8.
|
|
78
|
+
"@sentry/core": "8.31.0",
|
|
79
|
+
"@sentry/node": "8.31.0",
|
|
80
|
+
"@sentry/types": "8.31.0",
|
|
81
|
+
"@sentry/utils": "8.31.0",
|
|
82
82
|
"detect-libc": "^2.0.2",
|
|
83
83
|
"node-abi": "^3.61.0"
|
|
84
84
|
},
|