Skip to content

Commit 2e1ddb0

Browse files
Enhance ANR integration documentation and add detailed comments
Co-authored-by: aprasad <[email protected]>
1 parent 81e0e9b commit 2e1ddb0

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

packages/node/src/integrations/anr/common.ts

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,73 @@
11
import type { Contexts, DsnComponents, Primitive, SdkMetadata } from '@sentry/core';
22

33
/**
4+
* Configuration options for the ANR (Application Not Responding) integration.
5+
*
6+
* These options control how the ANR detection system monitors the Node.js event loop
7+
* and reports blocking events.
8+
*
49
* @deprecated The ANR integration has been deprecated. Use `eventLoopBlockIntegration` from `@sentry/node-native` instead.
10+
* @see {@link https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/application-not-responding/}
511
*/
612
export interface AnrIntegrationOptions {
713
/**
8-
* Interval to send heartbeat messages to the ANR worker.
14+
* Interval to send heartbeat messages to the ANR worker thread.
915
*
10-
* Defaults to 50ms.
16+
* The main thread sends heartbeat messages to the worker thread at this interval
17+
* to indicate that the event loop is still responsive. Lower values provide more
18+
* precise detection but may increase overhead.
19+
*
20+
* @default 50 (milliseconds)
1121
*/
1222
pollInterval: number;
23+
1324
/**
1425
* Threshold in milliseconds to trigger an ANR event.
1526
*
16-
* Defaults to 5000ms.
27+
* When the worker thread doesn't receive a heartbeat message for this duration,
28+
* it considers the main thread to be blocked and triggers an ANR event.
29+
*
30+
* @default 5000 (milliseconds)
1731
*/
1832
anrThreshold: number;
33+
1934
/**
2035
* Whether to capture a stack trace when the ANR event is triggered.
2136
*
22-
* Defaults to `false`.
37+
* When enabled, uses the Node.js inspector API to capture the stack trace
38+
* of the blocking code. This provides more detailed information about what
39+
* caused the ANR but requires the debugger to be enabled.
40+
*
41+
* **Note:** This opens the inspector API and required ports.
2342
*
24-
* This uses the node debugger which enables the inspector API and opens the required ports.
43+
* @default false
2544
*/
2645
captureStackTrace: boolean;
46+
2747
/**
28-
* Maximum number of ANR events to send.
48+
* Maximum number of ANR events to send per application session.
49+
*
50+
* Once this limit is reached, the ANR worker thread will exit to prevent
51+
* sending duplicate events. This helps avoid spamming Sentry with repeated
52+
* ANR events from the same blocking issue.
2953
*
30-
* Defaults to 1.
54+
* @default 1
3155
*/
3256
maxAnrEvents: number;
57+
3358
/**
34-
* Tags to include with ANR events.
59+
* Static tags to include with all ANR events.
60+
*
61+
* These tags will be attached to every ANR event sent by this integration,
62+
* useful for categorizing or filtering ANR events in Sentry.
3563
*/
3664
staticTags: { [key: string]: Primitive };
65+
3766
/**
3867
* @ignore Internal use only.
3968
*
4069
* If this is supplied, stack frame filenames will be rewritten to be relative to this path.
70+
* This is used internally for better stack trace readability.
4171
*/
4272
appRootPath: string | undefined;
4373
}

packages/node/src/integrations/anr/index.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,55 @@ const _anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {
117117
type AnrReturn = (options?: Partial<AnrIntegrationOptions>) => Integration & AnrInternal;
118118

119119
/**
120+
* Application Not Responding (ANR) integration for Node.js applications.
121+
*
122+
* Detects when the Node.js main thread event loop is blocked for more than the configured
123+
* threshold (5 seconds by default) and reports these as Sentry events.
124+
*
125+
* ## How it works
126+
*
127+
* ANR detection uses a worker thread to monitor the event loop in the main app thread.
128+
* The main app thread sends a heartbeat message to the ANR worker thread every 50ms by default.
129+
* If the ANR worker does not receive a heartbeat message for the configured threshold duration,
130+
* it triggers an ANR event.
131+
*
132+
* ## Requirements
133+
*
134+
* - Node.js 16.17.0 or higher
135+
* - Only supported in the Node.js runtime (not browsers)
136+
* - Not supported for Node.js clusters
137+
*
138+
* ## Performance Impact
139+
*
140+
* Overhead should be minimal:
141+
* - Main thread: Only polling the ANR worker over IPC every 50ms
142+
* - Worker thread: Consumes around 10-20 MB of RAM
143+
* - When ANR detected: Brief pause in debugger to capture stack trace (negligible compared to the blocking)
144+
*
145+
* ## Configuration Options
146+
*
147+
* - `pollInterval`: Interval to send heartbeat messages (default: 50ms)
148+
* - `anrThreshold`: Threshold in milliseconds to trigger an ANR event (default: 5000ms)
149+
* - `captureStackTrace`: Whether to capture stack traces using the Node.js inspector API (default: false)
150+
* - `maxAnrEvents`: Maximum number of ANR events to send (default: 1)
151+
* - `staticTags`: Tags to include with ANR events
152+
*
153+
* @example
154+
* ```javascript
155+
* Sentry.init({
156+
* dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
157+
* integrations: [
158+
* Sentry.anrIntegration({
159+
* anrThreshold: 5000,
160+
* captureStackTrace: true,
161+
* pollInterval: 50,
162+
* }),
163+
* ],
164+
* });
165+
* ```
166+
*
120167
* @deprecated The ANR integration has been deprecated. Use `eventLoopBlockIntegration` from `@sentry/node-native` instead.
168+
* @see {@link https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/application-not-responding/}
121169
*/
122170
export const anrIntegration = defineIntegration(_anrIntegration) as AnrReturn;
123171

@@ -232,8 +280,48 @@ async function _startWorker(
232280
export function disableAnrDetectionForCallback<T>(callback: () => T): T;
233281
export function disableAnrDetectionForCallback<T>(callback: () => Promise<T>): Promise<T>;
234282
/**
235-
* Disables ANR detection for the duration of the callback
283+
* Temporarily disables ANR detection for the duration of a callback function.
284+
*
285+
* This utility function allows you to disable ANR detection during operations that
286+
* are expected to block the event loop, such as intensive computational tasks or
287+
* synchronous I/O operations.
288+
*
289+
* ## Use Cases
290+
*
291+
* - CPU-intensive operations that legitimately block the event loop
292+
* - Synchronous file operations or database queries
293+
* - Intentional blocking operations during application startup
294+
* - Long-running computations that should not trigger ANR events
295+
*
296+
* ## Behavior
297+
*
298+
* - **Synchronous callbacks**: ANR detection is disabled before the callback runs
299+
* and re-enabled immediately after it completes
300+
* - **Asynchronous callbacks**: ANR detection is disabled before the callback runs
301+
* and re-enabled after the Promise resolves or rejects
302+
* - **No ANR integration**: If the ANR integration is not active, the callback
303+
* runs normally without any modifications
304+
*
305+
* @example
306+
* ```javascript
307+
* // For synchronous operations
308+
* const result = disableAnrDetectionForCallback(() => {
309+
* // Perform CPU-intensive work that might block for several seconds
310+
* return performHeavyComputation();
311+
* });
312+
*
313+
* // For asynchronous operations
314+
* const result = await disableAnrDetectionForCallback(async () => {
315+
* // Perform async work without ANR detection
316+
* return await heavyAsyncOperation();
317+
* });
318+
* ```
319+
*
320+
* @param callback - The function to execute with ANR detection disabled
321+
* @returns The result of the callback function
322+
*
236323
* @deprecated The ANR integration has been deprecated. Use `eventLoopBlockIntegration` from `@sentry/node-native` instead.
324+
* @see {@link https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/application-not-responding/}
237325
*/
238326
export function disableAnrDetectionForCallback<T>(callback: () => T | Promise<T>): T | Promise<T> {
239327
const integration = getClient()?.getIntegrationByName(INTEGRATION_NAME) as AnrInternal | undefined;

0 commit comments

Comments
 (0)