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

@galaxy-stack/orbit-telemetry

v0.1.10

Published

Telemetry and observability for Orbit - metrics, tracing, and health monitoring

Readme

@galaxy-stack/orbit-telemetry

Telemetry and observability module for Orbit - Prometheus-compatible metrics, distributed tracing with OpenTelemetry support, and request monitoring.

Installation

bun add @galaxy-stack/orbit-telemetry

Features

Metrics

  • Prometheus-compatible metrics format
  • Counter, Gauge, and Histogram metric types
  • Default process metrics (memory, uptime, event loop lag)
  • HTTP request metrics middleware
  • Method decorators for automatic timing and counting
  • MetricsProvider base class for decorator-based metrics

Tracing

  • OpenTelemetry-compatible distributed tracing
  • W3C Trace Context propagation
  • Span and Tracer APIs
  • @Trace() method decorator
  • Multiple exporters: Console, OTLP
  • Sampling strategies: AlwaysOn, AlwaysOff, Probability, RateLimiting

Quick Start

Metrics Setup

import { Module } from '@galaxy-stack/orbit-core';
import { MetricsModule } from '@galaxy-stack/orbit-telemetry';

@Module({
  imports: [
    MetricsModule.forRoot({
      path: '/metrics',
      collectDefaultMetrics: true,
      defaultLabels: {
        app: 'my-service',
        env: 'production',
      },
    }),
  ],
})
export class AppModule {}

Tracing Setup

import { Module } from '@galaxy-stack/orbit-core';
import { TracingModule, ConsoleExporter, OTLPExporter } from '@galaxy-stack/orbit-telemetry';

@Module({
  imports: [
    TracingModule.forRoot({
      serviceName: 'my-service',
      serviceVersion: '1.0.0',
      exporter: new ConsoleExporter({ prettyPrint: true }),
      // Or use OTLP for production:
      // exporter: new OTLPExporter({
      //   endpoint: 'http://localhost:4318',
      //   serviceName: 'my-service',
      // }),
    }),
  ],
})
export class AppModule {}

Using Tracer

import { Injectable } from '@galaxy-stack/orbit-core';
import { Tracer, SpanKind, SpanStatusCode } from '@galaxy-stack/orbit-telemetry';

@Injectable()
export class OrderService {
  constructor(private readonly tracer: Tracer) {}

  async processOrder(orderId: string) {
    return this.tracer.startActiveSpan('processOrder', {
      kind: SpanKind.INTERNAL,
      attributes: { 'order.id': orderId },
    }, async (span) => {
      try {
        await this.validateOrder(orderId);
        await this.chargePayment(orderId);
        await this.shipOrder(orderId);
        
        span.setStatus({ code: SpanStatusCode.OK });
        return { success: true };
      } catch (error) {
        span.setStatus({
          code: SpanStatusCode.ERROR,
          message: error.message,
        });
        throw error;
      }
    });
  }

  private async validateOrder(orderId: string) {
    return this.tracer.startActiveSpan('validateOrder', async (span) => {
      span.setAttribute('order.id', orderId);
      // Validation logic
      span.addEvent('validation_complete');
    });
  }
}

Using @Trace() Decorator

import { Injectable } from '@galaxy-stack/orbit-core';
import { TracingProvider, Tracer, Trace, SpanKind } from '@galaxy-stack/orbit-telemetry';

@Injectable()
export class PaymentService extends TracingProvider {
  constructor(tracer: Tracer) {
    super(tracer);
  }

  @Trace({ kind: SpanKind.CLIENT })
  async chargeCard(amount: number) {
    // This method is automatically traced
    return await this.gateway.charge(amount);
  }

  @Trace({ name: 'payment.refund' })
  async refund(transactionId: string) {
    return await this.gateway.refund(transactionId);
  }
}

Distributed Tracing

Context Propagation

Context is automatically propagated via W3C Trace Context headers:

import { extractContext, injectContext } from '@galaxy-stack/orbit-telemetry';

// Extract context from incoming request
const parentContext = extractContext(request.headers);

// Inject context into outgoing request
const headers = new Headers();
injectContext(span.spanContext, headers);
await fetch('http://other-service/api', { headers });

TracingMiddleware

Automatically trace all HTTP requests:

import { TracingMiddleware } from '@galaxy-stack/orbit-telemetry';

// Applied via module configuration
// Traces: http.method, http.url, http.status_code, etc.

Exporters

Console Exporter

import { ConsoleExporter } from '@galaxy-stack/orbit-telemetry';

const exporter = new ConsoleExporter({
  prettyPrint: true,  // Human-readable format
  logLevel: 'info',   // 'debug' | 'info' | 'log'
});

OTLP Exporter

Export to OpenTelemetry Collector, Jaeger, or any OTLP-compatible backend:

import { OTLPExporter } from '@galaxy-stack/orbit-telemetry';

const exporter = new OTLPExporter({
  endpoint: 'http://localhost:4318',
  serviceName: 'my-service',
  serviceVersion: '1.0.0',
  headers: {
    'Authorization': 'Bearer token',
  },
  timeout: 10000,
});

Samplers

Control which traces are recorded:

import {
  AlwaysOnSampler,
  AlwaysOffSampler,
  ProbabilitySampler,
  RateLimitingSampler,
  ParentBasedSampler,
} from '@galaxy-stack/orbit-telemetry';

// Sample 10% of traces
const sampler = new ProbabilitySampler(0.1);

// Max 100 traces per second
const rateSampler = new RateLimitingSampler(100);

// Always sample if parent was sampled
const parentSampler = new ParentBasedSampler(new ProbabilitySampler(0.5));

Metrics API

Counter

const counter = registry.createCounter({
  name: 'http_requests_total',
  help: 'Total HTTP requests',
  labelNames: ['method', 'status'],
});

counter.inc();
counter.inc({ method: 'GET', status: '200' }, 5);

Gauge

const gauge = registry.createGauge({
  name: 'active_connections',
  help: 'Number of active connections',
});

gauge.set(42);
gauge.inc();
gauge.dec();

Histogram

const histogram = registry.createHistogram({
  name: 'request_duration_seconds',
  help: 'Request duration',
  buckets: [0.01, 0.05, 0.1, 0.5, 1, 5],
});

histogram.observe(0.234);

// Timer helper
const timer = histogram.startTimer();
await doWork();
timer();

Default Metrics

When collectDefaultMetrics: true:

| Metric | Type | Description | |--------|------|-------------| | process_start_time_seconds | Gauge | Process start time | | process_uptime_seconds | Gauge | Process uptime | | process_resident_memory_bytes | Gauge | Memory RSS | | nodejs_heap_size_used_bytes | Gauge | Heap used | | nodejs_heap_size_total_bytes | Gauge | Heap total | | nodejs_eventloop_lag_seconds | Gauge | Event loop lag | | bun_version_info | Gauge | Bun version |

Module Options

MetricsModuleOptions

interface MetricsModuleOptions {
  path?: string;                    // Default: '/metrics'
  defaultLabels?: Record<string, string>;
  collectDefaultMetrics?: boolean;  // Default: true
  collectInterval?: number;         // Default: 10000ms
  isGlobal?: boolean;               // Default: true
}

TracingModuleOptions

interface TracingModuleOptions {
  serviceName: string;
  serviceVersion?: string;
  exporter?: SpanExporter;
  sampler?: Sampler;
  batchSize?: number;       // Default: 100
  flushInterval?: number;   // Default: 5000ms
  isGlobal?: boolean;       // Default: true
}

Integration Example

Full observability setup:

import { Module } from '@galaxy-stack/orbit-core';
import { 
  MetricsModule, 
  TracingModule, 
  OTLPExporter,
  ProbabilitySampler,
} from '@galaxy-stack/orbit-telemetry';

@Module({
  imports: [
    MetricsModule.forRoot({
      path: '/metrics',
      collectDefaultMetrics: true,
      defaultLabels: {
        service: 'order-service',
        env: process.env.NODE_ENV,
      },
    }),
    TracingModule.forRoot({
      serviceName: 'order-service',
      serviceVersion: '1.0.0',
      exporter: new OTLPExporter({
        endpoint: process.env.OTLP_ENDPOINT || 'http://localhost:4318',
        serviceName: 'order-service',
      }),
      sampler: new ProbabilitySampler(0.1),
    }),
  ],
})
export class AppModule {}