Skip to content

Commit 606e3f0

Browse files
authored
feat(electron): Document eventLoopBlockIntegration (#14471)
The `eventLoopBlockIntegration` has now been exported from the Electron SDK. This PR updates the docs to correctly document this feature for Electron.
1 parent 4724273 commit 606e3f0

File tree

2 files changed

+94
-31
lines changed

2 files changed

+94
-31
lines changed

docs/platforms/javascript/common/configuration/integrations/event-loop-block.mdx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ pnpm add @sentry/node-native
5050

5151
## Usage
5252

53+
<PlatformSection notSupported={["javascript.electron"]}>
54+
5355
If you instrument your application via the Node.js `--import` flag, Sentry will be started and this instrumentation will be automatically applied to all worker threads.
5456

5557
`instrument.mjs`
@@ -88,6 +90,24 @@ node --import instrument.mjs app.mjs
8890
8991
If a thread is blocked for more than the configured threshold, stack traces are automatically captured for all threads and sent to Sentry.
9092
93+
</PlatformSection>
94+
95+
<PlatformSection supported={["javascript.electron"]}>
96+
97+
_(Available in version 6.9.0 and above)_
98+
99+
```javascript
100+
import * as Sentry from "@sentry/electron/main";
101+
import { eventLoopBlockIntegration } from "@sentry/electron/native";
102+
103+
Sentry.init({
104+
dsn: "___PUBLIC_DSN___",
105+
integrations: [eventLoopBlockIntegration({ threshold: 500 })],
106+
});
107+
```
108+
109+
</PlatformSection>
110+
91111
## Configuration Options
92112
93113
You can pass a configuration object to the `eventLoopBlockIntegration` to customize the behavior:
@@ -112,6 +132,7 @@ interface ThreadBlockedIntegrationOptions {
112132
staticTags: { [key: string]: Primitive };
113133
}
114134
```
135+
<PlatformSection notSupported={["javascript.electron"]}>
115136
116137
## Example Configuration
117138
@@ -132,3 +153,5 @@ Sentry.init({
132153
],
133154
});
134155
```
156+
157+
</PlatformSection>

docs/platforms/javascript/guides/electron/configuration/event-loop-block.mdx

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,73 @@ keywords:
1212
---
1313

1414
Event 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
3449
import * as Sentry from "@sentry/electron/main";
50+
import { eventLoopBlockIntegration } from "@sentry/electron/native";
3551

3652
Sentry.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
4584
import * 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
5998
interface 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

Comments
 (0)