Nextjs OpenTelemetry Instrumentation

This document contains instructions on how to set up OpenTelemetry instrumentation in your Nextjs applications. OpenTelemetry, also known as OTel for short, is an open source observability framework that can help you generate and collect telemetry data - traces, metrics, and logs from your Nextjs application.

Send traces to SigNoz Cloud

Based on your application environment, you can choose the setup below to send traces to SigNoz Cloud.

From VMs, there are two ways to send data to SigNoz Cloud.

Send traces directly to SigNoz Cloud

Using vercel otel

Step 1. Install OpenTelemetry packages

npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/exporter-trace-otlp-http

Step 2. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 3. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Add otel logging
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); // set diaglog level to DEBUG when debugging

const exporterOptions = {
  url: 'https://ingest.[data_region].signoz.cloud:443/v1/traces', // Set your own data region or set to http://localhost:4318/v1/traces if using selfhost SigNoz
  headers: { 'signoz-access-token': 'SIGNOZ_INGESTION_KEY' }, // Set if you are using SigNoz Cloud
}

export const traceExporter = new OTLPTraceExporter(exporterOptions);
  • SIGNOZ_INGESTION_KEY : You can find your ingestion key from SigNoz cloud account details sent on your email.

Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.

RegionEndpoint
USingest.us.signoz.cloud:443/v1/traces
INingest.in.signoz.cloud:443/v1/traces
EUingest.eu.signoz.cloud:443/v1/traces

Step 4. Create instrumentation.ts file

import { registerOTel } from '@vercel/otel';
import { traceExporter } from './instrumentation.node';

export function register() {
  registerOTel({
    serviceName: 'Sample Next.js App',
    traceExporter: traceExporter,
  });
}

Step 5. Once you're done configuring the exporter options, try running your application and validate if your application is sending traces to SigNoz cloud here.

๐Ÿ“ Note

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.

You can also check the sample application at this GitHub repo.

Using OpenTelemetry instrument (only works for nodejs runtime)

Step 1. Install the OpenTelemetry packages

npm i @opentelemetry/sdk-node
npm i @opentelemetry/auto-instrumentations-node
npm i @opentelemetry/exporter-trace-otlp-http
npm i @opentelemetry/resources
npm i @opentelemetry/semantic-conventions

Step 2. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 3. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import process from 'process';
import {NodeSDK} from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { Resource } from '@opentelemetry/resources'
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'
 
// Add otel logging
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); // set diaglog level to DEBUG when debugging

const exporterOptions = {
  url: 'https://ingest.[region].signoz.cloud:443/v1/traces', // use your own data region 
  headers: { 'signoz-access-token': 'SIGNOZ_INGESTION_KEY' }, // Use if you are using SigNoz Cloud
}

const traceExporter = new OTLPTraceExporter(exporterOptions);
const sdk = new NodeSDK({
  traceExporter,
  instrumentations: [getNodeAutoInstrumentations()],
    resource: new Resource({
    [SEMRESATTRS_SERVICE_NAME]: 'next-app',
  }),
});

// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()

// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  sdk.shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch((error) => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});
  • SIGNOZ_INGESTION_KEY : You can find your ingestion key from SigNoz cloud account details sent on your email.

Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.

RegionEndpoint
USingest.us.signoz.cloud:443/v1/traces
INingest.in.signoz.cloud:443/v1/traces
EUingest.eu.signoz.cloud:443/v1/traces

Step 4. Create instrumentation.ts file

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation.node')
  }
}

Step 5. Once you're done configuring the exporter options, try running your application and validate if your application is sending traces to SigNoz cloud here.

๐Ÿ“ Note

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.

You can also check the sample application at this GitHub repo.

Send traces via OTel Collector binary

OTel Collector binary helps to collect logs, hostmetrics, resource and infra attributes. It is recommended to install Otel Collector binary to collect and send traces to SigNoz cloud. You can correlate signals and have rich contextual data through this way.

๐Ÿ“ Note

You can find instructions to install OTel Collector binary here in your VM. Once you are done setting up your OTel Collector binary, you can follow the below steps for instrumenting your Javascript application.

Using vercel otel

Step 1. Install OpenTelemetry packages

npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/exporter-trace-otlp-http

Step 2. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 3. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Add otel logging
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); // set diaglog level to DEBUG when debugging

const exporterOptions = {
  url: 'http://localhost:4318/v1/traces',
}

export const traceExporter = new OTLPTraceExporter(exporterOptions);

Step 4. Create instrumentation.ts file

import { registerOTel } from '@vercel/otel';
import { traceExporter } from './instrumentation.node';

export function register() {
  registerOTel({
    serviceName: 'Sample Next.js App',
    traceExporter: traceExporter,
  });
}

Step 5. Once you're done configuring the exporter options, try running your application and validate if your application is sending traces to SigNoz cloud here.

๐Ÿ“ Note

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.

You can also check the sample application at this GitHub repo.

Using OpenTelemetry instrument (only works for nodejs runtime)

Step 1. Install OpenTelemetry Collector binary

OTel Collector binary helps to collect logs, hostmetrics, resource and infra attributes. It is recommended to install Otel Collector binary to collect and send traces to SigNoz cloud. You can correlate signals and have rich contextual data through this way.

You can find instructions to install OTel Collector binary here in your VM.

While creating the config.yaml during the installation fo the OTel Collector Binary, you need to enable CORS under the receivers section of the config file. This is needed so that you don't get CORS error which can hinder sending your Traces to SigNoz Cloud. See the code snippet below to understand how you can enable CORS in your config file:

      http:
+        cors:
+          allowed_origins:
+            - <Frontend-application-URL>  # URL of your Frontend application. Example -> http://localhost:4200, https://netflix.com etc.

<Frontend-application-URL> - URL where your frontend application is running. For Example, http://localhost:4200 or https://netflix.com etc.

NOTE: Make sure to restart your collector after making the config changes

Step 2. Install OpenTelemetry packages

npm i @opentelemetry/sdk-node
npm i @opentelemetry/auto-instrumentations-node
npm i @opentelemetry/exporter-trace-otlp-http
npm i @opentelemetry/resources
npm i @opentelemetry/semantic-conventions

Step 3. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 4. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import process from 'process';
import {NodeSDK} from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { Resource } from '@opentelemetry/resources'
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'
 
// Add otel logging
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); // set diaglog level to DEBUG when debugging

const exporterOptions = {
  url: 'http://localhost:4318/v1/traces',
}

const traceExporter = new OTLPTraceExporter(exporterOptions);
const sdk = new NodeSDK({
  traceExporter,
  instrumentations: [getNodeAutoInstrumentations()],
    resource: new Resource({
    [SEMRESATTRS_SERVICE_NAME]: 'next-app',
  }),
});

// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()

// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  sdk.shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch((error) => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});

Step 5. Create instrumentation.ts file

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation.node')
  }
}

Step 6. Once we are done with the above configurations, you can run the collector service with the following command:

./otelcol-contrib --config ./config.yaml

Step 7. Start running your application and wait for few seconds to start receiving instrumentation data on the SigNoz Cloud.

๐Ÿ“ Note

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.

You can also check the sample application at this GitHub repo.

Send traces to SigNoz Self-Host

If you're trying to send instrumentation data to SigNoz self-hosted way, the only minor thing (apart from installing OpenTelemetry packages) that you'd be required is to change the exporterOptions in the tracing.js file

You can find instructions to install OTel Collector binary here in your Kubernetes cluster.

Using vercel otel

Step 1. Install OpenTelemetry packages

npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/exporter-trace-otlp-http

Step 2. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 3. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Add otel logging
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR); // set diaglog level to DEBUG when debugging

const exporterOptions = {
  url: 'http://localhost:4318/v1/traces', // Endpoint of SigNoz/Otel Collector
}

export const traceExporter = new OTLPTraceExporter(exporterOptions);
  • SIGNOZ_INGESTION_KEY : You can find your ingestion key from SigNoz cloud account details sent on your email.

Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.

RegionEndpoint
USingest.us.signoz.cloud:443/v1/traces
INingest.in.signoz.cloud:443/v1/traces
EUingest.eu.signoz.cloud:443/v1/traces

Step 4. Create instrumentation.ts file

import { registerOTel } from '@vercel/otel';
import { traceExporter } from './instrumentation.node';

export function register() {
  registerOTel({
    serviceName: 'Sample Next.js App',
    traceExporter: traceExporter,
  });
}

Step 5. Once you're done configuring the exporter options, try running your application and validate if your application is sending traces to SigNoz cloud here.

๐Ÿ“ Note

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.

You can also check the sample application at this GitHub repo.

Using OpenTelemetry instrument (only works for nodejs runtime)

Step 1. Install OpenTelemetry packages

npm i @opentelemetry/sdk-node
npm i @opentelemetry/auto-instrumentations-node
npm i @opentelemetry/exporter-trace-otlp-http
npm i @opentelemetry/resources
npm i @opentelemetry/semantic-conventions

Step 2. Update next.config.mjs to include instrumentationHook

/** @type {import('next').NextConfig} */
const nextConfig = {
    // include instrumentationHook experimental feature
    experimental: {
        instrumentationHook: true,
    },
};

export default nextConfig;

Step 3. Create instrumentation.ts file

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation.node')
  }
}

Step 4. Create instrumentation.node.ts file
You need to configure the endpoint for SigNoz cloud in this file.

'use strict'
import process from 'process';
import {NodeSDK} from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { Resource } from '@opentelemetry/resources'
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'
 
// Add otel logging when debugging
// import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);

const exporterOptions = {
  url: 'http://localhost:4318/v1/traces',
}

const traceExporter = new OTLPTraceExporter(exporterOptions);
const sdk = new NodeSDK({
  traceExporter,
  instrumentations: [getNodeAutoInstrumentations()],
    resource: new Resource({
    [SEMRESATTRS_SERVICE_NAME]: 'next-app',
  }),
});

// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()

// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
  sdk.shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch((error) => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});
๐Ÿ“ Note

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.

Again, http://localhost:4318/v1/traces is the default url for sending your tracing data. We are assuming you have installed SigNoz on your localhost. Based on your environment, you can update it accordingly. It should be in the following format:

http://<IP of SigNoz backend>:4318/v1/traces

NOTE: Remember to allow incoming requests to port 4318 of machine where SigNoz backend is hosted.

Once you're done with this, add your required changes including receivers, exporters in the config.yml file which can be generally found here.

Step 5. Once you're done configuring the exporter options, try running your application and validate if your application is sending traces to SigNoz here.

You can also check the sample application at this GitHub repo.

Validating instrumentation by checking for traces

With your application running, you can verify that youโ€™ve instrumented your application with OpenTelemetry correctly by confirming that tracing data is being reported to SigNoz.

To do this, you need to ensure that your application generates some data. Applications will not produce traces unless they are being interacted with, and OpenTelemetry will often buffer data before sending. So you need to interact with your application and wait for some time to see your tracing data in SigNoz.

Validate your traces in SigNoz:

  1. Trigger an action in your app that generates a web request. Hit the endpoint a number of times to generate some data. Then, wait for some time.
  2. In SigNoz, open the Services tab. Hit the Refresh button on the top right corner, and your application should appear in the list of Applications.
  3. Go to the Traces tab, and apply relevant filters to see your applicationโ€™s traces.

You might see other dummy applications if youโ€™re using SigNoz for the first time. You can remove it by following the docs here.

Nextjs Application in the list of services being monitored in SigNoz
Nextjs Application in the list of services being monitored in SigNoz

Conclusion

OpenTelemetry is the future for setting up observability for cloud-native apps. It is backed by a huge community and covers a wide variety of technology and frameworks. Using OpenTelemetry, engineering teams can instrument polyglot and distributed applications and be assured about compatibility with a lot of technologies.

SigNoz is an open-source observability tool that comes with a SaaS-like experience. You can check out SigNoz by visiting its GitHub repo ๐Ÿ‘‡

SigNoz GitHub repo

If you are someone who understands more from video, then you can watch the below video tutorial on the same with SigNoz.

If you face any issues while trying out SigNoz, you can reach out with your questions in #support channel ๐Ÿ‘‡

SigNoz Slack community

Further Reading

Implementing OpenTelemetry in Angular application

Monitor your Nodejs application with OpenTelemetry and SigNoz

Was this page helpful?