JSPM

@jaymanyoo/microservices-tracing

1.1.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 10
    • Score
      100M100P100Q47636F
    • License MIT

    A simple OpenTelemetry tracing setup for Node.js microservices

    Package Exports

    • @jaymanyoo/microservices-tracing
    • @jaymanyoo/microservices-tracing/dist/index.js

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@jaymanyoo/microservices-tracing) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    Microservice Tracing

    A simple, configurable OpenTelemetry tracing package for Node.js microservices with Jaeger integration.

    Features

    • 🚀 Zero-config setup - Works out of the box with sensible defaults
    • 🔧 Highly configurable - Customize instrumentations, endpoints, and behavior
    • 🏗️ Framework agnostic - Works with Express, Fastify, and other Node.js frameworks
    • 📊 Auto-instrumentation - Automatically traces HTTP, databases, message queues, and more
    • 🐳 Container-friendly - Designed for containerized microservices
    • Minimal overhead - Optimized for production use

    Quick Start

    Installation

    npm install microservice-tracing

    Basic Usage

    // Import at the very top of your main file, before any other imports
    import { initializeTracing } from 'microservice-tracing';
    
    // Initialize tracing
    initializeTracing({
      serviceName: 'my-service'
    });
    
    // Now import and start your application
    import express from 'express';
    // ... rest of your application

    Advanced Configuration

    import { initializeTracing } from 'microservice-tracing';
    
    initializeTracing({
      serviceName: 'my-service',
      serviceVersion: '1.2.3',
      environment: 'production',
      jaegerEndpoint: 'http://jaeger-collector:14268/api/traces',
      ignoreUrls: ['/health', '/metrics', '/custom-ignore'],
      instrumentations: {
        http: true,
        express: true,
        mysql: true,
        redis: true,
        amqp: true,
        socketio: false, // Disable if not using Socket.IO
        fs: false,       // Disabled by default (noisy)
        dns: false       // Disabled by default (noisy)
      }
    });

    Configuration Options

    Option Type Default Description
    serviceName string Required Name of your service as it appears in Jaeger
    serviceVersion string process.env.SERVICE_VERSION || '1.0.0' Version of your service
    environment string process.env.NODE_ENV || 'development' Deployment environment
    jaegerEndpoint string process.env.JAEGER_ENDPOINT || 'http://jaeger:14268/api/traces' Jaeger collector endpoint
    disabled boolean process.env.OTEL_DISABLED === 'true' Disable tracing entirely
    ignoreUrls string[] ['/health', '/ping', '/favicon', '/metrics'] URLs to ignore in HTTP tracing
    instrumentations object See below Enable/disable specific instrumentations

    Instrumentation Options

    instrumentations: {
      http: boolean;      // HTTP client/server (default: true)
      express: boolean;   // Express.js framework (default: true)
      mysql: boolean;     // MySQL/MySQL2 database (default: true)
      redis: boolean;     // Redis client (default: true)
      amqp: boolean;      // RabbitMQ/AMQP (default: true)
      socketio: boolean;  // Socket.IO (default: false)
      fs: boolean;        // File system operations (default: false)
      dns: boolean;       // DNS lookups (default: false)
    }

    Environment Variables

    You can configure the package using environment variables:

    # Disable tracing entirely
    OTEL_DISABLED=true
    
    # Set Jaeger endpoint
    JAEGER_ENDPOINT=http://jaeger-collector:14268/api/traces
    
    # Set service version
    SERVICE_VERSION=1.2.3
    
    # Set environment
    NODE_ENV=production

    Usage Patterns

    Express.js Application

    // src/index.ts
    import { initializeTracing } from 'microservice-tracing';
    
    // Initialize tracing first
    initializeTracing({
      serviceName: 'user-service',
      instrumentations: {
        express: true,
        mysql: true,
        redis: true
      }
    });
    
    // Then import your application
    import express from 'express';
    import { createUserRoutes } from './routes/users';
    
    const app = express();
    app.use('/users', createUserRoutes());
    
    app.listen(3000, () => {
      console.log('Server running on port 3000');
    });

    With Database and Redis

    import { initializeTracing } from 'microservice-tracing';
    
    initializeTracing({
      serviceName: 'data-service',
      instrumentations: {
        mysql: true,    // Traces MySQL queries
        redis: true,    // Traces Redis operations
        amqp: true      // Traces RabbitMQ messages
      }
    });
    
    // Your database and Redis operations will be automatically traced
    import mysql from 'mysql2/promise';
    import redis from 'redis';

    Chat Service with Socket.IO

    import { initializeTracing } from 'microservice-tracing';
    
    initializeTracing({
      serviceName: 'chat-service',
      instrumentations: {
        socketio: true,  // Enable Socket.IO tracing
        mysql: true,
        redis: true
      }
    });
    
    import { Server } from 'socket.io';
    // Socket.IO events will be automatically traced

    Microservice with Message Queues

    import { initializeTracing } from 'microservice-tracing';
    
    initializeTracing({
      serviceName: 'notification-service',
      instrumentations: {
        amqp: true,     // Traces RabbitMQ publish/consume
        http: true      // Traces outgoing HTTP calls
      }
    });
    
    // RabbitMQ operations will be automatically traced
    import amqp from 'amqplib';

    Manual Instrumentation

    For custom spans and metrics:

    import { trace } from 'microservice-tracing';
    
    const tracer = trace.getTracer('my-service');
    
    async function processOrder(orderId: string) {
      const span = tracer.startSpan('process-order');
      
      try {
        span.setAttributes({
          'order.id': orderId,
          'operation.type': 'business-logic'
        });
        
        // Your business logic here
        const result = await performOrderProcessing(orderId);
        
        span.setStatus({ code: 1 }); // OK
        return result;
      } catch (error) {
        span.recordException(error);
        span.setStatus({ code: 2, message: error.message }); // ERROR
        throw error;
      } finally {
        span.end();
      }
    }

    Production Considerations

    Performance

    The package is optimized for production use with minimal overhead (~1-3%). Key optimizations:

    • File system and DNS instrumentations are disabled by default
    • Health check endpoints are ignored
    • Efficient batch export to Jaeger

    Sampling

    For high-traffic services, you may want to implement sampling:

    // Set sampling rate via environment variable
    process.env.OTEL_TRACES_SAMPLER = 'traceidratio';
    process.env.OTEL_TRACES_SAMPLER_ARG = '0.1'; // Sample 10% of traces
    
    initializeTracing({
      serviceName: 'high-traffic-service'
    });

    Security

    • The package doesn't expose any sensitive information
    • All configuration is done via environment variables or explicit config
    • No sensitive data is automatically captured in spans

    Container Deployment

    # Dockerfile
    FROM node:18-alpine
    
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci --only=production
    
    COPY . .
    
    # Set tracing environment variables
    ENV JAEGER_ENDPOINT=http://jaeger-collector:14268/api/traces
    ENV SERVICE_VERSION=1.0.0
    
    CMD ["node", "dist/index.js"]
    # docker-compose.yml or Kubernetes deployment
    environment:
      - JAEGER_ENDPOINT=http://jaeger-collector:14268/api/traces
      - SERVICE_VERSION=1.0.0
      - NODE_ENV=production

    Troubleshooting

    Common Issues

    1. No traces appearing in Jaeger

      • Check that Jaeger is running and accessible
      • Verify the JAEGER_ENDPOINT is correct
      • Look for initialization logs in your service
    2. High memory usage

      • Disable file system instrumentation (default)
      • Implement sampling for high-traffic services
      • Check for memory leaks in your application code
    3. Missing spans

      • Ensure tracing is initialized before importing other modules
      • Check that the relevant instrumentation is enabled
      • Verify the operation is supported by auto-instrumentation

    Debug Mode

    Enable debug logging:

    DEBUG=@opentelemetry/* node your-app.js

    Health Checks

    The package automatically ignores common health check endpoints. To verify tracing is working:

    # This will be traced
    curl http://your-service/api/users
    
    # This will be ignored
    curl http://your-service/health

    API Reference

    initializeTracing(config: TracingConfig): MicroserviceTracing

    Convenience function that creates, initializes, and sets up graceful shutdown for tracing.

    class MicroserviceTracing

    constructor(config: TracingConfig)

    Creates a new tracing instance.

    initialize(): void

    Initializes OpenTelemetry tracing.

    shutdown(): Promise<void>

    Gracefully shuts down tracing.

    setupGracefulShutdown(): void

    Sets up process signal handlers for graceful shutdown.

    License

    MIT