This guide provides step-by-step instructions for setting up OpenTelemetry (OTel) instrumentation in your Nest.js applications to enable comprehensive observability. OpenTelemetry is an open-source framework that helps you collect telemetry data—such as traces, metrics, and logs—from your app to monitor its performance and health.
Once your telemetry data is captured, you can configure an exporter to send it directly to Atatus for advanced monitoring and insights.
The process of setting up OpenTelemetry in Nest.js involves three key steps:
Instrumenting Your Nest.js Application: Add the necessary OpenTelemetry components to your Nest.js app for trace and metric collection.
Configuring the Exporter: Set up the exporter to send your telemetry data to Atatus.
Validating the Setup: Verify that the configuration is working and that your data is being correctly sent to Atatus.
Sending Telemetry Data to Atatus in Two Ways
Send Telemetry Traces to Atatus
Option 1: Using vercel otel (recommended)
Option 2: Code Level Automatic Instrumentation(only works for nodejs runtime)
Send Traces Using the OTel Collector Binary
Option 1: Using vercel otel (recommended)
Option 2: Code Level Automatic Instrumentation(only works for nodejs runtime)
Send Telemetry Traces to Atatus
Option 1: Using vercel otel
Install OpenTelemetry packages
npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/exporter-trace-otlp-http
Update
next.config.mjs
to include instrumentationHook/** @type {import('next').NextConfig} */ const nextConfig = { // include instrumentationHook experimental feature experimental: { instrumentationHook: true, }, }; export default nextConfig;
Create
instrumentation.node.ts
file. You need to configure the endpoint for Atatus 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://otel-rx.atatus.com:443/v1/traces', headers: { 'api-key': 'ATATUS_INGESTION_KEY' }, } export const traceExporter = new OTLPTraceExporter(exporterOptions);
You can get the
ATATUS_INGESTION_KEY
from Settings -> Account Settings -> API Keys in Atatus dashboard.Create
instrumentation.ts
fileimport { registerOTel } from '@vercel/otel'; import { traceExporter } from './instrumentation.node'; export function register() { registerOTel({ serviceName: 'Sample Next.js App', traceExporter: traceExporter, }); }
Option 2: Code Level Automatic Instrumentation
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
Update
next.config.mjs
to include instrumentationHook/** @type {import('next').NextConfig} */ const nextConfig = { // include instrumentationHook experimental feature experimental: { instrumentationHook: true, }, }; export default nextConfig;
Create
instrumentation.node.ts
file. You need to configure the endpoint for Atatus 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://otel-rx.atatus.com:443/v1/traces', headers: { 'api-key': 'ATATUS_INGESTION_KEY' }, } 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)); });
You can get the
ATATUS_INGESTION_KEY
from Settings -> Account Settings -> API Keys in Atatus dashboard.Create
instrumentation.ts
fileexport async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { await import('./instrumentation.node') } }
Send Traces Using the OTel Collector Binary:
To collect and send traces to Atatus, it's recommended to install the OpenTelemetry (OTel) Collector binary. The OTel Collector helps gather logs, host metrics, resource, and infrastructure attributes, enabling richer contextual data and easier signal correlation.
For detailed instructions on setting up the OTel Collector binary on your VM, please refer to the official installation guide. Once the Collector is up and running, you can proceed with instrumenting your Java application to start sending telemetry data to Atatus.
Option 1: No Code Automatic Instrumentation
Install OpenTelemetry packages
npm install @vercel/otel @opentelemetry/sdk-logs @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/exporter-trace-otlp-http
Update
next.config.mjs
to include instrumentationHook/** @type {import('next').NextConfig} */ const nextConfig = { // include instrumentationHook experimental feature experimental: { instrumentationHook: true, }, }; export default nextConfig;
Create
instrumentation.node.ts
file. You need to configure the endpoint for Atatus 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);
Create
instrumentation.ts
fileimport { registerOTel } from '@vercel/otel'; import { traceExporter } from './instrumentation.node'; export function register() { registerOTel({ serviceName: 'Sample Next.js App', traceExporter: traceExporter, }); }
Option 2: Code Level Automatic Instrumentation
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
Update
next.config.mjs
to include instrumentationHook/** @type {import('next').NextConfig} */ const nextConfig = { // include instrumentationHook experimental feature experimental: { instrumentationHook: true, }, }; export default nextConfig;
Create
instrumentation.node.ts
file. You need to configure the endpoint for Atatus 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)); });
Create
instrumentation.ts
fileexport async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { await import('./instrumentation.node') } }
Start running your application and wait for few seconds to start receiving data on the Atatus dashboard