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

@opentrace-sdk/node

v0.1.0

Published

OpenTrace Node.js client — async structured log forwarding

Downloads

7

Readme

@opentrace-sdk/node

CI License: MIT Node.js TypeScript

Async structured log forwarding for Node.js backends. Ships logs, errors, events, and request traces to an OpenTrace server.

Requires an OpenTrace server — This package forwards data to a running OpenTrace server, a self-hosted observability tool with 75+ MCP tools for logs, database monitoring, and AI-driven debugging. See the server repo for setup.

This package will never crash or slow down your application. Every public method is wrapped in try/catch. All network errors are handled silently. If the server is unreachable, logs are dropped — your app continues running normally.

Features

Core

  • Zero runtime dependencies — uses only Node.js built-ins (http, crypto, zlib, async_hooks, v8)
  • Zero measurable overhead — deferred entries are plain object literals (~1μs), serialized only at flush time
  • TypeScript strict mode — full type safety with ESM + CJS dual-publish
  • Never throws — every public method wrapped in try/catch, safe for production
  • Async dispatch — entries queued in-memory, batched and sent via background timer
  • Bounded queue — caps at 1,000 entries to prevent memory bloat (drops newest when full)
  • Smart truncation — oversized payloads are truncated field-by-field instead of dropped
  • Gzip compression — automatic payload compression with configurable threshold
  • Level filteringminLevel threshold or allowedLevels list
  • Graceful shutdownbeforeExit handler + flush with deadline, no lost data on clean exit
  • Fork detection — resets state after cluster.fork() via PID comparison

Request Tracking

  • Express, Fastify, Hono — first-class middleware for all three frameworks
  • Per-request contextAsyncLocalStorage propagates trace IDs across async boundaries
  • Request summaries — SQL count, HTTP call count, N+1 detection, timeline per request
  • W3C traceparent — distributed trace context propagation across services
  • Breadcrumbs — FIFO trail of events (max 25) attached to request context

Instrumentation

  • Outbound HTTP — auto-instrument http.request/https.request with trace header injection
  • Console capture — forward console.log/warn/error to OpenTrace
  • Runtime metrics — V8 heap stats, RSS, active handles/requests (unreffed timer)
  • Connection pool — generic pool stats via user-provided function
  • Manual spansOpenTrace.trace('operation', fn) with sync + async support and nesting

Safety

  • Circuit breaker — 5 failures → open → 30s cooldown → half-open probe
  • Backpressure sampling — queue > 75% → exponential rate reduction (max 1024x)
  • Rate limit handling — respects 429 responses with automatic backoff
  • Auth suspension — stops sending on 401/403 until reinitialized
  • PII scrubbing — regex redaction for emails, credit cards, SSNs, phone numbers, bearer tokens, API keys
  • SQL normalization — strips literals, generates stable fingerprints for grouping

Install

npm install @opentrace-sdk/node

Quick Start

import OpenTrace from '@opentrace-sdk/node';

OpenTrace.init({
  endpoint: 'https://your-opentrace-server.com',
  apiKey: 'your-api-key',
  service: 'my-app',
  environment: 'production',
});

// Structured logging
OpenTrace.info('User signed in', { userId: 42 });
OpenTrace.warn('Rate limit approaching', { current: 95, max: 100 });

// Error tracking with cause chain + fingerprinting
OpenTrace.error(new Error('Payment failed'), { orderId: 'abc-123' });

// Business events (bypass level filtering)
OpenTrace.event('deploy', 'Deployed v2.1.0', { commit: 'abc123' });

// Global context attached to every entry
OpenTrace.setContext({ tenant: 'acme', region: 'us-east-1' });

// Graceful shutdown
await OpenTrace.shutdown();

Express Middleware

import express from 'express';
import OpenTrace from '@opentrace-sdk/node';

const app = express();
app.use(OpenTrace.middleware.express());

app.get('/api/users', (req, res) => {
  // SQL tracking within request context
  OpenTrace.recordSql('SELECT users', 5.2, 'SELECT * FROM users');
  OpenTrace.addBreadcrumb({ category: 'db', message: 'loaded users' });
  res.json([{ id: 1, name: 'Alice' }]);
});

Each request automatically captures: method, path, status code, duration, trace context (W3C traceparent), request ID, and an optional request summary with SQL/HTTP aggregation and N+1 detection.

Fastify Plugin

import Fastify from 'fastify';
import OpenTrace from '@opentrace-sdk/node';

const app = Fastify();
app.register(OpenTrace.middleware.fastify());

Hono Middleware

import { Hono } from 'hono';
import OpenTrace from '@opentrace-sdk/node';

const app = new Hono();
app.use('*', OpenTrace.middleware.hono());

Distributed Tracing

Trace context propagates automatically via W3C traceparent headers. Enable outbound HTTP instrumentation to inject trace headers into all outgoing requests:

OpenTrace.init({
  endpoint: 'https://opentrace.example.com',
  apiKey: 'key',
  service: 'my-app',
  instrumentHttp: true,
});

Manual span tracing with automatic timing:

const result = await OpenTrace.trace('fetchUser', async () => {
  return db.query('SELECT * FROM users WHERE id = ?', [userId]);
});

Spans support nesting — child spans automatically link to their parent.

Configuration

OpenTrace.init({
  // Required
  endpoint: 'https://opentrace.example.com',
  apiKey: 'your-api-key',
  service: 'my-app',

  // Environment
  environment: 'production',        // default: ''
  hostname: os.hostname(),           // auto-detected
  gitSha: process.env.GIT_SHA,       // auto-detected from REVISION/GIT_SHA/HEROKU_SLUG_COMMIT

  // Batching
  batchSize: 50,                     // entries per flush (default: 50)
  flushInterval: 5000,               // ms between flushes (default: 5000)
  maxPayloadBytes: 256 * 1024,       // max batch size (default: 256KB)

  // Network
  compression: true,                 // gzip payloads (default: true)
  compressionThreshold: 1024,        // min bytes to compress (default: 1024)
  timeout: 5000,                     // HTTP timeout ms (default: 5000)
  maxRetries: 2,                     // retry on 5xx (default: 2)
  retryBaseDelay: 100,               // initial retry delay ms (default: 100)

  // Circuit breaker
  circuitBreakerThreshold: 5,        // failures before OPEN (default: 5)
  circuitBreakerTimeout: 30000,      // ms before HALF_OPEN (default: 30000)

  // Filtering
  minLevel: 'info',                  // log level threshold (default: 'info')
  sampleRate: 1.0,                   // fraction of requests to trace (default: 1.0)
  ignorePaths: ['/health', '/ready', '/live'],

  // Features (all opt-in)
  requestSummary: true,              // aggregate SQL/HTTP per request (default: true)
  instrumentHttp: false,             // auto-instrument outbound HTTP
  instrumentConsole: false,          // capture console.log/warn/error
  runtimeMetrics: false,             // V8 heap/RSS/handles monitoring

  // PII scrubbing (always on, extend with custom patterns)
  extraPiiPatterns: [/CUSTOM_PATTERN/g],

  // Callbacks
  beforeSend: (payload) => payload,  // transform/filter before send (return null to drop)
  context: { tenant: 'acme' },       // static context merged into all entries
});

API Reference

Lifecycle

| Method | Description | |---|---| | OpenTrace.init(config) | Initialize with endpoint, apiKey, service | | OpenTrace.shutdown(timeoutMs?) | Flush remaining entries + cleanup (async) | | OpenTrace.enabled() | Check if initialized and active | | OpenTrace.enable() / .disable() | Runtime toggle without reinitializing |

Logging

| Method | Description | |---|---| | OpenTrace.log(level, message, metadata?) | Log at any level | | OpenTrace.debug(message, metadata?) | Debug-level log | | OpenTrace.info(message, metadata?) | Info-level log | | OpenTrace.warn(message, metadata?) | Warn-level log | | OpenTrace.error(err, metadata?) | Capture Error or string with fingerprint, cause chain, stack |

Events & Tracing

| Method | Description | |---|---| | OpenTrace.event(eventType, message, metadata?) | Business event (bypasses level filtering) | | OpenTrace.trace(operation, fn) | Span timing for sync + async functions with nesting |

Request Context

| Method | Description | |---|---| | OpenTrace.addBreadcrumb({ category?, message, data?, level? }) | Add breadcrumb to current request | | OpenTrace.setTransactionName(name) | Override auto-detected transaction name | | OpenTrace.recordSql(name, durationMs, sql?) | Record SQL query in request summary | | OpenTrace.setContext(ctx) | Set global context merged into all entries |

Observability

| Method | Description | |---|---| | OpenTrace.stats() | Counter snapshot: enqueued, delivered, dropped, bytesSent, etc. | | OpenTrace.healthy() | Circuit breaker + auth status check | | OpenTrace.flush() | Manually trigger a flush (async) |

Middleware

| Method | Description | |---|---| | OpenTrace.middleware.express() | Express middleware (intercepts res.end) | | OpenTrace.middleware.fastify() | Fastify plugin (onRequest/onResponse hooks) | | OpenTrace.middleware.hono() | Hono middleware (async wrapper) |

How It Works

OpenTrace.log/error/event/trace
    ↓
level filter → enabled check → sample check
    ↓
create DeferredEntry (object literal — ~1μs)
    ↓
Client.enqueue → Array (bounded 1000, drop newest when full)
    ↓
              [setInterval flush timer — unreffed, won't keep process alive]
                        ↓
              PayloadBuilder.materialize(batch)
              (merge contexts, enrich with hostname/pid/gitSha)
                        ↓
              PII scrub → beforeSend filter → fitPayload (truncate)
                        ↓
              JSON.stringify → gzip if > threshold
                        ↓
              HTTP POST with exponential backoff retry
                        ↓
              circuit breaker → rate limit → auth suspension

Payload Truncation Order

When a single entry exceeds maxPayloadBytes, fields are removed in this order:

  1. stack_trace
  2. params
  3. job_arguments
  4. sql (truncated to 200 chars)
  5. exception_message (truncated to 200 chars)
  6. timeline
  7. Drop entire entry if still too large

Batch Splitting

When a batch exceeds maxPayloadBytes, it's recursively split in half (max depth 5) and sent as separate requests.

OpenTrace Ecosystem

This is the Node.js server-side client. OpenTrace has clients for every layer of your stack:

| Client | Platform | Repo | |---|---|---| | OpenTrace Server | Go — self-hosted observability | adham90/opentrace | | @opentrace-sdk/node | Node.js backends | adham90/opentrace_node | | opentrace (gem) | Ruby / Rails backends | adham90/opentrace_ruby | | opentrace.js | Browser error tracking | adham90/opentrace_browser |

All clients send the same JSON payload format to POST /api/logs, so the server treats them identically.

Requirements

  • Node.js >= 18
  • TypeScript >= 5.0 (if using TypeScript)

Development

npm install
npm test                  # vitest (189 tests)
npm run lint              # biome check
npm run typecheck         # tsc --noEmit
npm run build             # tsup (ESM + CJS)

Tests use real HTTP servers (node:http.createServer) as mock collectors — no mock libraries.

License

MIT