Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ keywords:
]
---

Application Not Responding (ANR) errors, or Event Loop Stall errors, are triggered when the Node.js main thread event loop of an application is blocked for more than five seconds. The Node SDK reports ANR errors as Sentry events and can optionally attach a stack trace of the blocking code to the ANR event.
Application Not Responding (ANR) errors, or Event Loop Stall errors, are triggered when the Node.js main thread event loop of an application is blocked for more than a specified threshold. The Node SDK reports ANR errors as Sentry events and can optionally attach a stack trace of the blocking code to the ANR event.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capturing stack traces is not optional in the new integration


<Include name="feature-stage-beta.mdx" />

Expand All @@ -42,9 +42,33 @@ ANR detection is not supported for [Node.js clusters](https://nodejs.org/api/clu

</Alert>

## Event Loop Block Integration (Recommended)

For the best performance and comprehensive monitoring, we recommend using the [`eventLoopBlockIntegration`](./integrations/event-loop-block) from the `@sentry/node-native` package. This integration can monitor all threads in your Node.js application and provides better performance compared to the deprecated ANR integration.

```javascript
import * as Sentry from "@sentry/node";
import { eventLoopBlockIntegration } from "@sentry/node-native";

Sentry.init({
dsn: "___PUBLIC_DSN___",
integrations: [eventLoopBlockIntegration({ threshold: 1000 })],
});
```

For detailed usage instructions and configuration options, see the [`eventLoopBlockIntegration`](./integrations/event-loop-block) documentation.

## Deprecated ANR Integration

<Alert type="warning">

**Deprecated**: The `anrIntegration` is deprecated. Please use the [`eventLoopBlockIntegration`](./integrations/event-loop-block) instead for better performance and more comprehensive monitoring.

</Alert>

_(Available in version 7.91.0 and above)_

To enable ANR detection, add the `Anr` integration from the `@sentry/node` package.
The legacy ANR integration is still available but deprecated. If you're currently using it, we recommend migrating to the new `eventLoopBlockIntegration`.

<Alert>

Expand All @@ -61,9 +85,9 @@ Sentry.init({

![Example of an ANR error event](./img/anr-node-example.png)

## Configuration options
### Legacy ANR Configuration Options

You can pass a configuration object to the `Anr` integration to customize the ANR detection behavior.
The deprecated ANR integration supports the following configuration options:

```ts
interface Options {
Expand All @@ -90,9 +114,9 @@ interface Options {
}
```

## ANR Implementation and Overhead
### Legacy ANR Implementation and Overhead

ANR detection with the Node SDK uses a worker thread to monitor the event loop
ANR detection with the legacy Node SDK uses a worker thread to monitor the event loop
in the main app thread. The main app thread sends a heartbeat message to the ANR
worker thread every 50ms. If the ANR worker does not receive a heartbeat message
for 5 seconds, it triggers an ANR event. If the `captureStackTrace` option is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ supported:
- javascript.tanstackstart-react
---

<Alert type="warning">

**Deprecated**: This integration is deprecated. Please use the [`eventLoopBlockIntegration`](./event-loop-block) instead for better performance and more comprehensive monitoring.

</Alert>

<Alert>

This integration only works in the Node.js runtime.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
title: Event Loop Block
description: "Monitor for blocked event loops in all threads of a Node.js application."
supported:
- javascript.node
- javascript.aws-lambda
- javascript.azure-functions
- javascript.connect
- javascript.express
- javascript.fastify
- javascript.gcp-functions
- javascript.hapi
- javascript.hono
- javascript.koa
- javascript.nestjs
- javascript.electron
- javascript.nextjs
- javascript.nuxt
- javascript.solidstart
- javascript.sveltekit
- javascript.remix
- javascript.react-router
- javascript.astro
- javascript.tanstackstart-react
---

<Alert>

This integration only works in the Node.js runtime.

</Alert>

_Import name: `eventLoopBlockIntegration` from `@sentry/node-native`_

The `eventLoopBlockIntegration` can be used to monitor for blocked event loops in all threads of a Node.js application. This integration provides better performance and more comprehensive monitoring compared to the deprecated [`anrIntegration`](./anr).

## Installation

```bash
# Using yarn
yarn add @sentry/node @sentry/node-native

# Using npm
npm install --save @sentry/node @sentry/node-native
```

## Usage

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.

`instrument.mjs`

```javascript
import * as Sentry from "@sentry/node";
import { eventLoopBlockIntegration } from "@sentry/node-native";

Sentry.init({
dsn: "__YOUR_DSN__",
// Capture stack traces when the event loop is blocked for more than 500ms
integrations: [eventLoopBlockIntegration({ threshold: 500 })],
});
```

`app.mjs`

```javascript
import { Worker } from "worker_threads";

const worker = new Worker(new URL("./worker.mjs", import.meta.url));

// This main thread will be monitored for blocked event loops
```

`worker.mjs`

```javascript
// This worker thread will also be monitored for blocked event loops too
```

Start your application:

```bash
node --import instrument.mjs app.mjs
```

If a thread is blocked for more than the configured threshold, stack traces will be captured for all threads and sent to Sentry.

## Configuration Options

You can pass a configuration object to the `eventLoopBlockIntegration` to customize the behavior:

```typescript
interface ThreadBlockedIntegrationOptions {
/**
* Threshold in milliseconds to trigger an event.
*
* Defaults to 1000ms.
*/
threshold: number;
/**
* Maximum number of blocked events to send per clock hour.
*
* Defaults to 1.
*/
maxEventsPerHour: number;
/**
* Tags to include with blocked events.
*/
staticTags: { [key: string]: Primitive };
}
```

## Example Configuration

```javascript
import * as Sentry from "@sentry/node";
import { eventLoopBlockIntegration } from "@sentry/node-native";

Sentry.init({
dsn: "__YOUR_DSN__",
integrations: [
eventLoopBlockIntegration({
threshold: 500, // Trigger after 500ms of blocking
maxEventsPerHour: 5, // Maximum 5 events per hour
staticTags: {
component: "main-thread",
environment: "production",
},
}),
],
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Depending on whether an integration enhances the functionality of a particular r
| [`prismaIntegration`](./prisma) || || |
| [`vercelAiIntegration`](./vercelai) || || |
| [`anrIntegration`](./anr) | || | |
| [`eventLoopBlockIntegration`](./event-loop-block) | || | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | ||
| [`fsIntegration`](./fs) | | || |
| [`knexIntegration`](./knex) | | || |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| [`amqplibIntegration`](./amqplib) | | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`captureConsoleIntegration`](./captureconsole) | | | | ✓ |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`dataloaderIntegration`](./dataloader) | | | ✓ | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
| [`vercelAiIntegration`](./vercelai) | ✓ | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`captureConsoleIntegration`](./captureconsole) | | | | ✓ |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`dataloaderIntegration`](./dataloader) | | | ✓ | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
| [`vercelAiIntegration`](./vercelai) || || |
| [`anrIntegration`](./anr) | || | |
| [`captureConsoleIntegration`](./captureconsole) | | | ||
| [`eventLoopBlockIntegration`](./event-loop-block) | || | |
| [`dataloaderIntegration`](./dataloader) | | || |
| [`extraErrorDataIntegration`](./extraerrordata) | | | ||
| [`fsIntegration`](./fs) | | || |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| [`amqplibIntegration`](./amqplib) | | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`captureConsoleIntegration`](./captureconsole) | | | | ✓ |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`dataloaderIntegration`](./dataloader) | | | ✓ | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
| [`vercelAiIntegration`](./vercelai) | ✓ | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`captureConsoleIntegration`](./captureconsole) | | | | ✓ |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`dataloaderIntegration`](./dataloader) | | | ✓ | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
| [`vercelAiIntegration`](./vercelai) || || |
| [`anrIntegration`](./anr) | || | |
| [`captureConsoleIntegration`](./captureconsole) | | | ||
| [`eventLoopBlockIntegration`](./event-loop-block) | || | |
| [`dataloaderIntegration`](./dataloader) | | || |
| [`extraErrorDataIntegration`](./extraerrordata) | | | ||
| [`fsIntegration`](./fs) | | || |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Depending on whether an integration enhances the functionality of a particular r
| [`childProcessIntegration`](./childProcess) | ✓ | | | ✓ |
| [`prismaIntegration`](./prisma) | ✓ | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
| [`knexIntegration`](./knex) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| [`amqplibIntegration`](./amqplib) || || |
| [`anrIntegration`](./anr) | || | |
| [`captureConsoleIntegration`](./captureconsole) | | | ||
| [`eventLoopBlockIntegration`](./event-loop-block) | || | |
| [`childProcessIntegration`](./childProcess) || | ||
| [`consoleIntegration`](./console) || | ||
| [`contextLinesIntegration`](./contextlines) ||| | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Depending on whether an integration enhances the functionality of a particular r
### Browser Integrations

| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** |
|-------------------------------------------------------|:----------------:|:----------:|:-----------:|:----------:|:----------------------:|
| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: |
| [`breadcrumbsIntegration`](./breadcrumbs) | ✓ | | | | ✓ |
| [`browserApiErrorsIntegration`](./browserapierrors) | ✓ | ✓ | | | |
| [`browserSessionIntegration`](./browsersession) | ✓ | | | | ✓ |
Expand Down Expand Up @@ -73,6 +73,7 @@ Depending on whether an integration enhances the functionality of a particular r
| [`prismaIntegration`](./prisma) | ✓ | | ✓ | |
| [`vercelAiIntegration`](./vercelai) | ✓ | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
| [`knexIntegration`](./knex) | | | ✓ | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Depending on whether an integration enhances the functionality of a particular r
### Browser Integrations

| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** |
|-------------------------------------------------------|:----------------:|:----------:|:-----------:|:----------:|:----------------------:|
| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: |
| [`breadcrumbsIntegration`](./breadcrumbs) | ✓ | | | | ✓ |
| [`browserApiErrorsIntegration`](./browserapierrors) | ✓ | ✓ | | | |
| [`browserSessionIntegration`](./browsersession) | ✓ | | | | ✓ |
Expand Down Expand Up @@ -73,6 +73,7 @@ Depending on whether an integration enhances the functionality of a particular r
| [`prismaIntegration`](./prisma) | ✓ | | ✓ | |
| [`vercelAiIntegration`](./vercelai) | ✓ | | ✓ | |
| [`anrIntegration`](./anr) | | ✓ | | |
| [`eventLoopBlockIntegration`](./event-loop-block) | | ✓ | | |
| [`extraErrorDataIntegration`](./extraerrordata) | | | | ✓ |
| [`fsIntegration`](./fs) | | | ✓ | |
| [`knexIntegration`](./knex) | | | ✓ | |
Expand Down
Loading