Node.js

Node.js Integration

Instrument Node.js applications with OpenTelemetry

Overview

Instrument your Node.js applications to send traces, metrics, and logs to Qorrelate using OpenTelemetry. Supports automatic instrumentation for Express, NestJS, Next.js, and more.

Installation

npm install @opentelemetry/api \
  @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http \
  @opentelemetry/exporter-metrics-otlp-http

Auto-Instrumentation (Recommended)

Create a tracing.js file:

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');

const traceExporter = new OTLPTraceExporter({
  url: 'https://qorrelate.io/v1/traces',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'X-Organization-Id': 'YOUR_ORG_ID'
  }
});

const metricExporter = new OTLPMetricExporter({
  url: 'https://qorrelate.io/v1/metrics',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'X-Organization-Id': 'YOUR_ORG_ID'
  }
});

const sdk = new NodeSDK({
  serviceName: 'my-nodejs-app',
  traceExporter,
  metricReader: new PeriodicExportingMetricReader({
    exporter: metricExporter,
    exportIntervalMillis: 60000
  }),
  instrumentations: [getNodeAutoInstrumentations()]
});

sdk.start();

Run your app with the tracing file:

node -r ./tracing.js app.js

# Or with environment variables
OTEL_EXPORTER_OTLP_ENDPOINT="https://qorrelate.io" \
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer YOUR_API_KEY,X-Organization-Id=YOUR_ORG_ID" \
OTEL_SERVICE_NAME="my-nodejs-app" \
node -r ./tracing.js app.js

Manual Instrumentation

Add custom spans to your code:

const { trace } = require('@opentelemetry/api');

const tracer = trace.getTracer('my-app');

async function processOrder(orderId) {
  return tracer.startActiveSpan('processOrder', async (span) => {
    try {
      span.setAttribute('order.id', orderId);
      
      // Your business logic
      const result = await doSomething();
      
      span.setAttribute('order.status', 'completed');
      return result;
    } catch (error) {
      span.recordException(error);
      span.setStatus({ code: 2, message: error.message });
      throw error;
    } finally {
      span.end();
    }
  });
}

Express

npm install @opentelemetry/instrumentation-express @opentelemetry/instrumentation-http

// In tracing.js, add to instrumentations:
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');

instrumentations: [
  new HttpInstrumentation(),
  new ExpressInstrumentation(),
]

NestJS

npm install @opentelemetry/instrumentation-nestjs-core

// In tracing.js
const { NestInstrumentation } = require('@opentelemetry/instrumentation-nestjs-core');

instrumentations: [
  new NestInstrumentation(),
  // ... other instrumentations
]

// In main.ts, import tracing first
import './tracing';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

Next.js

// next.config.js
module.exports = {
  experimental: {
    instrumentationHook: true
  }
};

// instrumentation.ts (in root or src directory)
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { NodeSDK } = await import('@opentelemetry/sdk-node');
    const { OTLPTraceExporter } = await import('@opentelemetry/exporter-trace-otlp-http');
    const { getNodeAutoInstrumentations } = await import('@opentelemetry/auto-instrumentations-node');
    
    const sdk = new NodeSDK({
      serviceName: 'my-nextjs-app',
      traceExporter: new OTLPTraceExporter({
        url: 'https://qorrelate.io/v1/traces',
        headers: {
          'Authorization': `Bearer ${process.env.QORRELATE_API_KEY}`,
          'X-Organization-Id': process.env.QORRELATE_ORG_ID
        }
      }),
      instrumentations: [getNodeAutoInstrumentations()]
    });
    
    sdk.start();
  }
}

💡 Pro Tip

Use the Qorrelate CLI for zero-code instrumentation: qorrelate run node app.js