Skip to content

Commit

Permalink
Docs: Add instrumentation.ts API reference, improve instrumentation…
Browse files Browse the repository at this point in the history
… docs (#61403)

- Add instrumentation.ts API reference
- Polish and restructure instrumentation docs
  • Loading branch information
delbaoliveira committed Jan 31, 2024
1 parent 68c5edf commit 91cbe61
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,77 +1,78 @@
---
title: Instrumentation
description: Learn how to use instrumentation to run code at server startup in your Next.js app
related:
title: Learn more about Instrumentation
links:
- app/api-reference/file-conventions/instrumentation
- app/api-reference/next-config-js/instrumentationHook
---

{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

Instrumentation is the process of using code to integrate monitoring and logging tools into your application. This allows you to track the performance and behavior of your application, and to debug issues in production.

Next.js provides a `register` function that can be exported from a `instrumentation.ts|js` file in the **root directory** of your project (or inside the `src` folder if using one). Next.js will then call `register` whenever a new Next.js server instance is bootstrapped.
## Convention

<AppOnly>
To set up instrumentation, create `instrumentation.ts|js` file in the **root directory** of your project (or inside the [`src`](/docs/app/building-your-application/configuring/src-directory) folder if using one).

> **Good to know**
>
> - This feature is **experimental**. To use it, you must explicitly opt in by defining `experimental.instrumentationHook = true;` in your `next.config.js`.
> - The `instrumentation` file should be in the root of your project and not inside the `app` or `pages` directory. If you're using the `src` folder, then place the file inside `src` alongside `pages` and `app`.
> - If you use the [`pageExtensions` config option](/docs/app/api-reference/next-config-js/pageExtensions) to add a suffix, you will also need to update the `instrumentation` filename to match.
> - We have created a basic [with-opentelemetry](https://github.com/vercel/next.js/tree/canary/examples/with-opentelemetry) example that you can use.
</AppOnly>

<PagesOnly>

> **Good to know**
>
> - This feature is **experimental**. To use it, you must explicitly opt in by defining `experimental.instrumentationHook = true;` in your `next.config.js`.
> - The `instrumentation` file should be in the root of your project and not inside the `app` or `pages` directory. If you're using the `src` folder, then place the file inside `src` alongside `pages` and `app`.
> - If you use the [`pageExtensions` config option](/docs/pages/api-reference/next-config-js/pageExtensions) to add a suffix, you will also need to update the `instrumentation` filename to match.
> - We have created a basic [with-opentelemetry](https://github.com/vercel/next.js/tree/canary/examples/with-opentelemetry) example that you can use.
</PagesOnly>

When your `register` function is deployed, it will be called on each cold boot (but exactly once in each environment).

Sometimes, it may be useful to import a file in your code because of the side effects it will cause. For example, you might import a file that defines a set of global variables, but never explicitly use the imported file in your code. You would still have access to the global variables the package has declared.
Then, export a `register` function in the file. This function will be called **once** when a new Next.js server instance is initiated.

You can import files with side effects in `instrumentation.ts`, which you might want to use in your `register` function as demonstrated in the following example:
For example, to use Next.js with [OpenTelemetry](https://opentelemetry.io/) and [@vercel/otel](https://github.com/vercel/otel):

```ts filename="your-project/instrumentation.ts" switcher
import { init } from 'package-init'
```ts filename="instrumentation.ts" switcher
import { registerOTel } from '@vercel/otel'

export function register() {
init()
registerOTel('next-app')
}
```

```js filename="your-project/instrumentation.js" switcher
import { init } from 'package-init'
```js filename="instrumentation.js" switcher
import { registerOTel } from '@vercel/otel'

export function register() {
init()
registerOTel('next-app')
}
```

However, we recommend importing files with side effects using `import` from within your `register` function instead. The following example demonstrates a basic usage of `import` in a `register` function:
See the [Next.js with OpenTelemetry example](https://github.com/vercel/next.js/tree/canary/examples/with-opentelemetry) for a complete implementation.

> **Good to know**
>
> - This feature is **experimental**. To use it, you must explicitly opt in by defining [`experimental.instrumentationHook = true;`](/docs/app/api-reference/next-config-js/instrumentationHook) in your `next.config.js`.
> - The `instrumentation` file should be in the root of your project and not inside the `app` or `pages` directory. If you're using the `src` folder, then place the file inside `src` alongside `pages` and `app`.
> - If you use the [`pageExtensions` config option](/docs/app/api-reference/next-config-js/pageExtensions) to add a suffix, you will also need to update the `instrumentation` filename to match.
## Examples

```ts filename="your-project/instrumentation.ts" switcher
### Importing files with side effects

Sometimes, it may be useful to import a file in your code because of the side effects it will cause. For example, you might import a file that defines a set of global variables, but never explicitly use the imported file in your code. You would still have access to the global variables the package has declared.

We recommend importing files using JavaScript `import` syntax within your `register` function. The following example demonstrates a basic usage of `import` in a `register` function:

```ts filename="instrumentation.ts" switcher
export async function register() {
await import('package-with-side-effect')
}
```

```js filename="your-project/instrumentation.js" switcher
```js filename="instrumentation.js" switcher
export async function register() {
await import('package-with-side-effect')
}
```

By doing this, you can colocate all of your side effects in one place in your code, and avoid any unintended consequences from importing files.
> **Good to know:**
>
> We recommend importing the file from within the `register` function, rather than at the top of the file. By doing this, you can colocate all of your side effects in one place in your code, and avoid any unintended consequences from importing globally at the top of the file.
### Importing runtime-specific code

We call `register` in all environments, so it's necessary to conditionally import any code that doesn't support both `edge` and `nodejs`. You can use the environment variable `NEXT_RUNTIME` to get the current environment. Importing an environment-specific code would look like this:
Next.js calls `register` in all environments, so it's important to conditionally import any code that doesn't support specific runtimes (e.g. [Edge](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#edge-runtime) or [Node.js](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes#nodejs-runtime)). You can use the `NEXT_RUNTIME` environment variable to get the current environment:

```ts filename="your-project/instrumentation.ts" switcher
```ts filename="instrumentation.ts" switcher
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation-node')
Expand All @@ -83,7 +84,7 @@ export async function register() {
}
```

```js filename="your-project/instrumentation.js" switcher
```js filename="instrumentation.js" switcher
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./instrumentation-node')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: instrumentation.js
description: API reference for the instrumentation.js file.
related:
title: Learn more about Instrumentation
links:
- app/building-your-application/optimizing/instrumentation
---

The `instrumentation.js|ts` file is used to integrate monitoring and logging tools into your application. This allows you to track the performance and behavior of your application, and to debug issues in production.

To use it, place the file in the **root** of your application or inside a [`src` folder](/docs/app/building-your-application/configuring/src-directory) if using one.

## Config Option

Instrumentation is currently an experimental feature, to use the `instrumentation` file, you must explicitly opt-in by defining [`experimental.instrumentationHook = true;`](/docs/app/api-reference/next-config-js/instrumentationHook) in your `next.config.js`:

```js filename="next.config.js"
module.exports = {
experimental: {
instrumentationHook: true,
},
}
```

## Exports

### `register` (required)

The file exports a `register` function that is called **once** when a new Next.js server instance is initiated. `register` can be an async function.

```ts filename="instrumentation.ts" switcher
import { registerOTel } from '@vercel/otel'

export function register() {
registerOTel('next-app')
}
```

```js filename="instrumentation.js" switcher
import { registerOTel } from '@vercel/otel'

export function register() {
registerOTel('next-app')
}
```

## Version History

| Version | Changes |
| --------- | ------------------------------------------------------- |
| `v14.0.4` | Turbopack support for `instrumentation` |
| `v13.2.0` | `instrumentation` introduced as an experimental feature |
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: instrumentationHook
description: Use the instrumentationHook option to set up instrumentation in your Next.js App.
related:
title: Learn more about Instrumentation
links:
- app/api-reference/file-conventions/instrumentation
- app/building-your-application/optimizing/instrumentation
---

{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

The experimental `instrumentationHook` option allows you to set up instrumentation via the [`instrumentation` file](/docs/app/api-reference/file-conventions/instrumentation) in your Next.js App.

```js filename="next.config.js"
module.exports = {
experimental: {
instrumentationHook: true,
},
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: instrumentationHook
description: Use the instrumentationHook option to set up instrumentation in your Next.js App.
source: app/api-reference/next-config-js/instrumentationHook
---

{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

0 comments on commit 91cbe61

Please sign in to comment.