Foundational tracing SDK components for OpenTelemetry JavaScript providing manual instrumentation capabilities
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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:
Browser-specific implementations optimized for web environments with appropriate fallbacks for limited APIs.
/**
* 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:
Math.random() for random number generationUsage 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-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:
visibilitychange eventspagehide event as Safari fallbackEvent Handling:
visibilitychange event → flushes spans when document.hidden becomes truepagehide event → Safari-specific fallback for page unloadUsage 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-specific implementations optimized for server environments with better performance characteristics.
/**
* 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:
Buffer.allocUnsafe() for better performancewriteUInt32BE() for efficient random number writingPerformance Benefits:
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 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:
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);
});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:
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
]
});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())
]
});The platform implementations handle various environment constraints and limitations.
Browser Compatibility:
Node.js Compatibility:
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