@sentry/node-native 10.53.1 → 10.55.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/build/cjs/event-loop-block-integration.js +25 -140
- package/build/cjs/event-loop-block-integration.js.map +1 -1
- package/build/cjs/event-loop-block-watchdog.js +39 -101
- package/build/cjs/event-loop-block-watchdog.js.map +1 -1
- package/build/esm/event-loop-block-integration.js +25 -140
- package/build/esm/event-loop-block-integration.js.map +1 -1
- package/build/esm/event-loop-block-watchdog.js +39 -101
- package/build/esm/event-loop-block-watchdog.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/package.json +3 -3
|
@@ -16,123 +16,92 @@ const {
|
|
|
16
16
|
release,
|
|
17
17
|
sdkMetadata,
|
|
18
18
|
staticTags: tags,
|
|
19
|
-
tunnel
|
|
20
|
-
} = workerData
|
|
21
|
-
|
|
19
|
+
tunnel
|
|
20
|
+
} = workerData;
|
|
22
21
|
const pollInterval = threshold / POLL_RATIO;
|
|
23
|
-
const triggeredThreads = new Set();
|
|
24
|
-
|
|
22
|
+
const triggeredThreads = /* @__PURE__ */ new Set();
|
|
25
23
|
function log(...msg) {
|
|
26
24
|
if (debug) {
|
|
27
|
-
|
|
28
|
-
console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);
|
|
25
|
+
console.log("[Sentry Event Loop Blocked Watchdog]", ...msg);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
function createRateLimiter(maxEventsPerHour) {
|
|
28
|
+
function createRateLimiter(maxEventsPerHour2) {
|
|
33
29
|
let currentHour = 0;
|
|
34
30
|
let currentCount = 0;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const hour = new Date().getHours();
|
|
38
|
-
|
|
31
|
+
return function isRateLimited2() {
|
|
32
|
+
const hour = (/* @__PURE__ */ new Date()).getHours();
|
|
39
33
|
if (hour !== currentHour) {
|
|
40
34
|
currentHour = hour;
|
|
41
35
|
currentCount = 0;
|
|
42
36
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (currentCount === maxEventsPerHour) {
|
|
37
|
+
if (currentCount >= maxEventsPerHour2) {
|
|
38
|
+
if (currentCount === maxEventsPerHour2) {
|
|
46
39
|
currentCount += 1;
|
|
47
40
|
log(`Rate limit reached: ${currentCount} events in this hour`);
|
|
48
41
|
}
|
|
49
42
|
return true;
|
|
50
43
|
}
|
|
51
|
-
|
|
52
44
|
currentCount += 1;
|
|
53
45
|
return false;
|
|
54
46
|
};
|
|
55
47
|
}
|
|
56
|
-
|
|
57
48
|
const url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);
|
|
58
49
|
const transport = makeNodeTransport({
|
|
59
50
|
url,
|
|
60
51
|
recordDroppedEvent: () => {
|
|
61
|
-
|
|
62
|
-
},
|
|
52
|
+
}
|
|
63
53
|
});
|
|
64
54
|
const isRateLimited = createRateLimiter(maxEventsPerHour);
|
|
65
|
-
|
|
66
55
|
async function sendAbnormalSession(serializedSession) {
|
|
67
56
|
if (!serializedSession) {
|
|
68
57
|
return;
|
|
69
58
|
}
|
|
70
|
-
|
|
71
|
-
log('Sending abnormal session');
|
|
59
|
+
log("Sending abnormal session");
|
|
72
60
|
const session = makeSession(serializedSession);
|
|
73
|
-
|
|
74
61
|
updateSession(session, {
|
|
75
|
-
status:
|
|
76
|
-
abnormal_mechanism:
|
|
62
|
+
status: "abnormal",
|
|
63
|
+
abnormal_mechanism: "anr_foreground",
|
|
77
64
|
release,
|
|
78
|
-
environment
|
|
65
|
+
environment
|
|
79
66
|
});
|
|
80
|
-
|
|
81
67
|
const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);
|
|
82
|
-
// Log the envelope so to aid in testing
|
|
83
68
|
log(JSON.stringify(envelope));
|
|
84
|
-
|
|
85
69
|
await transport.send(envelope);
|
|
86
70
|
}
|
|
87
|
-
|
|
88
|
-
log('Started');
|
|
89
|
-
|
|
71
|
+
log("Started");
|
|
90
72
|
function prepareStackFrames(stackFrames) {
|
|
91
73
|
if (!stackFrames) {
|
|
92
|
-
return
|
|
74
|
+
return void 0;
|
|
93
75
|
}
|
|
94
|
-
|
|
95
|
-
// Strip Sentry frames and reverse the stack frames so they are in the correct order
|
|
96
76
|
const strippedFrames = stripSentryFramesAndReverse(stackFrames);
|
|
97
|
-
|
|
98
77
|
for (const frame of strippedFrames) {
|
|
99
78
|
if (!frame.filename) {
|
|
100
79
|
continue;
|
|
101
80
|
}
|
|
102
|
-
|
|
103
81
|
frame.in_app = filenameIsInApp(frame.filename);
|
|
104
|
-
|
|
105
|
-
// If we have an app root path, rewrite the filenames to be relative to the app root
|
|
106
82
|
if (appRootPath) {
|
|
107
83
|
frame.filename = normalizeUrlToBase(frame.filename, appRootPath);
|
|
108
84
|
}
|
|
109
85
|
}
|
|
110
|
-
|
|
111
86
|
return strippedFrames;
|
|
112
87
|
}
|
|
113
|
-
|
|
114
88
|
function stripFileProtocol(filename) {
|
|
115
89
|
if (!filename) {
|
|
116
|
-
return
|
|
90
|
+
return void 0;
|
|
117
91
|
}
|
|
118
|
-
return filename.replace(/^file:\/\//,
|
|
92
|
+
return filename.replace(/^file:\/\//, "");
|
|
119
93
|
}
|
|
120
|
-
|
|
121
|
-
// eslint-disable-next-line complexity
|
|
122
94
|
function applyDebugMeta(event, debugImages) {
|
|
123
95
|
if (Object.keys(debugImages).length === 0) {
|
|
124
96
|
return;
|
|
125
97
|
}
|
|
126
|
-
|
|
127
98
|
const normalisedDebugImages = appRootPath ? {} : debugImages;
|
|
128
99
|
if (appRootPath) {
|
|
129
100
|
for (const [path, debugId] of Object.entries(debugImages)) {
|
|
130
101
|
normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;
|
|
131
102
|
}
|
|
132
103
|
}
|
|
133
|
-
|
|
134
|
-
const filenameToDebugId = new Map();
|
|
135
|
-
|
|
104
|
+
const filenameToDebugId = /* @__PURE__ */ new Map();
|
|
136
105
|
for (const exception of event.exception?.values || []) {
|
|
137
106
|
for (const frame of exception.stacktrace?.frames || []) {
|
|
138
107
|
const filename = stripFileProtocol(frame.abs_path || frame.filename);
|
|
@@ -141,7 +110,6 @@ function applyDebugMeta(event, debugImages) {
|
|
|
141
110
|
}
|
|
142
111
|
}
|
|
143
112
|
}
|
|
144
|
-
|
|
145
113
|
for (const thread of event.threads?.values || []) {
|
|
146
114
|
for (const frame of thread.stacktrace?.frames || []) {
|
|
147
115
|
const filename = stripFileProtocol(frame.abs_path || frame.filename);
|
|
@@ -150,145 +118,115 @@ function applyDebugMeta(event, debugImages) {
|
|
|
150
118
|
}
|
|
151
119
|
}
|
|
152
120
|
}
|
|
153
|
-
|
|
154
121
|
if (filenameToDebugId.size > 0) {
|
|
155
122
|
const images = [];
|
|
156
123
|
for (const [code_file, debug_id] of filenameToDebugId.entries()) {
|
|
157
124
|
images.push({
|
|
158
|
-
type:
|
|
125
|
+
type: "sourcemap",
|
|
159
126
|
code_file,
|
|
160
|
-
debug_id
|
|
127
|
+
debug_id
|
|
161
128
|
});
|
|
162
129
|
}
|
|
163
130
|
event.debug_meta = { images };
|
|
164
131
|
}
|
|
165
132
|
}
|
|
166
|
-
|
|
167
|
-
function getExceptionAndThreads(
|
|
168
|
-
crashedThreadId,
|
|
169
|
-
threads,
|
|
170
|
-
) {
|
|
133
|
+
function getExceptionAndThreads(crashedThreadId, threads) {
|
|
171
134
|
const crashedThread = threads[crashedThreadId];
|
|
172
|
-
|
|
173
135
|
return {
|
|
174
136
|
exception: {
|
|
175
137
|
values: [
|
|
176
138
|
{
|
|
177
|
-
type:
|
|
139
|
+
type: "EventLoopBlocked",
|
|
178
140
|
value: `Event Loop Blocked for at least ${threshold} ms`,
|
|
179
141
|
stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },
|
|
180
142
|
// This ensures the UI doesn't say 'Crashed in' for the stack trace
|
|
181
|
-
mechanism: { type:
|
|
182
|
-
thread_id: crashedThreadId
|
|
183
|
-
}
|
|
184
|
-
]
|
|
143
|
+
mechanism: { type: "ANR" },
|
|
144
|
+
thread_id: crashedThreadId
|
|
145
|
+
}
|
|
146
|
+
]
|
|
185
147
|
},
|
|
186
148
|
threads: {
|
|
187
149
|
values: Object.entries(threads).map(([threadId, threadState]) => {
|
|
188
150
|
const crashed = threadId === crashedThreadId;
|
|
189
|
-
|
|
190
151
|
const thread = {
|
|
191
152
|
id: threadId,
|
|
192
|
-
name: threadId ===
|
|
153
|
+
name: threadId === "0" ? "main" : `worker-${threadId}`,
|
|
193
154
|
crashed,
|
|
194
155
|
current: true,
|
|
195
|
-
main: threadId ===
|
|
156
|
+
main: threadId === "0"
|
|
196
157
|
};
|
|
197
|
-
|
|
198
158
|
if (!crashed) {
|
|
199
159
|
thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };
|
|
200
160
|
}
|
|
201
|
-
|
|
202
161
|
return thread;
|
|
203
|
-
})
|
|
204
|
-
}
|
|
162
|
+
})
|
|
163
|
+
}
|
|
205
164
|
};
|
|
206
165
|
}
|
|
207
|
-
|
|
208
166
|
function applyScopeToEvent(event, scope) {
|
|
209
167
|
applyScopeDataToEvent(event, scope);
|
|
210
|
-
|
|
211
168
|
if (!event.contexts?.trace) {
|
|
212
169
|
const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;
|
|
213
170
|
event.contexts = {
|
|
214
171
|
trace: {
|
|
215
172
|
trace_id: traceId,
|
|
216
173
|
span_id: propagationSpanId || generateSpanId(),
|
|
217
|
-
parent_span_id: parentSpanId
|
|
174
|
+
parent_span_id: parentSpanId
|
|
218
175
|
},
|
|
219
|
-
...event.contexts
|
|
176
|
+
...event.contexts
|
|
220
177
|
};
|
|
221
178
|
}
|
|
222
179
|
}
|
|
223
|
-
|
|
224
180
|
async function sendBlockEvent(crashedThreadId) {
|
|
225
181
|
if (isRateLimited()) {
|
|
226
182
|
return;
|
|
227
183
|
}
|
|
228
|
-
|
|
229
184
|
const threads = captureStackTrace();
|
|
230
185
|
const crashedThread = threads[crashedThreadId];
|
|
231
|
-
|
|
232
186
|
if (!crashedThread) {
|
|
233
187
|
log(`No thread found with ID '${crashedThreadId}'`);
|
|
234
188
|
return;
|
|
235
189
|
}
|
|
236
|
-
|
|
237
190
|
try {
|
|
238
191
|
await sendAbnormalSession(crashedThread.pollState?.session);
|
|
239
192
|
} catch (error) {
|
|
240
193
|
log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);
|
|
241
194
|
}
|
|
242
|
-
|
|
243
|
-
log('Sending event');
|
|
244
|
-
|
|
195
|
+
log("Sending event");
|
|
245
196
|
const event = {
|
|
246
197
|
event_id: uuid4(),
|
|
247
198
|
contexts,
|
|
248
199
|
release,
|
|
249
200
|
environment,
|
|
250
201
|
dist,
|
|
251
|
-
platform:
|
|
252
|
-
level:
|
|
202
|
+
platform: "node",
|
|
203
|
+
level: "error",
|
|
253
204
|
tags,
|
|
254
|
-
...getExceptionAndThreads(crashedThreadId, threads)
|
|
205
|
+
...getExceptionAndThreads(crashedThreadId, threads)
|
|
255
206
|
};
|
|
256
|
-
|
|
257
|
-
const scope = crashedThread.pollState?.scope
|
|
258
|
-
? new Scope().update(crashedThread.pollState.scope).getScopeData()
|
|
259
|
-
: new Scope().getScopeData();
|
|
260
|
-
|
|
207
|
+
const scope = crashedThread.pollState?.scope ? new Scope().update(crashedThread.pollState.scope).getScopeData() : new Scope().getScopeData();
|
|
261
208
|
if (crashedThread?.asyncState?.isolationScope) {
|
|
262
|
-
// We need to rehydrate the scope from the serialized object with properties beginning with _user, etc
|
|
263
209
|
const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();
|
|
264
210
|
mergeScopeData(scope, isolationScope);
|
|
265
211
|
}
|
|
266
212
|
applyScopeToEvent(event, scope);
|
|
267
|
-
|
|
268
213
|
const allDebugImages = Object.values(threads).reduce((acc, threadState) => {
|
|
269
214
|
return { ...acc, ...threadState.pollState?.debugImages };
|
|
270
215
|
}, {});
|
|
271
|
-
|
|
272
216
|
applyDebugMeta(event, allDebugImages);
|
|
273
|
-
|
|
274
217
|
const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);
|
|
275
|
-
// Log the envelope to aid in testing
|
|
276
218
|
log(JSON.stringify(envelope));
|
|
277
|
-
|
|
278
219
|
await transport.send(envelope);
|
|
279
|
-
await transport.flush(
|
|
220
|
+
await transport.flush(2e3);
|
|
280
221
|
}
|
|
281
|
-
|
|
282
222
|
setInterval(async () => {
|
|
283
223
|
for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {
|
|
284
224
|
if (time > threshold) {
|
|
285
225
|
if (triggeredThreads.has(threadId)) {
|
|
286
226
|
continue;
|
|
287
227
|
}
|
|
288
|
-
|
|
289
228
|
log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);
|
|
290
229
|
triggeredThreads.add(threadId);
|
|
291
|
-
|
|
292
230
|
try {
|
|
293
231
|
await sendBlockEvent(threadId);
|
|
294
232
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n filenameIsInApp,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry-internal/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = crashedThread.pollState?.scope\n ? new Scope().update(crashedThread.pollState.scope).getScopeData()\n : new Scope().getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-loop-block-watchdog.js","sources":["../../src/event-loop-block-watchdog.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport type { DebugImage, Event, ScopeData, Session, StackFrame, Thread } from '@sentry/core';\nimport {\n applyScopeDataToEvent,\n createEventEnvelope,\n createSessionEnvelope,\n filenameIsInApp,\n generateSpanId,\n getEnvelopeEndpointWithUrlEncodedAuth,\n makeSession,\n mergeScopeData,\n normalizeUrlToBase,\n Scope,\n stripSentryFramesAndReverse,\n updateSession,\n uuid4,\n} from '@sentry/core';\nimport { makeNodeTransport } from '@sentry/node';\nimport { captureStackTrace, getThreadsLastSeen } from '@sentry-internal/node-native-stacktrace';\nimport type { ThreadState, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\ntype CurrentScopes = {\n isolationScope: Scope;\n};\n\nconst {\n threshold,\n appRootPath,\n contexts,\n debug,\n dist,\n dsn,\n environment,\n maxEventsPerHour,\n release,\n sdkMetadata,\n staticTags: tags,\n tunnel,\n} = workerData as WorkerStartData;\n\nconst pollInterval = threshold / POLL_RATIO;\nconst triggeredThreads = new Set<string>();\n\nfunction log(...msg: unknown[]): void {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log('[Sentry Event Loop Blocked Watchdog]', ...msg);\n }\n}\n\nfunction createRateLimiter(maxEventsPerHour: number): () => boolean {\n let currentHour = 0;\n let currentCount = 0;\n\n return function isRateLimited(): boolean {\n const hour = new Date().getHours();\n\n if (hour !== currentHour) {\n currentHour = hour;\n currentCount = 0;\n }\n\n if (currentCount >= maxEventsPerHour) {\n if (currentCount === maxEventsPerHour) {\n currentCount += 1;\n log(`Rate limit reached: ${currentCount} events in this hour`);\n }\n return true;\n }\n\n currentCount += 1;\n return false;\n };\n}\n\nconst url = getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkMetadata.sdk);\nconst transport = makeNodeTransport({\n url,\n recordDroppedEvent: () => {\n //\n },\n});\nconst isRateLimited = createRateLimiter(maxEventsPerHour);\n\nasync function sendAbnormalSession(serializedSession: Session | undefined): Promise<void> {\n if (!serializedSession) {\n return;\n }\n\n log('Sending abnormal session');\n const session = makeSession(serializedSession);\n\n updateSession(session, {\n status: 'abnormal',\n abnormal_mechanism: 'anr_foreground',\n release,\n environment,\n });\n\n const envelope = createSessionEnvelope(session, dsn, sdkMetadata, tunnel);\n // Log the envelope so to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n}\n\nlog('Started');\n\nfunction prepareStackFrames(stackFrames: StackFrame[] | undefined): StackFrame[] | undefined {\n if (!stackFrames) {\n return undefined;\n }\n\n // Strip Sentry frames and reverse the stack frames so they are in the correct order\n const strippedFrames = stripSentryFramesAndReverse(stackFrames);\n\n for (const frame of strippedFrames) {\n if (!frame.filename) {\n continue;\n }\n\n frame.in_app = filenameIsInApp(frame.filename);\n\n // If we have an app root path, rewrite the filenames to be relative to the app root\n if (appRootPath) {\n frame.filename = normalizeUrlToBase(frame.filename, appRootPath);\n }\n }\n\n return strippedFrames;\n}\n\nfunction stripFileProtocol(filename: string | undefined): string | undefined {\n if (!filename) {\n return undefined;\n }\n return filename.replace(/^file:\\/\\//, '');\n}\n\n// eslint-disable-next-line complexity\nfunction applyDebugMeta(event: Event, debugImages: Record<string, string>): void {\n if (Object.keys(debugImages).length === 0) {\n return;\n }\n\n const normalisedDebugImages = appRootPath ? {} : debugImages;\n if (appRootPath) {\n for (const [path, debugId] of Object.entries(debugImages)) {\n normalisedDebugImages[normalizeUrlToBase(path, appRootPath)] = debugId;\n }\n }\n\n const filenameToDebugId = new Map<string, string>();\n\n for (const exception of event.exception?.values || []) {\n for (const frame of exception.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n for (const thread of event.threads?.values || []) {\n for (const frame of thread.stacktrace?.frames || []) {\n const filename = stripFileProtocol(frame.abs_path || frame.filename);\n if (filename && normalisedDebugImages[filename]) {\n filenameToDebugId.set(filename, normalisedDebugImages[filename]);\n }\n }\n }\n\n if (filenameToDebugId.size > 0) {\n const images: DebugImage[] = [];\n for (const [code_file, debug_id] of filenameToDebugId.entries()) {\n images.push({\n type: 'sourcemap',\n code_file,\n debug_id,\n });\n }\n event.debug_meta = { images };\n }\n}\n\nfunction getExceptionAndThreads(\n crashedThreadId: string,\n threads: ReturnType<typeof captureStackTrace<CurrentScopes, ThreadState>>,\n): Event {\n const crashedThread = threads[crashedThreadId];\n\n return {\n exception: {\n values: [\n {\n type: 'EventLoopBlocked',\n value: `Event Loop Blocked for at least ${threshold} ms`,\n stacktrace: { frames: prepareStackFrames(crashedThread?.frames) },\n // This ensures the UI doesn't say 'Crashed in' for the stack trace\n mechanism: { type: 'ANR' },\n thread_id: crashedThreadId,\n },\n ],\n },\n threads: {\n values: Object.entries(threads).map(([threadId, threadState]) => {\n const crashed = threadId === crashedThreadId;\n\n const thread: Thread = {\n id: threadId,\n name: threadId === '0' ? 'main' : `worker-${threadId}`,\n crashed,\n current: true,\n main: threadId === '0',\n };\n\n if (!crashed) {\n thread.stacktrace = { frames: prepareStackFrames(threadState.frames) };\n }\n\n return thread;\n }),\n },\n };\n}\n\nfunction applyScopeToEvent(event: Event, scope: ScopeData): void {\n applyScopeDataToEvent(event, scope);\n\n if (!event.contexts?.trace) {\n const { traceId, parentSpanId, propagationSpanId } = scope.propagationContext;\n event.contexts = {\n trace: {\n trace_id: traceId,\n span_id: propagationSpanId || generateSpanId(),\n parent_span_id: parentSpanId,\n },\n ...event.contexts,\n };\n }\n}\n\nasync function sendBlockEvent(crashedThreadId: string): Promise<void> {\n if (isRateLimited()) {\n return;\n }\n\n const threads = captureStackTrace<CurrentScopes, ThreadState>();\n const crashedThread = threads[crashedThreadId];\n\n if (!crashedThread) {\n log(`No thread found with ID '${crashedThreadId}'`);\n return;\n }\n\n try {\n await sendAbnormalSession(crashedThread.pollState?.session);\n } catch (error) {\n log(`Failed to send abnormal session for thread '${crashedThreadId}':`, error);\n }\n\n log('Sending event');\n\n const event: Event = {\n event_id: uuid4(),\n contexts,\n release,\n environment,\n dist,\n platform: 'node',\n level: 'error',\n tags,\n ...getExceptionAndThreads(crashedThreadId, threads),\n };\n\n const scope = crashedThread.pollState?.scope\n ? new Scope().update(crashedThread.pollState.scope).getScopeData()\n : new Scope().getScopeData();\n\n if (crashedThread?.asyncState?.isolationScope) {\n // We need to rehydrate the scope from the serialized object with properties beginning with _user, etc\n const isolationScope = Object.assign(new Scope(), crashedThread.asyncState.isolationScope).getScopeData();\n mergeScopeData(scope, isolationScope);\n }\n applyScopeToEvent(event, scope);\n\n const allDebugImages: Record<string, string> = Object.values(threads).reduce((acc, threadState) => {\n return { ...acc, ...threadState.pollState?.debugImages };\n }, {});\n\n applyDebugMeta(event, allDebugImages);\n\n const envelope = createEventEnvelope(event, dsn, sdkMetadata, tunnel);\n // Log the envelope to aid in testing\n log(JSON.stringify(envelope));\n\n await transport.send(envelope);\n await transport.flush(2000);\n}\n\nsetInterval(async () => {\n for (const [threadId, time] of Object.entries(getThreadsLastSeen())) {\n if (time > threshold) {\n if (triggeredThreads.has(threadId)) {\n continue;\n }\n\n log(`Blocked thread detected '${threadId}' last polled ${time} ms ago.`);\n triggeredThreads.add(threadId);\n\n try {\n await sendBlockEvent(threadId);\n } catch (error) {\n log(`Failed to send event for thread '${threadId}':`, error);\n }\n } else {\n triggeredThreads.delete(threadId);\n }\n }\n}, pollInterval);\n"],"names":["maxEventsPerHour","isRateLimited"],"mappings":"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"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.55.0","sideEffects":false}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/node-native",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.55.0",
|
|
4
4
|
"description": "Native Tools for the Official Sentry Node.js SDK",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-native",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@sentry-internal/node-native-stacktrace": "^0.5.0",
|
|
66
|
-
"@sentry/core": "10.
|
|
67
|
-
"@sentry/node": "10.
|
|
66
|
+
"@sentry/core": "10.55.0",
|
|
67
|
+
"@sentry/node": "10.55.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/node": "^18.19.1"
|