@sentry/node
Version:
Sentry Node SDK using OpenTelemetry for performance instrumentation
107 lines (103 loc) • 8.08 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const node_worker_threads = require('node:worker_threads');
const core = require('@sentry/core');
const debug = require('../../utils/debug.js');
const common = require('./common.js');
const base64WorkerScript = "LyohIEBzZW50cnkvbm9kZSAxMS4xMC4wICg5ZTMzNjYwKSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQgKi8KaW1wb3J0e1Nlc3Npb24gYXMgZX1mcm9tIm5vZGU6aW5zcGVjdG9yL3Byb21pc2VzIjtpbXBvcnR7d29ya2VyRGF0YSBhcyB0fWZyb20ibm9kZTp3b3JrZXJfdGhyZWFkcyI7Y29uc3Qgbj1nbG9iYWxUaGlzLGk9e307Y29uc3Qgbz0iX19TRU5UUllfRVJST1JfTE9DQUxfVkFSSUFCTEVTX18iO2NvbnN0IGE9dDtmdW5jdGlvbiBzKC4uLmUpe2EuZGVidWcmJmZ1bmN0aW9uKGUpe2lmKCEoImNvbnNvbGUiaW4gbikpcmV0dXJuIGUoKTtjb25zdCB0PW4uY29uc29sZSxvPXt9LGE9T2JqZWN0LmtleXMoaSk7YS5mb3JFYWNoKGU9Pntjb25zdCBuPWlbZV07b1tlXT10W2VdLHRbZV09bn0pO3RyeXtyZXR1cm4gZSgpfWZpbmFsbHl7YS5mb3JFYWNoKGU9Pnt0W2VdPW9bZV19KX19KCgpPT5jb25zb2xlLmxvZygiW0xvY2FsVmFyaWFibGVzIFdvcmtlcl0iLC4uLmUpKX1hc3luYyBmdW5jdGlvbiBjKGUsdCxuLGkpe2NvbnN0IG89YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KTtpW25dPW8ucmVzdWx0LmZpbHRlcihlPT4ibGVuZ3RoIiE9PWUubmFtZSYmIWlzTmFOKHBhcnNlSW50KGUubmFtZSwxMCkpKS5zb3J0KChlLHQpPT5wYXJzZUludChlLm5hbWUsMTApLXBhcnNlSW50KHQubmFtZSwxMCkpLm1hcChlPT5lLnZhbHVlPy52YWx1ZSl9YXN5bmMgZnVuY3Rpb24gcihlLHQsbixpKXtjb25zdCBvPWF3YWl0IGUucG9zdCgiUnVudGltZS5nZXRQcm9wZXJ0aWVzIix7b2JqZWN0SWQ6dCxvd25Qcm9wZXJ0aWVzOiEwfSk7aVtuXT1vLnJlc3VsdC5tYXAoZT0+W2UubmFtZSxlLnZhbHVlPy52YWx1ZV0pLnJlZHVjZSgoZSxbdCxuXSk9PihlW3RdPW4sZSkse30pfWZ1bmN0aW9uIHUoZSx0KXtlLnZhbHVlJiYoInZhbHVlImluIGUudmFsdWU/dm9pZCAwPT09ZS52YWx1ZS52YWx1ZXx8bnVsbD09PWUudmFsdWUudmFsdWU/dFtlLm5hbWVdPWA8JHtlLnZhbHVlLnZhbHVlfT5gOnRbZS5uYW1lXT1lLnZhbHVlLnZhbHVlOiJkZXNjcmlwdGlvbiJpbiBlLnZhbHVlJiYiZnVuY3Rpb24iIT09ZS52YWx1ZS50eXBlP3RbZS5uYW1lXT1gPCR7ZS52YWx1ZS5kZXNjcmlwdGlvbn0+YDoidW5kZWZpbmVkIj09PWUudmFsdWUudHlwZSYmKHRbZS5uYW1lXT0iPHVuZGVmaW5lZD4iKSl9YXN5bmMgZnVuY3Rpb24gbChlLHQpe2NvbnN0IG49YXdhaXQgZS5wb3N0KCJSdW50aW1lLmdldFByb3BlcnRpZXMiLHtvYmplY3RJZDp0LG93blByb3BlcnRpZXM6ITB9KSxpPXt9O2Zvcihjb25zdCB0IG9mIG4ucmVzdWx0KWlmKHQudmFsdWU/Lm9iamVjdElkJiYiQXJyYXkiPT09dC52YWx1ZS5jbGFzc05hbWUpe2NvbnN0IG49dC52YWx1ZS5vYmplY3RJZDthd2FpdCBjKGUsbix0Lm5hbWUsaSl9ZWxzZSBpZih0LnZhbHVlPy5vYmplY3RJZCYmIk9iamVjdCI9PT10LnZhbHVlLmNsYXNzTmFtZSl7Y29uc3Qgbj10LnZhbHVlLm9iamVjdElkO2F3YWl0IHIoZSxuLHQubmFtZSxpKX1lbHNlIHQudmFsdWUmJnUodCxpKTtyZXR1cm4gaX1sZXQgZjsoYXN5bmMgZnVuY3Rpb24oKXtjb25zdCB0PW5ldyBlO3QuY29ubmVjdFRvTWFpblRocmVhZCgpLHMoIkNvbm5lY3RlZCB0byBtYWluIHRocmVhZCIpO2xldCBuPSExO3Qub24oIkRlYnVnZ2VyLnJlc3VtZWQiLCgpPT57bj0hMX0pLHQub24oIkRlYnVnZ2VyLnBhdXNlZCIsZT0+e249ITAsYXN5bmMgZnVuY3Rpb24oZSx7cmVhc29uOnQsZGF0YTp7b2JqZWN0SWQ6bn0sY2FsbEZyYW1lczppfSl7aWYoImV4Y2VwdGlvbiIhPT10JiYicHJvbWlzZVJlamVjdGlvbiIhPT10KXJldHVybjtpZihmPy4oKSxudWxsPT1uKXJldHVybjtjb25zdCBhPVtdO2ZvcihsZXQgdD0wO3Q8aS5sZW5ndGg7dCsrKXtjb25zdHtzY29wZUNoYWluOm4sZnVuY3Rpb25OYW1lOm8sdGhpczpzfT1pW3RdLGM9bi5maW5kKGU9PiJsb2NhbCI9PT1lLnR5cGUpLHI9Imdsb2JhbCIhPT1zLmNsYXNzTmFtZSYmcy5jbGFzc05hbWU/YCR7cy5jbGFzc05hbWV9LiR7b31gOm87aWYodm9pZCAwPT09Yz8ub2JqZWN0Lm9iamVjdElkKWFbdF09e2Z1bmN0aW9uOnJ9O2Vsc2V7Y29uc3Qgbj1hd2FpdCBsKGUsYy5vYmplY3Qub2JqZWN0SWQpO2FbdF09e2Z1bmN0aW9uOnIsdmFyczpufX19YXdhaXQgZS5wb3N0KCJSdW50aW1lLmNhbGxGdW5jdGlvbk9uIix7ZnVuY3Rpb25EZWNsYXJhdGlvbjpgZnVuY3Rpb24oKSB7IHRoaXMuJHtvfSA9IHRoaXMuJHtvfSB8fCAke0pTT04uc3RyaW5naWZ5KGEpfTsgfWAsc2lsZW50OiEwLG9iamVjdElkOm59KSxhd2FpdCBlLnBvc3QoIlJ1bnRpbWUucmVsZWFzZU9iamVjdCIse29iamVjdElkOm59KX0odCxlLnBhcmFtcykudGhlbihhc3luYygpPT57biYmYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKX0sYXN5bmMgZT0+e24mJmF3YWl0IHQucG9zdCgiRGVidWdnZXIucmVzdW1lIil9KX0pLGF3YWl0IHQucG9zdCgiRGVidWdnZXIuZW5hYmxlIik7Y29uc3QgaT0hMSE9PWEuY2FwdHVyZUFsbEV4Y2VwdGlvbnM7aWYoYXdhaXQgdC5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOmk/ImFsbCI6InVuY2F1Z2h0In0pLGkpe2NvbnN0IGU9YS5tYXhFeGNlcHRpb25zUGVyU2Vjb25kfHw1MDtmPWZ1bmN0aW9uKGUsdCxuKXtsZXQgaT0wLG89NSxhPTA7cmV0dXJuIHNldEludGVydmFsKCgpPT57MD09PWE/aT5lJiYobyo9MixuKG8pLG8+ODY0MDAmJihvPTg2NDAwKSxhPW8pOihhLT0xLDA9PT1hJiZ0KCkpLGk9MH0sMWUzKS51bnJlZigpLCgpPT57aSs9MX19KGUsYXN5bmMoKT0+e3MoIlJhdGUtbGltaXQgbGlmdGVkLiIpLGF3YWl0IHQucG9zdCgiRGVidWdnZXIuc2V0UGF1c2VPbkV4Y2VwdGlvbnMiLHtzdGF0ZToiYWxsIn0pfSxhc3luYyBlPT57cyhgUmF0ZS1saW1pdCBleGNlZWRlZC4gRGlzYWJsaW5nIGNhcHR1cmluZyBvZiBjYXVnaHQgZXhjZXB0aW9ucyBmb3IgJHtlfSBzZWNvbmRzLmApLGF3YWl0IHQucG9zdCgiRGVidWdnZXIuc2V0UGF1c2VPbkV4Y2VwdGlvbnMiLHtzdGF0ZToidW5jYXVnaHQifSl9KX19KSgpLmNhdGNoKGU9PntzKCJGYWlsZWQgdG8gc3RhcnQgZGVidWdnZXIiLGUpfSksc2V0SW50ZXJ2YWwoKCk9Pnt9LDFlNCk7";
function log(...args) {
core.debug.log("[LocalVariables]", ...args);
}
const localVariablesAsyncIntegration = core.defineIntegration(((integrationOptions = {}) => {
function addLocalVariablesToException(exception, localVariables, behavior) {
if (behavior === false) {
return;
}
const frames = (exception.stacktrace?.frames || []).filter((frame) => frame.function !== "new Promise");
for (let i = 0; i < frames.length; i++) {
const frameIndex = frames.length - i - 1;
const frameLocalVariables = localVariables[i];
const frame = frames[frameIndex];
if (!frame || !frameLocalVariables) {
break;
}
if (
// We need to have vars to add
frameLocalVariables.vars === void 0 || // Only skip out-of-app frames if includeOutOfAppFrames is not true
frame.in_app === false && integrationOptions.includeOutOfAppFrames !== true || // The function names need to match
!common.functionNamesMatch(frame.function, frameLocalVariables.function)
) {
continue;
}
frame.vars = common.filterFrameVariables(frameLocalVariables.vars, behavior);
}
}
function addLocalVariablesToEvent(event, hint) {
if (hint.originalException && typeof hint.originalException === "object" && common.LOCAL_VARIABLES_KEY in hint.originalException && Array.isArray(hint.originalException[common.LOCAL_VARIABLES_KEY])) {
const behavior = core.getClient()?.getDataCollectionOptions().stackFrameVariables ?? true;
for (const exception of event.exception?.values || []) {
addLocalVariablesToException(exception, hint.originalException[common.LOCAL_VARIABLES_KEY], behavior);
}
hint.originalException[common.LOCAL_VARIABLES_KEY] = void 0;
}
return event;
}
async function startInspector() {
const inspector = await import('node:inspector');
if (!inspector.url()) {
inspector.open(0);
}
}
function startWorker(options) {
const worker = new node_worker_threads.Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {
workerData: options,
// We don't want any Node args to be passed to the worker
execArgv: [],
env: { ...process.env, NODE_OPTIONS: void 0 }
});
process.on("exit", () => {
worker.terminate();
});
worker.once("error", (err) => {
log("Worker error", err);
});
worker.once("exit", (code) => {
log("Worker exit", code);
});
worker.unref();
}
return {
name: "LocalVariablesAsync",
async setup(client) {
const clientOptions = client.getOptions();
if (!clientOptions.includeLocalVariables) {
return;
}
if (await debug.isDebuggerEnabled()) {
core.debug.warn("Local variables capture has been disabled because the debugger was already enabled");
return;
}
const options = {
...integrationOptions,
debug: core.debug.isEnabled()
};
startInspector().then(
() => {
try {
startWorker(options);
} catch (e) {
core.debug.error("Failed to start worker", e);
}
},
(e) => {
core.debug.error("Failed to start inspector", e);
}
);
},
processEvent(event, hint) {
return addLocalVariablesToEvent(event, hint);
}
};
}));
exports.base64WorkerScript = base64WorkerScript;
exports.localVariablesAsyncIntegration = localVariablesAsyncIntegration;
//# sourceMappingURL=local-variables-async.js.map