npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bluealba/opentelemetry-nodejs

v1.0.0

Published

OpenTelemetry wrapper for NodeJs Apps

Readme

@bluealba/opentelemetry-nodejs

OpenTelemetry wrapper for Node.js that simplifies instrumentation and observability of applications.

Table of Contents

Quick Start

# 1. Install the package
npm install @bluealba/opentelemetry-nodejs

# 2. Set up environment variables
export OTEL_ENABLED=true
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces

# 3. Initialize in your application (must be FIRST import)
# main.ts
import { startOtel } from "@bluealba/opentelemetry-nodejs";
import { name, version } from "./package.json";

startOtel(name, version);

// Then import the rest of your app
import { app } from "./app";

Prerequisites

Before using this package, you need to have an OpenTelemetry Collector running and listening on the port specified in OTEL_EXPORTER_OTLP_ENDPOINT.

We recommend https://hub.docker.com/r/otel/opentelemetry-collector-contrib as it has support for exporting traces to Datadog: https://docs.datadoghq.com/opentelemetry/setup/collector_exporter/install/

Installation

npm install @bluealba/opentelemetry-nodejs

Initial Setup

⚠️ Important: OpenTelemetry must be initialized before any other imports and before the application bootstraps. It is recommended to be the first line of code executed.

Example with NestJS

// main.ts
import { startOtel } from "@bluealba/opentelemetry-nodejs";
import { name, version } from "../package.json";

// Initialize OpenTelemetry FIRST
startOtel(name, version);
// Or
startOtel(name, version, customLoggerInstance);
// Where customLoggerInstance is optional an can be any logger that support, info, log, warn and error methods

// Then, import and start the application normally
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { json } from "express";
import { NestFactory } from "@nestjs/core";
import { ValidationPipe } from "@nestjs/common";
import { AppConfigService } from "./app-config/app-config.service";
import { AppModule } from "./app.module";

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

  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
    })
  );

  const configService = app.get(AppConfigService);
  await app.listen(configService.get("PORT"));
}

bootstrap();

Environment Variables

Required Environment Variables

| Variable | Description | Default | | ----------------------------- | ---------------------------------- | -------------------------------------- | | OTEL_ENABLED | Enables/disables OpenTelemetry | false | | OTEL_EXPORTER_OTLP_ENDPOINT | URL of the OpenTelemetry collector | None (SDK won't initialize if missing) |

Important: Both OTEL_ENABLED=true AND OTEL_EXPORTER_OTLP_ENDPOINT must be set for OpenTelemetry to initialize. If the endpoint is missing, a warning will be logged but your application will continue to run normally.

What are auto-instrumentations?
https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node

The node_autoinstrumentations are a set of automatic instrumentations for popular Node.js libraries (HTTP, Express, PostgreSQL, MongoDB, Redis, KafkaJs, etc.). When enabled, OpenTelemetry automatically captures traces from these operations without requiring additional code.

Exporter Configuration

| Variable | Description | Default | Example | | ----------------------------- | --------------------------------------------------------------- | ------- | ------------------------------------ | | OTEL_EXPORTER_OTLP_ENDPOINT | URL of the OpenTelemetry collector that will receive the traces | None | http://localhost:4318/v1/traces | | OTEL_BATCH_EXPORT_TIMEOUT | Timeout to export collected traces (in ms) | 5000 | 5000 | | OTEL_BATCH_SCHEDULE_DELAY | Delay between trace exports (in ms) | 2000 | 2000 | | OTEL_BATCH_MAX_SIZE | Maximum size of the trace batch to be sent | 512 | 512 | | OTEL_QUEUE_SIZE | Queue size (number of traces to accumulate before sending them) | 2048 | 2048 |

Optional Configuration

| Variable | Default | Description | | ------------------------------------- | ------------------------------- | ----------------------------------------------------------------- | | OTEL_APP_NAME | Service name from startOtel() | Override service name | | OTEL_APP_NAMESPACE | namespace | Service namespace for grouping | | TARGET_ENV | local | Environment name (dev, staging, prod) | | OTEL_NODE_AUTOINSTRUMENTATIONS | false | Enable auto-instrumentations for popular Node.js libraries | | OTEL_SAMPLING_RATIO | 1 | Sampling ratio (0-1) for traces. 1 = 100% sampling | | OTEL_METRICS_ENABLED | false | Enable metrics exporter | | OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | Falls back to traces endpoint | Metrics exporter endpoint (uses OTEL_EXPORTER_OTLP_ENDPOINT if not set) | | OTEL_METRICS_EXPORT_INTERVAL | 60000 | How often metrics are exported (ms) | | OTEL_ENABLE_HOST_METRICS | false | Enable host metrics exporter (needs OTEL_METRICS_ENABLED to init) |

Example .env File

# OpenTelemetry Configuration
OTEL_ENABLED=true
OTEL_NODE_AUTOINSTRUMENTATIONS=true
OTEL_SAMPLING_RATIO=1
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
OTEL_BATCH_EXPORT_TIMEOUT=5000
OTEL_BATCH_SCHEDULE_DELAY=2000
OTEL_BATCH_MAX_SIZE=512
OTEL_QUEUE_SIZE=2048

#Service identity
OTEL_APP_NAME=your_app_name
OTEL_APP_NAMESPACE=your_workspace
TARGET_ENV=dev

# Metrics Configuration
OTEL_METRICS_ENABLED=true # to enable metrics export
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics # Specify the otel-collector EP
OTEL_METRICS_EXPORT_INTERVAL=60000  # How often metrics are going to be exported in milliseconds
OTEL_ENABLE_HOST_METRICS=true # to export host metrics (cpu metrics from the host running the node process)

Custom Traces

@Span() Decorator

You can use the @Span() decorator to generate custom spans on specific methods:

import { Span } from "@bluealba/opentelemetry-nodejs";

export class MyService {
  // Without arguments: automatically uses the class and method name
  @Span()
  async processData(data: any) {
    // your logic...
  }

  // With custom name
  @Span("custom-operation-name")
  async complexOperation() {
    // your logic...
  }
}

withSpan() Function

For functional/imperative code, use withSpan to manually create spans:

import { withSpan } from "@bluealba/opentelemetry-nodejs";

async function processOrder(orderId: string) {
  return withSpan("process-order", async () => {
    // Your logic here
    const order = await fetchOrder(orderId);
    return order;
  });
}

Adding Custom Attributes

You can add specific attributes to the current span using setOtelAttribute:

import { Span, setOtelAttribute } from "@bluealba/opentelemetry-nodejs";

export class PaymentService {
  @Span()
  async handlePayload(payload: any[]) {
    // Your logic...

    // Add custom attribute to the current span
    setOtelAttribute("payload.count", payload.length);
    setOtelAttribute("payload.type", typeof payload);

    // More logic...
  }
}

Custom attributes are useful for:

  • Adding business context to traces
  • Facilitating filtering and searching in observability tools
  • Debugging and performance analysis

Available Metrics

When OTEL_METRICS_ENABLED=true, the following metrics are automatically exported:

Runtime Metrics (from auto-instrumentations)

  • nodejs_eventloop_delay_* - Event loop delay (mean, p50, p90, p99)
  • nodejs_eventloop_utilization - Event loop utilization (0-1)
  • v8js_memory_heap_* - V8 heap memory usage
  • v8js_gc_duration_* - Garbage collection duration by type
  • http_server_duration - HTTP server request duration
  • http_client_duration - HTTP client request duration
  • db_client_operation_duration - Database operation duration

Host Metrics (when OTEL_ENABLE_HOST_METRICS=true)

  • process_cpu_time - Process CPU time (user/system)
  • process_cpu_utilization - Process CPU utilization (0-1)
  • process_resident_memory_bytes - Resident memory (RSS)
  • process_heap_bytes - Heap memory

All metrics include resource attributes: service.name, service.namespace, service.version, deployment.environment

Framework Examples

Express.js

// server.ts
import { startOtel } from "@bluealba/opentelemetry-nodejs";
import { name, version } from "./package.json";

// Initialize OpenTelemetry FIRST
startOtel(name, version);

// Then import Express and other dependencies
import express from "express";
import { Span, setOtelAttribute } from "@bluealba/opentelemetry-nodejs";

const app = express();
app.use(express.json());

// Routes will be automatically instrumented if OTEL_NODE_AUTOINSTRUMENTATIONS=true
app.get("/api/users/:id", async (req, res) => {
  // Add custom attributes to the auto-generated span
  setOtelAttribute("user.id", req.params.id);

  const user = await getUserById(req.params.id);
  res.json(user);
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

Fastify

// server.ts
import { startOtel } from "@bluealba/opentelemetry-nodejs";
import { name, version } from "./package.json";

// Initialize OpenTelemetry FIRST
startOtel(name, version);

// Then import Fastify
import Fastify from "fastify";
import { setOtelAttribute } from "@bluealba/opentelemetry-nodejs";

const fastify = Fastify({ logger: true });

fastify.get("/api/health", async (request, reply) => {
  setOtelAttribute("health.status", "ok");
  return { status: "healthy" };
});

const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};

start();

Standalone Node.js Application

// index.ts
import { startOtel, Span, withSpan, setOtelAttribute } from "@bluealba/opentelemetry-nodejs";
import { name, version } from "./package.json";

// Initialize OpenTelemetry FIRST
startOtel(name, version);

class DataProcessor {
  @Span("process-batch")
  async processBatch(items: any[]) {
    setOtelAttribute("batch.size", items.length);

    for (const item of items) {
      await this.processItem(item);
    }
  }

  @Span()
  async processItem(item: any) {
    setOtelAttribute("item.id", item.id);
    // Processing logic...
  }
}

// Using withSpan for functional code
async function main() {
  await withSpan("main-operation", async () => {
    const processor = new DataProcessor();
    await processor.processBatch([{ id: 1 }, { id: 2 }]);
  });
}

main();

Development

This section is for developers who want to contribute to this library or run it locally.

Setup Development Environment

# Clone the repository
git clone <repository-url>
cd opentelemetry-nodejs

# Install dependencies
npm install

# Build the project
npm run build

Development Commands

# Watch mode for development
npm run dev

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Generate coverage report
npm run coverage

# Lint code
npm run lint

# Auto-fix linting issues
npm run lint:fix

# Clean build artifacts
npm run clean

Running Tests

This project uses Jest for testing. Test files follow the pattern *.spec.ts and are located alongside source files in src/.

# Run all tests
npm test

# Run specific test file
npm test -- src/otel/otel.spec.ts

# Run tests matching a pattern
npm test -- -t "should initialize SDK"

# Run with coverage
npm run coverage

Project Structure

src/
├── index.ts                  # Public API exports
└── otel/
    ├── otel.ts              # Main initialization logic
    ├── otel.spec.ts         # Tests for otel.ts
    ├── otel-config.ts       # Environment variable configuration
    ├── otel-config.spec.ts  # Tests for otel-config.ts
    ├── otel.helper.ts       # User-facing utilities (@Span, withSpan, etc.)
    └── otel.helper.spec.ts  # Tests for otel.helper.ts

Making Changes

  1. Create a new branch for your feature/fix
  2. Make your changes and add tests
  3. Run npm test to ensure all tests pass
  4. Run npm run lint:fix to format code
  5. Commit your changes following conventional commits
  6. Submit a pull request

Troubleshooting

OpenTelemetry is not initializing

Problem: No traces are being sent to the collector.

Solutions:

  1. Verify OTEL_ENABLED=true is set
  2. Verify OTEL_EXPORTER_OTLP_ENDPOINT is set and reachable
  3. Check that startOtel() is called BEFORE any other imports
  4. Check application logs for initialization warnings
# Test if collector is reachable
curl -X POST http://localhost:4318/v1/traces \
  -H "Content-Type: application/json" \
  -d '{}'

Spans are not showing custom attributes

Problem: Custom attributes added with setOtelAttribute() are not visible in traces.

Solutions:

  1. Ensure OTEL_ENABLED=true
  2. Verify you're calling setOtelAttribute() within an active span (inside a @Span() decorated method or withSpan() callback)
  3. Check that the attribute name and value are valid

Auto-instrumentation not working

Problem: HTTP requests, database queries, etc. are not being traced automatically.

Solutions:

  1. Set OTEL_NODE_AUTOINSTRUMENTATIONS=true
  2. Ensure startOtel() is called BEFORE importing libraries like Express, PostgreSQL clients, etc.
  3. Verify the library you're using is supported by @opentelemetry/auto-instrumentations-node

Metrics not being exported

Problem: Metrics are not appearing in your observability platform.

Solutions:

  1. Set OTEL_METRICS_ENABLED=true
  2. Verify OTEL_EXPORTER_OTLP_METRICS_ENDPOINT is set (or it will fall back to the traces endpoint)
  3. Check that your collector is configured to receive metrics
  4. For host metrics, ensure OTEL_ENABLE_HOST_METRICS=true

TypeScript compilation errors

Problem: Getting type errors when using the library.

Solutions:

  1. Ensure you have @types/node installed in your project
  2. Check that your tsconfig.json includes the necessary compiler options:
    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }

Initialization order issues

Problem: Getting errors or unexpected behavior.

Solution: Ensure OpenTelemetry initialization happens FIRST. Common mistake:

// WRONG - imports before initialization
import { NestFactory } from "@nestjs/core";
import { startOtel } from "@bluealba/opentelemetry-nodejs";
startOtel("app", "1.0.0");

// CORRECT - initialization before imports
import { startOtel } from "@bluealba/opentelemetry-nodejs";
startOtel("app", "1.0.0");
import { NestFactory } from "@nestjs/core";

Collector connection refused

Problem: Error connecting to the OpenTelemetry collector.

Solutions:

  1. Verify the collector is running: docker ps or check your collector service
  2. Check the endpoint URL format: http://host:port/v1/traces (note the /v1/traces path)
  3. Ensure the port is accessible from your application
  4. Check firewall rules if running in containers or different networks

Performance impact

Problem: Concerned about performance overhead.

Information:

  • Adjust OTEL_SAMPLING_RATIO to sample fewer traces (e.g., 0.1 for 10%)
  • Increase OTEL_BATCH_SCHEDULE_DELAY to batch spans less frequently
  • Disable auto-instrumentations if not needed: OTEL_NODE_AUTOINSTRUMENTATIONS=false
  • Disable metrics if only traces are needed: OTEL_METRICS_ENABLED=false

Additional Resources