@@ -12,34 +12,73 @@ keywords:
1212---
1313
1414Event Loop Block errors, or Application Not Responding (ANR) errors are
15- triggered when the Electron main or renderer processes event loop is blocked for more than
16- five seconds. The Electron SDK reports ANR errors as Sentry events and can
17- optionally attach a stack trace of the blocking code to the ANR event.
15+ triggered when the Electron main or renderer processes event loop is blocked for
16+ more than the configured threshold. The Electron SDK reports ANR errors as
17+ Sentry events and can attach a stack trace of the blocking code to the ANR
18+ event.
1819
1920<Include name = " feature-stage-beta.mdx" />
2021
21- _ (Available in version 4.17 .0 and above)_
22+ _ (Available in version 6.9 .0 and above)_
2223
23- <Alert >
24+ Event loop blocked detection can be individually enabled for the main and
25+ renderer processes.
2426
25- ANR detection requires Electron v22 or higher.
27+ # Main Process:
2628
27- </ Alert >
29+ ## Installation
2830
29- ANR tracking can be individually enabled for the main and renderer processes.
31+ Install ` @sentry/node-native ` to use the ` eventLoopBlockIntegration ` in the main
32+ process.
3033
31- For the main process:
34+ ``` bash {tabTitle:npm}
35+ npm install @sentry/node-native
36+ ```
37+
38+ ``` bash {tabTitle:yarn}
39+ yarn add @sentry/node-native
40+ ```
41+
42+ ``` bash {tabTitle:pnpm}
43+ pnpm add @sentry/node-native
44+ ```
45+
46+ ## Usage
3247
3348``` javascript
3449import * as Sentry from " @sentry/electron/main" ;
50+ import { eventLoopBlockIntegration } from " @sentry/electron/native" ;
3551
3652Sentry .init ({
3753 dsn: " ___PUBLIC_DSN___" ,
38- integrations: [Sentry . anrIntegration ({ captureStackTrace : true })],
54+ integrations: [eventLoopBlockIntegration ({ threshold : 500 })],
3955});
4056```
4157
42- For renderer processes:
58+ ## Configuration options
59+
60+ ``` typescript
61+ export interface ThreadBlockedIntegrationOptions {
62+ /**
63+ * Threshold in milliseconds to trigger an event.
64+ *
65+ * Defaults to 1000ms.
66+ */
67+ threshold: number ;
68+ /**
69+ * Maximum number of blocked events to send per clock hour.
70+ *
71+ * Defaults to 1.
72+ */
73+ maxEventsPerHour: number ;
74+ /**
75+ * Tags to include with blocked events.
76+ */
77+ staticTags: { [key : string ]: Primitive };
78+ }
79+ ```
80+
81+ # Renderer Processes:
4382
4483``` javascript
4584import * as Sentry from " @sentry/electron/renderer" ;
@@ -52,8 +91,8 @@ Sentry.init({
5291
5392## Configuration options
5493
55- You can pass a configuration object to both the ` Anr ` integration and the
56- ` anrDetection ` renderer option to customize the ANR detection behavior.
94+ You can pass a configuration object for ` anrDetection ` in the renderer to
95+ customize the ANR detection behavior.
5796
5897``` Typescript
5998interface Options {
@@ -79,21 +118,22 @@ interface Options {
79118}
80119```
81120
82- ## Application Not Responding (ANR) Implementation and Overhead
83-
84- ANR detection in the Electron main process uses a worker thread to monitor the event loop
85- in the main app thread. The main app thread sends a heartbeat message to the ANR
86- worker thread every 50ms. If the ANR worker does not receive a heartbeat message
87- for 5 seconds, it triggers an ANR event. If the ` captureStackTrace ` option is
88- enabled, the ANR worker uses the ` inspector ` module to capture stack traces via the [ v8
89- inspector API] ( https://nodejs.org/api/inspector.html ) .
90-
91- Once an ANR event is reported, the ANR worker thread exits to prevent further
92- duplicate events and the main app thread will continue to run as usual.
93-
94- Overhead from Node.js ANR tracking should be minimal. With no ANR detected, the
95- only overhead in the main app thread is polling the ANR worker over IPC every 50ms by
96- default. The ANR worker thread consumes around 10-20 MB of RAM to keep track of
97- the polling. Once an ANR has been detected, the main thread is paused briefly
98- in the debugger to capture the stack trace frames. At this point, the event loop
99- has been blocked for seconds so the debugging overhead is negligible.
121+ ## Event Loop Block Detection Implementation and Overhead
122+
123+ In the main process, the ` eventLoopBlockIntegration ` uses a native module to
124+ track threads and capture stack traces via v8's native APIs. A worker thread is
125+ used to capture events even if the main thread is blocked. Overhead with no
126+ event loop blocking should be minimal. Each thread notifies the native module
127+ that it is alive every ` threshold / 2 ` milliseconds. Once an event loop block is
128+ detected, v8's native APIs are used to pause all threads and capture stack
129+ traces. The pause time is considered inconsequential if the event loop has
130+ already been blocked for hundreds of milliseconds.
131+
132+ In the renderer processes, a similar polling mechanism is used to detect event
133+ loop blocks. In Electron v34 or newer, the
134+ [ ` frame.collectJavaScriptCallStack() ` ] ( https://www.electronjs.org/docs/latest/api/web-frame-main#framecollectjavascriptcallstack-experimental )
135+ API is used to capture stack traces when an event loop block is detected. In
136+ older Electron versions, the ` v8 ` inspector API is used to capture stack traces.
137+ The inspector API can have a slight negative impact on performance since it can
138+ cause v8 to de-optimize some code paths. For this reason we recommend updating
139+ to Electron v34 or newer to use this feature in production.
0 commit comments