CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-opentelemetry--sdk-trace-base

Foundational tracing SDK components for OpenTelemetry JavaScript providing manual instrumentation capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

platform.mddocs/

Platform Support

OpenTelemetry SDK Trace Base provides platform-specific implementations optimized for browser and Node.js environments. These implementations offer better performance and platform-appropriate behavior for ID generation and batch processing.

Capabilities

Core IdGenerator Interface

Platform-specific ID generators implement the base IdGenerator interface for creating trace and span identifiers.

/**
 * Interface for generating trace and span IDs
 */
interface IdGenerator {
  /**
   * Generate a random trace ID
   * @returns 32-character lowercase hexadecimal string representing a 16-byte trace ID
   */
  generateTraceId(): string;
  
  /**
   * Generate a random span ID  
   * @returns 16-character lowercase hexadecimal string representing an 8-byte span ID
   */
  generateSpanId(): string;
}

ID Format Requirements:

  • Trace IDs: 32 characters, lowercase hexadecimal, represents 16 bytes (128 bits)
  • Span IDs: 16 characters, lowercase hexadecimal, represents 8 bytes (64 bits)
  • All IDs must be non-zero
  • IDs should be cryptographically random for security and distribution

Browser Platform

Browser-specific implementations optimized for web environments with appropriate fallbacks for limited APIs.

Browser RandomIdGenerator

/**
 * Browser implementation of ID generator using Math.random()
 */
class RandomIdGenerator implements IdGenerator {
  /**
   * Generate trace ID using browser-safe random number generation
   * @returns 32-character hex trace ID
   */
  generateTraceId(): string;
  
  /**
   * Generate span ID using browser-safe random number generation
   * @returns 16-character hex span ID
   */
  generateSpanId(): string;
}

Browser Implementation Details:

  • Uses Math.random() for random number generation
  • Fallback-safe for all browser environments
  • Ensures non-zero IDs by regenerating if all bytes are zero
  • No external dependencies or Node.js-specific APIs

Usage Examples:

import { BasicTracerProvider, RandomIdGenerator } from '@opentelemetry/sdk-trace-base';

// Browser-specific tracer provider
const provider = new BasicTracerProvider({
  idGenerator: new RandomIdGenerator(),
  resource: new Resource({
    'service.name': 'web-app',
    'deployment.environment': 'browser'
  })
});

// ID generator works in all browser contexts
const generator = new RandomIdGenerator();
const traceId = generator.generateTraceId(); // e.g., "a1b2c3d4e5f6789012345678901234567890abcd"
const spanId = generator.generateSpanId();   // e.g., "1234567890abcdef"

Browser BatchSpanProcessor

/**
 * Browser-specific batch span processor with page lifecycle integration
 */
class BatchSpanProcessor implements SpanProcessor {
  /**
   * @param exporter - The span exporter to send batched spans to
   * @param config - Browser-specific configuration options
   */
  constructor(exporter: SpanExporter, config?: BatchSpanProcessorBrowserConfig);
  
  /**
   * Forces flush of all pending spans within the configured timeout
   * @returns Promise that resolves when flush completes
   */
  forceFlush(): Promise<void>;
  
  /**
   * No-op: does nothing when span starts
   */
  onStart(span: Span, parentContext: Context): void;
  
  /**
   * Adds span to buffer for batched export if sampled
   * @param span - The span to add to the batch
   */
  onEnd(span: ReadableSpan): void;
  
  /**
   * Shuts down the processor and flushes remaining spans
   * @returns Promise that resolves when shutdown completes
   */
  shutdown(): Promise<void>;
}

/**
 * Browser-specific batch processor configuration
 */
interface BatchSpanProcessorBrowserConfig extends BufferConfig {
  /** 
   * Disable flush when user navigates away or closes tab
   * Auto flush is enabled by default for better data collection
   */
  disableAutoFlushOnDocumentHide?: boolean;
}

Browser-Specific Features:

  • Page Lifecycle Integration: Listens for visibilitychange events
  • Safari Compatibility: Uses pagehide event as Safari fallback
  • Auto-Flush on Navigation: Automatically flushes spans when page becomes hidden
  • Mobile Support: Handles app switching on mobile devices

Event Handling:

  1. visibilitychange event → flushes spans when document.hidden becomes true
  2. pagehide event → Safari-specific fallback for page unload
  3. Graceful degradation if events are not supported

Usage Examples:

import { BasicTracerProvider, BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';

// Browser batch processor with auto-flush (default behavior)
const provider = new BasicTracerProvider({
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter())
  ]
});

// Disable auto-flush for single-page applications
const provider = new BasicTracerProvider({
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter(), {
      disableAutoFlushOnDocumentHide: true,
      maxExportBatchSize: 100,
      scheduledDelayMillis: 3000
    })
  ]
});

// Mobile-optimized configuration
const provider = new BasicTracerProvider({
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter(), {
      maxExportBatchSize: 50,      // Smaller batches for mobile
      scheduledDelayMillis: 2000,   // More frequent exports
      maxQueueSize: 500             // Smaller memory footprint
    })
  ]
});

Node.js Platform

Node.js-specific implementations optimized for server environments with better performance characteristics.

Node.js RandomIdGenerator

/**
 * Node.js implementation using Buffer for improved performance
 */
class RandomIdGenerator implements IdGenerator {
  /**
   * Generate trace ID using Node.js Buffer for better performance
   * @returns 32-character hex trace ID
   */
  generateTraceId(): string;
  
  /**
   * Generate span ID using Node.js Buffer for better performance  
   * @returns 16-character hex span ID
   */
  generateSpanId(): string;
}

Node.js Implementation Details:

  • Uses Buffer.allocUnsafe() for better performance
  • Uses writeUInt32BE() for efficient random number writing
  • Ensures non-zero IDs by setting last byte to 1 if all zeros detected
  • Optimized for high-throughput server environments

Performance Benefits:

  • ~2-3x faster than browser implementation
  • Lower memory allocation overhead
  • Better entropy distribution
  • Suitable for high-frequency ID generation

Usage Examples:

import { BasicTracerProvider, RandomIdGenerator } from '@opentelemetry/sdk-trace-base';

// Node.js-optimized tracer provider
const provider = new BasicTracerProvider({
  idGenerator: new RandomIdGenerator(),
  resource: new Resource({
    'service.name': 'api-server',
    'deployment.environment': 'production'
  })
});

// High-performance ID generation for server use
const generator = new RandomIdGenerator();

// Generate many IDs efficiently
const traceIds = Array.from({ length: 1000 }, () => generator.generateTraceId());
const spanIds = Array.from({ length: 1000 }, () => generator.generateSpanId());

Node.js BatchSpanProcessor

/**
 * Node.js batch span processor implementation
 */
class BatchSpanProcessor implements SpanProcessor {
  /**
   * @param exporter - The span exporter to send batched spans to  
   * @param config - Standard buffer configuration
   */
  constructor(exporter: SpanExporter, config?: BufferConfig);
  
  /**
   * Forces flush of all pending spans within the configured timeout
   * @returns Promise that resolves when flush completes
   */
  forceFlush(): Promise<void>;
  
  /**
   * No-op: does nothing when span starts
   */
  onStart(span: Span, parentContext: Context): void;
  
  /**
   * Adds span to buffer for batched export if sampled
   * @param span - The span to add to the batch
   */
  onEnd(span: ReadableSpan): void;
  
  /**
   * Shuts down the processor and flushes remaining spans
   * @returns Promise that resolves when shutdown completes
   */
  shutdown(): Promise<void>;
}

Node.js-Specific Features:

  • No Page Lifecycle: No browser-specific event listeners
  • Process Integration: Works with Node.js process lifecycle events
  • High Throughput: Optimized for server-side span volumes
  • Memory Management: Better handling of large span queues

Usage Examples:

import { BasicTracerProvider, BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base';

// Server-optimized batch processor  
const provider = new BasicTracerProvider({
  spanProcessors: [
    // Example with external exporter (requires @opentelemetry/exporter-jaeger)
    // new BatchSpanProcessor(new JaegerExporter(), {
    //   maxExportBatchSize: 1000,     // Larger batches for servers
    //   scheduledDelayMillis: 5000,   // Less frequent exports  
    //   maxQueueSize: 4096,           // Larger queue for high throughput
    //   exportTimeoutMillis: 30000    // Longer timeout for network exports
    // })
    new BatchSpanProcessor(new ConsoleSpanExporter(), {
      maxExportBatchSize: 1000,     // Larger batches for servers
      scheduledDelayMillis: 5000,   // Less frequent exports  
      maxQueueSize: 4096,           // Larger queue for high throughput
      exportTimeoutMillis: 30000    // Longer timeout for network exports
    })
  ]
});

// Process lifecycle integration
process.on('SIGTERM', async () => {
  console.log('Received SIGTERM, shutting down gracefully');
  await provider.forceFlush();
  await provider.shutdown();
  process.exit(0);
});

process.on('SIGINT', async () => {
  console.log('Received SIGINT, shutting down gracefully');
  await provider.forceFlush();
  await provider.shutdown();
  process.exit(0);
});

Platform Import Pattern

The package automatically selects the appropriate platform implementation based on the environment.

// Platform exports are automatically selected
export { BatchSpanProcessor, RandomIdGenerator } from './platform';

// Platform-specific implementations are in:
// - ./platform/browser/index.ts (for browser)
// - ./platform/node/index.ts (for Node.js)

Automatic Platform Detection:

  • Browser environments get browser-optimized implementations
  • Node.js environments get Node.js-optimized implementations
  • Build tools handle platform-specific bundling
  • No manual platform selection required

Usage Examples:

// Imports automatically resolve to correct platform
import { BasicTracerProvider, BatchSpanProcessor, RandomIdGenerator } from '@opentelemetry/sdk-trace-base';

// Same code works in both browser and Node.js
const provider = new BasicTracerProvider({
  idGenerator: new RandomIdGenerator(),  // Platform-appropriate implementation
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter()) // Platform-appropriate implementation
  ]
});

Custom Platform Implementations

You can create custom platform-specific implementations by extending base classes or implementing interfaces.

Usage Examples:

import { IdGenerator } from '@opentelemetry/sdk-trace-base';
import { webcrypto } from 'crypto';

// Custom secure ID generator using Web Crypto API
class SecureIdGenerator implements IdGenerator {
  generateTraceId(): string {
    const bytes = new Uint8Array(16);
    webcrypto.getRandomValues(bytes);
    
    // Ensure non-zero
    if (bytes.every(b => b === 0)) {
      bytes[15] = 1;
    }
    
    return Array.from(bytes)
      .map(b => b.toString(16).padStart(2, '0'))
      .join('');
  }
  
  generateSpanId(): string {
    const bytes = new Uint8Array(8);
    webcrypto.getRandomValues(bytes);
    
    // Ensure non-zero
    if (bytes.every(b => b === 0)) {
      bytes[7] = 1;
    }
    
    return Array.from(bytes)
      .map(b => b.toString(16).padStart(2, '0'))
      .join('');
  }
}

// Custom batch processor with platform-specific optimizations
class OptimizedBatchSpanProcessor implements SpanProcessor {
  private batchProcessor: BatchSpanProcessor;
  
  constructor(exporter: SpanExporter, config?: BufferConfig) {
    // Platform-specific defaults
    const platformConfig = {
      maxExportBatchSize: typeof window !== 'undefined' ? 100 : 1000,
      scheduledDelayMillis: typeof window !== 'undefined' ? 2000 : 5000,
      ...config
    };
    
    this.batchProcessor = new BatchSpanProcessor(exporter, platformConfig);
  }
  
  forceFlush(): Promise<void> {
    return this.batchProcessor.forceFlush();
  }
  
  onStart(span: Span, parentContext: Context): void {
    this.batchProcessor.onStart(span, parentContext);
  }
  
  onEnd(span: ReadableSpan): void {
    this.batchProcessor.onEnd(span);
  }
  
  shutdown(): Promise<void> {
    if (typeof window !== 'undefined') {
      console.log('Browser shutdown');
    } else {
      console.log('Node.js shutdown');
    }
    return this.batchProcessor.shutdown();
  }
}

// Use custom implementations
const provider = new BasicTracerProvider({
  idGenerator: new SecureIdGenerator(),
  spanProcessors: [
    new OptimizedBatchSpanProcessor(new ConsoleSpanExporter())
  ]
});

Environment Compatibility

The platform implementations handle various environment constraints and limitations.

Browser Compatibility:

  • Works in all modern browsers (ES2017+)
  • Progressive enhancement for newer APIs
  • Graceful fallbacks for limited environments
  • Web Worker support
  • Service Worker support

Node.js Compatibility:

  • Node.js 14+ for optimal performance
  • Uses native Node.js APIs for best performance
  • Works with serverless environments
  • Compatible with clustering and worker threads

Usage Examples:

// Universal setup that works everywhere
function createTracerProvider(environment: 'browser' | 'node' | 'worker') {
  const baseConfig = {
    resource: new Resource({
      'service.name': 'universal-app',
      'deployment.environment': environment
    })
  };
  
  switch (environment) {
    case 'browser':
      return new BasicTracerProvider({
        ...baseConfig,
        spanProcessors: [
          new BatchSpanProcessor(new ConsoleSpanExporter(), {
            maxExportBatchSize: 50,
            scheduledDelayMillis: 2000
          })
        ]
      });
      
    case 'node':
      return new BasicTracerProvider({
        ...baseConfig,
        spanProcessors: [
          // Example with external exporter (requires @opentelemetry/exporter-jaeger)
          // new BatchSpanProcessor(new JaegerExporter(), {
          //   maxExportBatchSize: 1000,
          //   scheduledDelayMillis: 5000
          // })
          new BatchSpanProcessor(new ConsoleSpanExporter(), {
            maxExportBatchSize: 1000,
            scheduledDelayMillis: 5000
          })
        ]
      });
      
    case 'worker':
      return new BasicTracerProvider({
        ...baseConfig,
        spanProcessors: [
          new SimpleSpanProcessor(new ConsoleSpanExporter())
        ]
      });
  }
}

// Auto-detect environment
const environment = typeof window !== 'undefined' ? 'browser' : 'node';
const provider = createTracerProvider(environment);

Install with Tessl CLI

npx tessl i tessl/npm-opentelemetry--sdk-trace-base

docs

index.md

platform.md

samplers.md

span-exporters.md

span-processors.md

tracer-provider.md

tile.json