@mirobestbg/otel
v1.2.0
Published
High-performance zero-allocation OpenTelemetry SDK for Bun and Node.js using SharedArrayBuffers
Maintainers
Readme
@mirobestbg/otel
High-Performance Zero-Allocation OpenTelemetry SDK for Bun & Node.js
@mirobestbg/otel is an ultra-fast OpenTelemetry (OTEL) tracing SDK built from the ground up to eliminate GC pauses and allocation overhead on critical tracing hot paths. It utilizes a Lockless Two-Phase Commit Ring Buffer backed by SharedArrayBuffer and a Zero-Allocation String Interner.
Features
- ⚡ Zero-Allocation Hot Path: Pre-allocated Array of Structs (AoS) backed by
SharedArrayBuffer. - 🔒 Lockless Multi-Threaded Sync: Atomic operations guarantee safe lock-free concurrency between worker threads and main application loops.
- 🪶 String Interning: Static ID interning for standard HTTP/DB span names with a dynamic ring buffer fallback.
- 🎯 Modern API Support: Works with ES Stage 3 decorators (
@withSpan) and callback wrappers (withSpan(options, fn)). AnactiveSpanproxy gives safe, leak-free access to the currently active span. - 🏷️ Type-Safe Custom Semantics: Strongly-typed custom project semantics merged with standard OpenTelemetry semantics.
Installation
# Using Bun
bun add @mirobestbg/otel
# Using npm
npm install @mirobestbg/otelQuick Start
1. Define Telemetry Configuration
Create a telemetry.config.ts file:
import { defineConfig, initTelemetry, defineSemantics } from "@mirobestbg/otel";
// 1. Define custom project semantics
export const SEMANTICS = defineSemantics({
PROJECT_TENANT_ID: "project.tenant_id",
USER_ROLE: "user.role",
} as const);
// 2. Configure endpoint & tracing options
export const config = defineConfig({
endpoint: "http://localhost:4318",
semantics: SEMANTICS,
traces: {
enabled: true,
type: "HTTP",
url: "http://localhost:4318/v1/traces",
config: {
memoryUsage: 5120, // 5MB memory budget for arena & string buffer
},
},
});
// 3. Initialize SDK
export const { activeSpan, withSpan, semantics } = initTelemetry(config);Usage Patterns
A. Callback Wrapper (withSpan)
import { withSpan, activeSpan, semantics } from "./telemetry.config";
const result = await withSpan({ name: "db_query" }, async () => {
// activeSpan proxies to the currently active span context
activeSpan.setAttribute(semantics.PROJECT_TENANT_ID, "tenant_123");
return await db.orders.findMany();
});B. ES Stage 3 Decorator (@withSpan)
import { withSpan, activeSpan } from "./telemetry.config";
class OrderService {
@withSpan({ name: "create_order" })
async createOrder(orderData: any) {
activeSpan.setAttribute("order.amount", orderData.amount);
return await db.orders.insert(orderData);
}
}Architecture Overview
- TelemetryArena: Manages a 64-byte aligned ring buffer (
BYTES_PER_SPAN = 64) holding high-resolution timestamps, UUIDv7 trace IDs, span IDs, name IDs, and critical flag bits. - String Dictionary: Interns static span names (e.g.,
"HTTP GET","db_query") into integer IDs, while storing dynamic strings in a SharedArrayBuffer text buffer. - Trace API Proxy: Dynamically delegates attributes and state to the current active span context via
AsyncLocalStorage.
Running Tests
bun testLicense
SEE LICENSE IN LICENSE
