@sentry/node-native
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"event-loop-block-integration.js","sources":["../../src/event-loop-block-integration.ts"],"sourcesContent":["import { isPromise } from 'node:util/types';\nimport { isMainThread, Worker } from 'node:worker_threads';\nimport type {\n ClientOptions,\n Contexts,\n DsnComponents,\n Event,\n EventHint,\n Integration,\n IntegrationFn,\n ScopeData,\n} from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getClient,\n getCurrentScope,\n getFilenameToDebugIdMap,\n getGlobalScope,\n getIsolationScope,\n mergeScopeData,\n} from '@sentry/core';\nimport type { NodeClient } from '@sentry/node';\nimport { registerThread, threadPoll } from '@sentry/node-native-stacktrace';\nimport type { ThreadBlockedIntegrationOptions, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\nconst INTEGRATION_NAME = 'ThreadBlocked';\nconst DEFAULT_THRESHOLD_MS = 1_000;\n\nfunction log(message: string, ...args: unknown[]): void {\n debug.log(`[Sentry Event Loop Blocked] ${message}`, ...args);\n}\n\n/**\n * Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: INTEGRATION_NAME };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nfunction getLocalScopeData(): ScopeData {\n const globalScope = getGlobalScope().getScopeData();\n const currentScope = getCurrentScope().getScopeData();\n mergeScopeData(globalScope, currentScope);\n return globalScope;\n}\n\ntype IntegrationInternal = { start: () => void; stop: () => void };\n\nfunction poll(enabled: boolean, clientOptions: ClientOptions): void {\n try {\n const currentSession = getIsolationScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n const scope = getLocalScopeData();\n // message the worker to tell it the main event loop is still running\n threadPoll(enabled, { session, scope, debugImages: getFilenameToDebugIdMap(clientOptions.stackParser) });\n } catch {\n // we ignore all errors\n }\n}\n\n/**\n * Starts polling\n */\nfunction startPolling(\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): IntegrationInternal | undefined {\n if (client.asyncLocalStorageLookup) {\n const { asyncLocalStorage, contextSymbol } = client.asyncLocalStorageLookup;\n registerThread({ asyncLocalStorage, stateLookup: ['_currentContext', contextSymbol] });\n } else {\n registerThread();\n }\n\n let enabled = true;\n\n const initOptions = client.getOptions();\n const pollInterval = (integrationOptions.threshold || DEFAULT_THRESHOLD_MS) / POLL_RATIO;\n\n // unref so timer does not block exit\n setInterval(() => poll(enabled, initOptions), pollInterval).unref();\n\n return {\n start: () => {\n enabled = true;\n },\n stop: () => {\n enabled = false;\n // poll immediately because the timer above might not get a chance to run\n // before the event loop gets blocked\n poll(enabled, initOptions);\n },\n };\n}\n\n/**\n * Starts the worker thread that will monitor the other threads.\n *\n * This function is only called in the main thread.\n */\nasync function startWorker(\n dsn: DsnComponents,\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): Promise<void> {\n const contexts = await getContexts(client);\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: debug.isEnabled(),\n dsn,\n tunnel: initOptions.tunnel,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: integrationOptions.appRootPath,\n threshold: integrationOptions.threshold || DEFAULT_THRESHOLD_MS,\n maxEventsPerHour: integrationOptions.maxEventsPerHour || 1,\n staticTags: integrationOptions.staticTags || {},\n contexts,\n };\n\n const worker = new Worker(new URL('./event-loop-block-watchdog.js', import.meta.url), {\n workerData: options,\n // We don't want any Node args like --import to be passed to the worker\n execArgv: [],\n env: { ...process.env, NODE_OPTIONS: undefined },\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('error', (err: Error) => {\n log('watchdog worker error', err);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('exit', (code: number) => {\n log('watchdog worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n}\n\nconst _eventLoopBlockIntegration = ((options: Partial<ThreadBlockedIntegrationOptions> = {}) => {\n let polling: IntegrationInternal | undefined;\n\n return {\n name: INTEGRATION_NAME,\n async afterAllSetup(client: NodeClient): Promise<void> {\n const dsn = client.getDsn();\n\n if (!dsn) {\n log('No DSN configured, skipping starting integration');\n return;\n }\n\n // Otel is not setup until after afterAllSetup returns.\n setImmediate(async () => {\n try {\n polling = startPolling(client, options);\n\n if (isMainThread) {\n await startWorker(dsn, client, options);\n }\n } catch (err) {\n log('Failed to start integration', err);\n return;\n }\n });\n },\n start() {\n polling?.start();\n },\n stop() {\n polling?.stop();\n },\n } as Integration & IntegrationInternal;\n}) satisfies IntegrationFn;\n\n/**\n * Monitors the Node.js event loop for blocking behavior and reports blocked events to Sentry.\n *\n * Uses a background worker thread to detect when the main thread is blocked for longer than\n * the configured threshold (default: 1 second).\n *\n * When instrumenting via the `--import` flag, this integration will\n * automatically monitor all worker threads as well.\n *\n * ```js\n * // instrument.mjs\n * import * as Sentry from '@sentry/node';\n * import { eventLoopBlockIntegration } from '@sentry/node-native';\n *\n * Sentry.init({\n * dsn: '__YOUR_DSN__',\n * integrations: [\n * eventLoopBlockIntegration({\n * threshold: 500, // Report blocks longer than 500ms\n * }),\n * ],\n * });\n * ```\n *\n * Start your application with:\n * ```bash\n * node --import instrument.mjs app.mjs\n * ```\n */\nexport const eventLoopBlockIntegration = defineIntegration(_eventLoopBlockIntegration);\n\nexport function disableBlockDetectionForCallback<T>(callback: () => T): T;\nexport function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;\n/**\n * Disables Event Loop Block detection for the current thread for the duration\n * of the callback.\n *\n * This utility function allows you to disable block detection during operations that\n * are expected to block the event loop, such as intensive computational tasks or\n * synchronous I/O operations.\n */\nexport function disableBlockDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return callback();\n }\n\n integration.stop();\n\n try {\n const result = callback();\n if (isPromise(result)) {\n return result.finally(() => integration.start());\n }\n\n integration.start();\n return result;\n } catch (error) {\n integration.start();\n throw error;\n }\n}\n\n/**\n * Pauses the block detection integration.\n *\n * This function pauses event loop block detection for the current thread.\n */\nexport function pauseEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.stop();\n}\n\n/**\n * Restarts the block detection integration.\n *\n * This function restarts event loop block detection for the current thread.\n */\nexport function restartEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.start();\n}\n"],"names":["debug","getGlobalScope","getCurrentScope","mergeScopeData","getIsolationScope","threadPoll","getFilenameToDebugIdMap","registerThread","POLL_RATIO","Worker","isMainThread","defineIntegration","getClient","isPromise"],"mappings":"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"} | ||
| {"version":3,"file":"event-loop-block-integration.js","sources":["../../src/event-loop-block-integration.ts"],"sourcesContent":["import { isPromise } from 'node:util/types';\nimport { isMainThread, Worker } from 'node:worker_threads';\nimport type {\n ClientOptions,\n Contexts,\n DsnComponents,\n Event,\n EventHint,\n Integration,\n IntegrationFn,\n ScopeData,\n} from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getClient,\n getCurrentScope,\n getFilenameToDebugIdMap,\n getGlobalScope,\n getIsolationScope,\n mergeScopeData,\n} from '@sentry/core';\nimport type { NodeClient } from '@sentry/node';\nimport { registerThread, threadPoll } from '@sentry/node-native-stacktrace';\nimport type { ThreadBlockedIntegrationOptions, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\nconst INTEGRATION_NAME = 'ThreadBlocked' as const;\nconst DEFAULT_THRESHOLD_MS = 1_000;\n\nfunction log(message: string, ...args: unknown[]): void {\n debug.log(`[Sentry Event Loop Blocked] ${message}`, ...args);\n}\n\n/**\n * Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: INTEGRATION_NAME };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nfunction getLocalScopeData(): ScopeData {\n const globalScope = getGlobalScope().getScopeData();\n const currentScope = getCurrentScope().getScopeData();\n mergeScopeData(globalScope, currentScope);\n return globalScope;\n}\n\ntype IntegrationInternal = { start: () => void; stop: () => void };\n\nfunction poll(enabled: boolean, clientOptions: ClientOptions): void {\n try {\n const currentSession = getIsolationScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n const scope = getLocalScopeData();\n // message the worker to tell it the main event loop is still running\n threadPoll(enabled, { session, scope, debugImages: getFilenameToDebugIdMap(clientOptions.stackParser) });\n } catch {\n // we ignore all errors\n }\n}\n\n/**\n * Starts polling\n */\nfunction startPolling(\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): IntegrationInternal | undefined {\n if (client.asyncLocalStorageLookup) {\n const { asyncLocalStorage, contextSymbol } = client.asyncLocalStorageLookup;\n registerThread({ asyncLocalStorage, stateLookup: ['_currentContext', contextSymbol] });\n } else {\n registerThread();\n }\n\n let enabled = true;\n\n const initOptions = client.getOptions();\n const pollInterval = (integrationOptions.threshold || DEFAULT_THRESHOLD_MS) / POLL_RATIO;\n\n // unref so timer does not block exit\n setInterval(() => poll(enabled, initOptions), pollInterval).unref();\n\n return {\n start: () => {\n enabled = true;\n },\n stop: () => {\n enabled = false;\n // poll immediately because the timer above might not get a chance to run\n // before the event loop gets blocked\n poll(enabled, initOptions);\n },\n };\n}\n\n/**\n * Starts the worker thread that will monitor the other threads.\n *\n * This function is only called in the main thread.\n */\nasync function startWorker(\n dsn: DsnComponents,\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): Promise<void> {\n const contexts = await getContexts(client);\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: debug.isEnabled(),\n dsn,\n tunnel: initOptions.tunnel,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: integrationOptions.appRootPath,\n threshold: integrationOptions.threshold || DEFAULT_THRESHOLD_MS,\n maxEventsPerHour: integrationOptions.maxEventsPerHour || 1,\n staticTags: integrationOptions.staticTags || {},\n contexts,\n };\n\n const worker = new Worker(new URL('./event-loop-block-watchdog.js', import.meta.url), {\n workerData: options,\n // We don't want any Node args like --import to be passed to the worker\n execArgv: [],\n env: { ...process.env, NODE_OPTIONS: undefined },\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('error', (err: Error) => {\n log('watchdog worker error', err);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('exit', (code: number) => {\n log('watchdog worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n}\n\nconst _eventLoopBlockIntegration = ((options: Partial<ThreadBlockedIntegrationOptions> = {}) => {\n let polling: IntegrationInternal | undefined;\n\n return {\n name: INTEGRATION_NAME,\n async afterAllSetup(client: NodeClient): Promise<void> {\n const dsn = client.getDsn();\n\n if (!dsn) {\n log('No DSN configured, skipping starting integration');\n return;\n }\n\n // Otel is not setup until after afterAllSetup returns.\n setImmediate(async () => {\n try {\n polling = startPolling(client, options);\n\n if (isMainThread) {\n await startWorker(dsn, client, options);\n }\n } catch (err) {\n log('Failed to start integration', err);\n return;\n }\n });\n },\n start() {\n polling?.start();\n },\n stop() {\n polling?.stop();\n },\n } as Integration & IntegrationInternal;\n}) satisfies IntegrationFn;\n\n/**\n * Monitors the Node.js event loop for blocking behavior and reports blocked events to Sentry.\n *\n * Uses a background worker thread to detect when the main thread is blocked for longer than\n * the configured threshold (default: 1 second).\n *\n * When instrumenting via the `--import` flag, this integration will\n * automatically monitor all worker threads as well.\n *\n * ```js\n * // instrument.mjs\n * import * as Sentry from '@sentry/node';\n * import { eventLoopBlockIntegration } from '@sentry/node-native';\n *\n * Sentry.init({\n * dsn: '__YOUR_DSN__',\n * integrations: [\n * eventLoopBlockIntegration({\n * threshold: 500, // Report blocks longer than 500ms\n * }),\n * ],\n * });\n * ```\n *\n * Start your application with:\n * ```bash\n * node --import instrument.mjs app.mjs\n * ```\n */\nexport const eventLoopBlockIntegration = defineIntegration(_eventLoopBlockIntegration);\n\nexport function disableBlockDetectionForCallback<T>(callback: () => T): T;\nexport function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;\n/**\n * Disables Event Loop Block detection for the current thread for the duration\n * of the callback.\n *\n * This utility function allows you to disable block detection during operations that\n * are expected to block the event loop, such as intensive computational tasks or\n * synchronous I/O operations.\n */\nexport function disableBlockDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return callback();\n }\n\n integration.stop();\n\n try {\n const result = callback();\n if (isPromise(result)) {\n return result.finally(() => integration.start());\n }\n\n integration.start();\n return result;\n } catch (error) {\n integration.start();\n throw error;\n }\n}\n\n/**\n * Pauses the block detection integration.\n *\n * This function pauses event loop block detection for the current thread.\n */\nexport function pauseEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.stop();\n}\n\n/**\n * Restarts the block detection integration.\n *\n * This function restarts event loop block detection for the current thread.\n */\nexport function restartEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.start();\n}\n"],"names":["debug","getGlobalScope","getCurrentScope","mergeScopeData","getIsolationScope","threadPoll","getFilenameToDebugIdMap","registerThread","POLL_RATIO","Worker","isMainThread","defineIntegration","getClient","isPromise"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"event-loop-block-integration.js","sources":["../../src/event-loop-block-integration.ts"],"sourcesContent":["import { isPromise } from 'node:util/types';\nimport { isMainThread, Worker } from 'node:worker_threads';\nimport type {\n ClientOptions,\n Contexts,\n DsnComponents,\n Event,\n EventHint,\n Integration,\n IntegrationFn,\n ScopeData,\n} from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getClient,\n getCurrentScope,\n getFilenameToDebugIdMap,\n getGlobalScope,\n getIsolationScope,\n mergeScopeData,\n} from '@sentry/core';\nimport type { NodeClient } from '@sentry/node';\nimport { registerThread, threadPoll } from '@sentry/node-native-stacktrace';\nimport type { ThreadBlockedIntegrationOptions, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\nconst INTEGRATION_NAME = 'ThreadBlocked';\nconst DEFAULT_THRESHOLD_MS = 1_000;\n\nfunction log(message: string, ...args: unknown[]): void {\n debug.log(`[Sentry Event Loop Blocked] ${message}`, ...args);\n}\n\n/**\n * Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: INTEGRATION_NAME };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nfunction getLocalScopeData(): ScopeData {\n const globalScope = getGlobalScope().getScopeData();\n const currentScope = getCurrentScope().getScopeData();\n mergeScopeData(globalScope, currentScope);\n return globalScope;\n}\n\ntype IntegrationInternal = { start: () => void; stop: () => void };\n\nfunction poll(enabled: boolean, clientOptions: ClientOptions): void {\n try {\n const currentSession = getIsolationScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n const scope = getLocalScopeData();\n // message the worker to tell it the main event loop is still running\n threadPoll(enabled, { session, scope, debugImages: getFilenameToDebugIdMap(clientOptions.stackParser) });\n } catch {\n // we ignore all errors\n }\n}\n\n/**\n * Starts polling\n */\nfunction startPolling(\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): IntegrationInternal | undefined {\n if (client.asyncLocalStorageLookup) {\n const { asyncLocalStorage, contextSymbol } = client.asyncLocalStorageLookup;\n registerThread({ asyncLocalStorage, stateLookup: ['_currentContext', contextSymbol] });\n } else {\n registerThread();\n }\n\n let enabled = true;\n\n const initOptions = client.getOptions();\n const pollInterval = (integrationOptions.threshold || DEFAULT_THRESHOLD_MS) / POLL_RATIO;\n\n // unref so timer does not block exit\n setInterval(() => poll(enabled, initOptions), pollInterval).unref();\n\n return {\n start: () => {\n enabled = true;\n },\n stop: () => {\n enabled = false;\n // poll immediately because the timer above might not get a chance to run\n // before the event loop gets blocked\n poll(enabled, initOptions);\n },\n };\n}\n\n/**\n * Starts the worker thread that will monitor the other threads.\n *\n * This function is only called in the main thread.\n */\nasync function startWorker(\n dsn: DsnComponents,\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): Promise<void> {\n const contexts = await getContexts(client);\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: debug.isEnabled(),\n dsn,\n tunnel: initOptions.tunnel,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: integrationOptions.appRootPath,\n threshold: integrationOptions.threshold || DEFAULT_THRESHOLD_MS,\n maxEventsPerHour: integrationOptions.maxEventsPerHour || 1,\n staticTags: integrationOptions.staticTags || {},\n contexts,\n };\n\n const worker = new Worker(new URL('./event-loop-block-watchdog.js', import.meta.url), {\n workerData: options,\n // We don't want any Node args like --import to be passed to the worker\n execArgv: [],\n env: { ...process.env, NODE_OPTIONS: undefined },\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('error', (err: Error) => {\n log('watchdog worker error', err);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('exit', (code: number) => {\n log('watchdog worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n}\n\nconst _eventLoopBlockIntegration = ((options: Partial<ThreadBlockedIntegrationOptions> = {}) => {\n let polling: IntegrationInternal | undefined;\n\n return {\n name: INTEGRATION_NAME,\n async afterAllSetup(client: NodeClient): Promise<void> {\n const dsn = client.getDsn();\n\n if (!dsn) {\n log('No DSN configured, skipping starting integration');\n return;\n }\n\n // Otel is not setup until after afterAllSetup returns.\n setImmediate(async () => {\n try {\n polling = startPolling(client, options);\n\n if (isMainThread) {\n await startWorker(dsn, client, options);\n }\n } catch (err) {\n log('Failed to start integration', err);\n return;\n }\n });\n },\n start() {\n polling?.start();\n },\n stop() {\n polling?.stop();\n },\n } as Integration & IntegrationInternal;\n}) satisfies IntegrationFn;\n\n/**\n * Monitors the Node.js event loop for blocking behavior and reports blocked events to Sentry.\n *\n * Uses a background worker thread to detect when the main thread is blocked for longer than\n * the configured threshold (default: 1 second).\n *\n * When instrumenting via the `--import` flag, this integration will\n * automatically monitor all worker threads as well.\n *\n * ```js\n * // instrument.mjs\n * import * as Sentry from '@sentry/node';\n * import { eventLoopBlockIntegration } from '@sentry/node-native';\n *\n * Sentry.init({\n * dsn: '__YOUR_DSN__',\n * integrations: [\n * eventLoopBlockIntegration({\n * threshold: 500, // Report blocks longer than 500ms\n * }),\n * ],\n * });\n * ```\n *\n * Start your application with:\n * ```bash\n * node --import instrument.mjs app.mjs\n * ```\n */\nexport const eventLoopBlockIntegration = defineIntegration(_eventLoopBlockIntegration);\n\nexport function disableBlockDetectionForCallback<T>(callback: () => T): T;\nexport function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;\n/**\n * Disables Event Loop Block detection for the current thread for the duration\n * of the callback.\n *\n * This utility function allows you to disable block detection during operations that\n * are expected to block the event loop, such as intensive computational tasks or\n * synchronous I/O operations.\n */\nexport function disableBlockDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return callback();\n }\n\n integration.stop();\n\n try {\n const result = callback();\n if (isPromise(result)) {\n return result.finally(() => integration.start());\n }\n\n integration.start();\n return result;\n } catch (error) {\n integration.start();\n throw error;\n }\n}\n\n/**\n * Pauses the block detection integration.\n *\n * This function pauses event loop block detection for the current thread.\n */\nexport function pauseEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.stop();\n}\n\n/**\n * Restarts the block detection integration.\n *\n * This function restarts event loop block detection for the current thread.\n */\nexport function restartEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.start();\n}\n"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"event-loop-block-integration.js","sources":["../../src/event-loop-block-integration.ts"],"sourcesContent":["import { isPromise } from 'node:util/types';\nimport { isMainThread, Worker } from 'node:worker_threads';\nimport type {\n ClientOptions,\n Contexts,\n DsnComponents,\n Event,\n EventHint,\n Integration,\n IntegrationFn,\n ScopeData,\n} from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getClient,\n getCurrentScope,\n getFilenameToDebugIdMap,\n getGlobalScope,\n getIsolationScope,\n mergeScopeData,\n} from '@sentry/core';\nimport type { NodeClient } from '@sentry/node';\nimport { registerThread, threadPoll } from '@sentry/node-native-stacktrace';\nimport type { ThreadBlockedIntegrationOptions, WorkerStartData } from './common';\nimport { POLL_RATIO } from './common';\n\nconst INTEGRATION_NAME = 'ThreadBlocked' as const;\nconst DEFAULT_THRESHOLD_MS = 1_000;\n\nfunction log(message: string, ...args: unknown[]): void {\n debug.log(`[Sentry Event Loop Blocked] ${message}`, ...args);\n}\n\n/**\n * Gets contexts by calling all event processors. This shouldn't be called until all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: INTEGRATION_NAME };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nfunction getLocalScopeData(): ScopeData {\n const globalScope = getGlobalScope().getScopeData();\n const currentScope = getCurrentScope().getScopeData();\n mergeScopeData(globalScope, currentScope);\n return globalScope;\n}\n\ntype IntegrationInternal = { start: () => void; stop: () => void };\n\nfunction poll(enabled: boolean, clientOptions: ClientOptions): void {\n try {\n const currentSession = getIsolationScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n const scope = getLocalScopeData();\n // message the worker to tell it the main event loop is still running\n threadPoll(enabled, { session, scope, debugImages: getFilenameToDebugIdMap(clientOptions.stackParser) });\n } catch {\n // we ignore all errors\n }\n}\n\n/**\n * Starts polling\n */\nfunction startPolling(\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): IntegrationInternal | undefined {\n if (client.asyncLocalStorageLookup) {\n const { asyncLocalStorage, contextSymbol } = client.asyncLocalStorageLookup;\n registerThread({ asyncLocalStorage, stateLookup: ['_currentContext', contextSymbol] });\n } else {\n registerThread();\n }\n\n let enabled = true;\n\n const initOptions = client.getOptions();\n const pollInterval = (integrationOptions.threshold || DEFAULT_THRESHOLD_MS) / POLL_RATIO;\n\n // unref so timer does not block exit\n setInterval(() => poll(enabled, initOptions), pollInterval).unref();\n\n return {\n start: () => {\n enabled = true;\n },\n stop: () => {\n enabled = false;\n // poll immediately because the timer above might not get a chance to run\n // before the event loop gets blocked\n poll(enabled, initOptions);\n },\n };\n}\n\n/**\n * Starts the worker thread that will monitor the other threads.\n *\n * This function is only called in the main thread.\n */\nasync function startWorker(\n dsn: DsnComponents,\n client: NodeClient,\n integrationOptions: Partial<ThreadBlockedIntegrationOptions>,\n): Promise<void> {\n const contexts = await getContexts(client);\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: debug.isEnabled(),\n dsn,\n tunnel: initOptions.tunnel,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: integrationOptions.appRootPath,\n threshold: integrationOptions.threshold || DEFAULT_THRESHOLD_MS,\n maxEventsPerHour: integrationOptions.maxEventsPerHour || 1,\n staticTags: integrationOptions.staticTags || {},\n contexts,\n };\n\n const worker = new Worker(new URL('./event-loop-block-watchdog.js', import.meta.url), {\n workerData: options,\n // We don't want any Node args like --import to be passed to the worker\n execArgv: [],\n env: { ...process.env, NODE_OPTIONS: undefined },\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('error', (err: Error) => {\n log('watchdog worker error', err);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n worker.once('exit', (code: number) => {\n log('watchdog worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n}\n\nconst _eventLoopBlockIntegration = ((options: Partial<ThreadBlockedIntegrationOptions> = {}) => {\n let polling: IntegrationInternal | undefined;\n\n return {\n name: INTEGRATION_NAME,\n async afterAllSetup(client: NodeClient): Promise<void> {\n const dsn = client.getDsn();\n\n if (!dsn) {\n log('No DSN configured, skipping starting integration');\n return;\n }\n\n // Otel is not setup until after afterAllSetup returns.\n setImmediate(async () => {\n try {\n polling = startPolling(client, options);\n\n if (isMainThread) {\n await startWorker(dsn, client, options);\n }\n } catch (err) {\n log('Failed to start integration', err);\n return;\n }\n });\n },\n start() {\n polling?.start();\n },\n stop() {\n polling?.stop();\n },\n } as Integration & IntegrationInternal;\n}) satisfies IntegrationFn;\n\n/**\n * Monitors the Node.js event loop for blocking behavior and reports blocked events to Sentry.\n *\n * Uses a background worker thread to detect when the main thread is blocked for longer than\n * the configured threshold (default: 1 second).\n *\n * When instrumenting via the `--import` flag, this integration will\n * automatically monitor all worker threads as well.\n *\n * ```js\n * // instrument.mjs\n * import * as Sentry from '@sentry/node';\n * import { eventLoopBlockIntegration } from '@sentry/node-native';\n *\n * Sentry.init({\n * dsn: '__YOUR_DSN__',\n * integrations: [\n * eventLoopBlockIntegration({\n * threshold: 500, // Report blocks longer than 500ms\n * }),\n * ],\n * });\n * ```\n *\n * Start your application with:\n * ```bash\n * node --import instrument.mjs app.mjs\n * ```\n */\nexport const eventLoopBlockIntegration = defineIntegration(_eventLoopBlockIntegration);\n\nexport function disableBlockDetectionForCallback<T>(callback: () => T): T;\nexport function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;\n/**\n * Disables Event Loop Block detection for the current thread for the duration\n * of the callback.\n *\n * This utility function allows you to disable block detection during operations that\n * are expected to block the event loop, such as intensive computational tasks or\n * synchronous I/O operations.\n */\nexport function disableBlockDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return callback();\n }\n\n integration.stop();\n\n try {\n const result = callback();\n if (isPromise(result)) {\n return result.finally(() => integration.start());\n }\n\n integration.start();\n return result;\n } catch (error) {\n integration.start();\n throw error;\n }\n}\n\n/**\n * Pauses the block detection integration.\n *\n * This function pauses event loop block detection for the current thread.\n */\nexport function pauseEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.stop();\n}\n\n/**\n * Restarts the block detection integration.\n *\n * This function restarts event loop block detection for the current thread.\n */\nexport function restartEventLoopBlockDetection(): void {\n const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as IntegrationInternal | undefined;\n\n if (!integration) {\n return;\n }\n\n integration.start();\n}\n"],"names":[],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"type":"module","version":"10.62.0","sideEffects":false} | ||
| {"type":"module","version":"10.63.0","sideEffects":false} |
@@ -32,3 +32,5 @@ import { Integration } from '@sentry/core'; | ||
| */ | ||
| export declare const eventLoopBlockIntegration: (options?: Partial<ThreadBlockedIntegrationOptions> | undefined) => Integration; | ||
| export declare const eventLoopBlockIntegration: (options?: Partial<ThreadBlockedIntegrationOptions> | undefined) => Integration & { | ||
| name: string; | ||
| }; | ||
| export declare function disableBlockDetectionForCallback<T>(callback: () => T): T; | ||
@@ -35,0 +37,0 @@ export declare function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>; |
@@ -32,3 +32,5 @@ import type { Integration } from '@sentry/core'; | ||
| */ | ||
| export declare const eventLoopBlockIntegration: (options?: Partial<ThreadBlockedIntegrationOptions> | undefined) => Integration; | ||
| export declare const eventLoopBlockIntegration: (options?: Partial<ThreadBlockedIntegrationOptions> | undefined) => Integration & { | ||
| name: string; | ||
| }; | ||
| export declare function disableBlockDetectionForCallback<T>(callback: () => T): T; | ||
@@ -35,0 +37,0 @@ export declare function disableBlockDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"event-loop-block-integration.d.ts","sourceRoot":"","sources":["../../src/event-loop-block-integration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAMV,WAAW,EAGZ,MAAM,cAAc,CAAC;AAatB,OAAO,KAAK,EAAE,+BAA+B,EAAmB,MAAM,UAAU,CAAC;AAuLjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,yBAAyB,iFAAgD,CAAC;AAEvF,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1E,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAgC5F;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAQnD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAQrD"} | ||
| {"version":3,"file":"event-loop-block-integration.d.ts","sourceRoot":"","sources":["../../src/event-loop-block-integration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAMV,WAAW,EAGZ,MAAM,cAAc,CAAC;AAatB,OAAO,KAAK,EAAE,+BAA+B,EAAmB,MAAM,UAAU,CAAC;AAuLjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,yBAAyB;;CAAgD,CAAC;AAEvF,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1E,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAgC5F;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAQnD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAQrD"} |
+3
-3
| { | ||
| "name": "@sentry/node-native", | ||
| "version": "10.62.0", | ||
| "version": "10.63.0", | ||
| "description": "Native Tools for the Official Sentry Node.js SDK", | ||
@@ -66,4 +66,4 @@ "repository": "git://github.com/getsentry/sentry-javascript.git", | ||
| "@sentry/node-native-stacktrace": "^0.5.1", | ||
| "@sentry/core": "10.62.0", | ||
| "@sentry/node": "10.62.0" | ||
| "@sentry/core": "10.63.0", | ||
| "@sentry/node": "10.63.0" | ||
| }, | ||
@@ -70,0 +70,0 @@ "devDependencies": { |
104812
0.06%1013
0.4%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated