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

@webtypen/webframez-telemetry

v0.0.3

Published

Optional telemetry addon for @webtypen/webframez-core with route, job and command instrumentation

Readme

@webtypen/webframez-telemetry

Optional telemetry addon for @webtypen/webframez-core.

It tracks and groups runtime data by:

  • routes
  • queue jobs
  • console commands
  • runtime/process metrics (CPU + memory)

The package is OpenTelemetry-compatible:

  • spans are created via @opentelemetry/api
  • metrics are recorded via OpenTelemetry meters
  • semantic attributes like service.name, http.request.method, url.template and webframez.* are attached
  • you can plug in any OpenTelemetry SDK/exporter (OTLP, Prometheus bridge, SigNoz, Grafana, Datadog, ...)

Install

npm i @webtypen/webframez-telemetry

For export to OTel backends you also need an OpenTelemetry SDK setup (application-side):

npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http

OpenTelemetry Export Setup

@webtypen/webframez-telemetry itself does not ship a collector/exporter.
You connect your app to any backend by configuring NodeSDK + OTLP exporter.

Create a bootstrap file (load it before app startup):

// telemetry-otel.ts
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  // Example: http://localhost:4318/v1/traces
  // Prefer env vars in production.
});

export const otelSdk = new NodeSDK({
  traceExporter: exporter,
  instrumentations: [getNodeAutoInstrumentations()],
});

export async function startOtel() {
  await otelSdk.start();
}

export async function stopOtel() {
  await otelSdk.shutdown();
}

Typical env vars:

OTEL_SERVICE_NAME=my-webframez-app
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
# optional:
# OTEL_EXPORTER_OTLP_HEADERS=key=value,key2=value2

Quick Start

Hook-based telemetry is the preferred integration for webframez-core versions that export WebframezHooks.

import { initWebframezTelemetry } from "@webtypen/webframez-telemetry";
import { Route, WebApplication } from "@webtypen/webframez-core";

const telemetry = initWebframezTelemetry({
  serviceName: "my-webframez-app",
  traces: true,
  metrics: true,
  runtime: { enabled: true }
});

Route.get("/health", async () => {
  return { ok: true };
});

new WebApplication().boot({
  routesFunction: () => {},
});

initWebframezTelemetry() subscribes to core lifecycle hooks and emits OpenTelemetry spans and metrics. The package does not initialize an SDK or exporter for you; configure the OpenTelemetry SDK in your application bootstrap.

Metrics

The hook subscriber records:

  • http.server.request.duration histogram in seconds
  • http.server.active_requests up/down counter
  • webframez.command.duration histogram in seconds
  • webframez.queue.job.duration histogram in seconds
  • webframez.route.handler.duration histogram in seconds
  • webframez.operation.errors counter

Runtime metrics are exposed as observable gauges:

  • process.cpu.percent
  • process.memory.rss
  • process.memory.heap_used
  • system.memory.used_percent

Legacy wrappers

The older wrapper APIs are still exported for compatibility:

  • initWebframezTelemetryRoute
  • instrumentConsoleCommandClass
  • instrumentQueueJobClass
  • wrapRouteHandler
  • wrapCommandHandler
  • wrapJobHandler

Prefer the hook-based API for new integrations.

Instrument Commands

import { instrumentConsoleCommandClass } from "@webtypen/webframez-telemetry";
import { MyCommand } from "./commands/MyCommand";

const TelemetryMyCommand = instrumentConsoleCommandClass(MyCommand, telemetry);

Instrument Queue Jobs

import { instrumentQueueJobClass } from "@webtypen/webframez-telemetry";
import { SendMailJob } from "./jobs/SendMailJob";

const TelemetrySendMailJob = instrumentQueueJobClass(SendMailJob, telemetry);

Read Metrics Snapshot

const snapshot = telemetry.snapshot();
console.log(snapshot.routes);
console.log(snapshot.jobs);
console.log(snapshot.commands);

Snapshot fields include:

  • calls
  • errors
  • error_rate
  • active
  • max_active
  • avg_duration_ms
  • min_duration_ms
  • max_duration_ms

Runtime snapshot fields include:

  • runtime.last_sample.cpu.process_percent
  • runtime.last_sample.memory.process_rss_bytes
  • runtime.last_sample.memory.process_heap_used_bytes
  • runtime.last_sample.memory.system_used_percent
  • runtime.cpu.process_percent_avg
  • runtime.memory.process_heap_used_avg_bytes

Runtime Sampling Configuration

Defaults are tuned for low overhead:

  • enabled: true
  • sampleIntervalMs: 5000
  • historyLimit: 120 (about 10 minutes at 5s interval)
  • emitToTracer: false

You can reconfigure at runtime:

telemetry.configureRuntimeSampling({
  sampleIntervalMs: 2000,
  historyLimit: 300
});

const runtimeNow = telemetry.sampleRuntimeNow();
console.log(runtimeNow.last_sample);

Backend Examples

The package does not need backend-specific changes for these systems.
Use the same NodeSDK pattern and switch exporter config per target.

SigNoz

  • Recommended: OTLP to SigNoz Collector
  • Traces endpoint (default self-host): http://<signoz-host>:4318/v1/traces
  • Usually no custom headers needed in trusted network.
// telemetry-otel.ts (SigNoz)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<signoz-host>:4318/v1/traces",
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Grafana Tempo

  • Send OTLP directly to Tempo (if OTLP receiver is enabled) or via Grafana Alloy/Otel Collector.
  • Typical endpoint: http://<tempo-or-collector-host>:4318/v1/traces
// telemetry-otel.ts (Grafana Tempo)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<tempo-or-collector-host>:4318/v1/traces",
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Jaeger

  • Modern Jaeger supports OTLP ingest.
  • Typical endpoint: http://<jaeger-host>:4318/v1/traces
  • Alternative: route via OpenTelemetry Collector and forward to Jaeger.
// telemetry-otel.ts (Jaeger OTLP)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<jaeger-host>:4318/v1/traces",
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Zipkin (via Collector)

  • Recommended path: app -> OpenTelemetry Collector (OTLP) -> Zipkin exporter.
  • App endpoint: http://<otel-collector-host>:4318/v1/traces
  • Zipkin is configured inside the collector, not in this package.
// telemetry-otel.ts (Zipkin via OTel Collector)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<otel-collector-host>:4318/v1/traces",
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Datadog

  • Recommended path: app -> Datadog Agent OTLP ingest.
  • Typical endpoint: http://<datadog-agent-host>:4318/v1/traces
  • If your Datadog setup requires API key headers for direct ingest, provide them with OTEL_EXPORTER_OTLP_HEADERS.
// telemetry-otel.ts (Datadog via Agent OTLP)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<datadog-agent-host>:4318/v1/traces",
  // headers: { "DD-API-KEY": "<api-key>" }, // only if required by your setup
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

New Relic

  • Use OTLP endpoint with API key header.
  • Typical endpoint: https://otlp.nr-data.net:4318/v1/traces
  • Typical header: api-key=<NEW_RELIC_LICENSE_KEY> via OTEL_EXPORTER_OTLP_HEADERS.
// telemetry-otel.ts (New Relic)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "https://otlp.nr-data.net:4318/v1/traces",
  headers: {
    "api-key": process.env.NEW_RELIC_LICENSE_KEY || "",
  },
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Elastic APM

  • Use OTLP ingest on APM Server.
  • Typical endpoint: http://<elastic-apm-host>:8200/v1/traces
  • If required, set auth header via OTEL_EXPORTER_OTLP_HEADERS (for example Authorization=Bearer <token>).
// telemetry-otel.ts (Elastic APM OTLP)
import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "http://<elastic-apm-host>:8200/v1/traces",
  headers: process.env.ELASTIC_APM_TOKEN
    ? { Authorization: `Bearer ${process.env.ELASTIC_APM_TOKEN}` }
    : {},
});

export const otelSdk = new NodeSDK({ traceExporter: exporter });

Other OTel-compatible backends

  • If it accepts OTLP traces, set:
    • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
    • optional OTEL_EXPORTER_OTLP_HEADERS
  • No package code changes are required.

Notes

  • Route auto-instrumentation wraps function-based route handlers.
  • String-controller routes ("MyController@method") are not auto-wrapped; use wrapper helpers where needed.
  • This package only emits telemetry; export/ingest is handled by your OpenTelemetry SDK setup.