Developer-First Observability
A turnkey monitoring system for Express and NestJS backends, paired with ready-to-mount React & Next.js admin dashboards. Collect Prometheus metrics, OpenTelemetry traces, and intelligent error fingerprints with zero external framework lock-in.
Backend Core SDK
One-line middleware setup for Express and NestJS. Exposes /metrics for Prometheus and /api/observability/stats.
React Dashboard UI
6 pre-built dashboard layouts, 6 runtime color themes, deep error inspector with stack traces and breadcrumb timelines.
Zero-Config CLI
Detects Next.js App/Pages Router and Vite. Installs UI routes, initializes configs, and validates connectivity with doctor.
⚡️ Quick Start in 3 Steps
npm install @stacklenzz/server
npx stacklenzz dashboard
Navigate to your frontend application to inspect live traffic, latencies, and errors in real-time:
📦 Installation Options
Choose your preferred installation method:
# 1. Scaffold Dashboard Route npx stacklenzz dashboard # 2. Run Doctor to Validate Connection npx stacklenzz doctor
React & Next.js UI Dashboard
Render the unified <ObservabilityDashboard /> inside any client component:
"use client";
import { ObservabilityDashboard } from "@stacklenzz/ui";
export default function AdminObservabilityPage() {
return (
<main className="min-h-screen bg-background">
<ObservabilityDashboard
config={{
endpoint: "http://localhost:5000/api/observability/stats",
refreshIntervalMs: 5000,
}}
defaultDashboard="full"
showSwitcher={true}
/>
</main>
);
}6 Built-in Runtime Themes & State Management
Switch themes live on the UI or configure your preferred default aesthetic. Powered by built-in state management with automatic localStorage persistence (stacklenzz_theme):
The service header dynamically calculates composite system health (HEALTHY / DEGRADED / CRITICAL) in real-time, respecting your active Error Rate time window filter (e.g. Last 1 min, Last 5 min, Last 1 hour, or All-time):
- CRITICAL: Triggered if active 5xx Error Rate ≥ 5.0%, P95 Latency ≥ 2,000ms, CPU Load ≥ 90%, Event Loop Lag ≥ 100ms, or Heap ≥ 95% (when Heap > 128MB).
- DEGRADED: Triggered if active 5xx Error Rate ≥ 1.0%, P95 Latency ≥ 800ms, CPU Load ≥ 75%, Event Loop Lag ≥ 30ms, or Heap ≥ 85% (when Heap > 128MB).
- HEALTHY: All metrics operating within normal baseline boundaries.
Error Rate % = (Total HTTP 500+ Responses / Total HTTP Responses) × 100HTTP 4xx client errors (such as 404 Not Found or 401 Unauthorized) are tracked in HTTP breakdown charts but excluded from health degradation formulas so client mistakes do not impact server SLA scores.* Note: Persisted PostgreSQL / MongoDB database crash logs (dbCrashLogs) are excluded from active health evaluation so historical entries from prior instances do not falsely mark a clean server instance as degraded.
Theme selections automatically persist immediately to localStorage (key: stacklenzz_theme). Upon page reloads or navigating between administrative views, your chosen theme is instantly restored without visual flickering.
💻 Stacklenzz CLI Reference
The CLI is accessible via stacklenzz, stackcli, or short command stack:
1. dashboard
Auto-detects framework and generates an admin dashboard route with your choice of 7 templates.
npx stacklenzz dashboardSupports --dry-run, -y, and custom --route2. doctor
Validates dependencies and tests live telemetry reachability against your backend.
npx stacklenzz doctorCustom endpoint: --endpoint <url>3. init
Creates a strongly-typed observability.config.ts configuration file.
npx stacklenzz initInstant TypeScript starter configurationExpress Instrumentation
Import setupObservability directly from @stacklenzz/server/express and call it before declaring routes:
import express from "express";
import { setupObservability } from "@stacklenzz/server/express";
import { logger, addBreadcrumb } from "@stacklenzz/server/core";
const app = express();
// Automatically configures:
// 1. /metrics (Prometheus scraper)
// 2. /api/observability/stats (JSON telemetry feed for dashboard UI)
// 3. OpenTelemetry NodeSDK distributed tracing
// 4. Winston JSON structured logging
setupObservability(app, {
serviceName: "billing-service",
environment: "production",
});
app.get("/api/checkout", (req, res) => {
addBreadcrumb({ category: "cart", message: "Processing card payment", level: "info" });
res.json({ status: "success" });
});
// Fallback for non-existent routes (captured as 404 in dashboard)
app.use((req, res) => {
res.status(404).json({ statusCode: 404, error: "Not Found", message: `Cannot ${req.method} ${req.url}` });
});
app.listen(5000, () => console.log("Server listening on port 5000"));NestJS Module Setup
Import ObservabilityModule directly from @stacklenzz/server/nestjs in your root AppModule:
import { Module } from "@nestjs/common";
import { ObservabilityModule } from "@stacklenzz/server/nestjs";
@Module({
imports: [
ObservabilityModule.forRoot({
serviceName: "auth-service",
environment: process.env.NODE_ENV || "production",
autoInitTracing: true,
}),
],
})
export class AppModule {}import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { ObservabilityModule } from "@stacklenzz/server/nestjs";
@Module({
imports: [
ConfigModule.forRoot(),
ObservabilityModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
serviceName: config.get<string>("APP_NAME", "auth-service"),
environment: config.get<string>("NODE_ENV", "production"),
}),
}),
],
})
export class AppModule {}📦 Node.js Framework Compatibility
If your backend uses Fastify, Koa, Hono, Hapi, or pure Node.js http, you can use @stacklenzz/server/core to capture errors, record Prometheus metrics, and feed real-time telemetry to the dashboard:
import Fastify from "fastify";
import { getObservabilitySnapshot, recordError } from "@stacklenzz/server/core";
const fastify = Fastify();
// Expose stats endpoint for dashboard UI
fastify.get("/api/observability/stats", async (request, reply) => {
const snapshot = await getObservabilitySnapshot();
return reply.header("Access-Control-Allow-Origin", "*").send(snapshot);
});
// Capture unhandled errors into the dashboard error stream
fastify.setErrorHandler((error, request, reply) => {
recordError({
message: error.message,
stack: error.stack,
route: request.url,
method: request.method,
statusCode: error.statusCode || 500,
});
reply.status(error.statusCode || 500).send({ error: error.message });
});import Koa from "koa";
import Router from "@koa/router";
import { getObservabilitySnapshot, recordError } from "@stacklenzz/server/core";
const app = new Koa();
const router = new Router();
// Stats endpoint
router.get("/api/observability/stats", async (ctx) => {
ctx.set("Access-Control-Allow-Origin", "*");
ctx.body = await getObservabilitySnapshot();
});
// Global error tracking middleware
app.use(async (ctx, next) => {
try {
await next();
} catch (err: any) {
recordError({
message: err.message,
stack: err.stack,
route: ctx.path,
method: ctx.method,
statusCode: err.status || 500,
});
throw err;
}
});
app.use(router.routes());import { Hono } from "hono";
import { getObservabilitySnapshot, recordError } from "@stacklenzz/server/core";
const app = new Hono();
app.get("/api/observability/stats", async (c) => {
c.header("Access-Control-Allow-Origin", "*");
return c.json(await getObservabilitySnapshot());
});
app.onError((err, c) => {
recordError({
message: err.message,
stack: err.stack,
route: c.req.path,
method: c.req.method,
statusCode: 500,
});
return c.text("Internal Server Error", 500);
});⚡️ Advanced SDK Features & Telemetry APIs
Unlock powerful built-in telemetry utilities directly from @stacklenzz/server:
1. Automatic Error Fingerprinting & Deduplication
Error messages are dynamically sanitized (stripping IDs, timestamps, and numbers) to compute a deterministic hash. 50 recurring database failures appear as 1 grouped incident card with occurrence counters (x50) and occurrence timestamps.
2. Programmatic Snapshot API
getObservabilitySnapshotGenerate instant JSON operational snapshots directly inside your Node.js code to stream live metrics via WebSockets or push custom alerts to Slack/Discord.
3. Custom Prometheus Metrics
CounterGaugeregisterRe-exports prom-client primitives directly. Register custom domain metrics (e.g. orders_created_total) without installing extra dependencies.
4. OpenTelemetry Native Exports
tracecontextDirect access to OpenTelemetry API primitives to create custom spans and extract active trace IDs without installing @opentelemetry/api separately.
import { getObservabilitySnapshot, Counter, register } from "@stacklenzz/server/core";
// 1. Register custom business metric on the /metrics endpoint
const ordersCounter = new Counter({
name: "orders_processed_total",
help: "Total processed checkout orders",
registers: [register],
});
ordersCounter.inc();
// 2. Fetch live telemetry JSON directly in backend code
const snapshot = await getObservabilitySnapshot();
console.log("Current Error Rate:", snapshot.summary.errorRate);
console.log("Active Requests:", snapshot.summary.activeRequests);📊 Metrics & OpenTelemetry Distributed Tracing
@stacklenzz/server provides built-in Prometheus metric collection via prom-client on /metrics and OpenTelemetry NodeSDK tracing:
http_requests_total: Counter tracking total HTTP requests broken down by method, route, and status code.http_request_duration_seconds: Histogram tracking P50, P95, and P99 latency percentiles across endpoints.http_active_requests: Gauge monitoring active in-flight requests.- Standard Node.js runtime metrics: CPU usage %, RSS/Heap memory, and V8 event loop lag.
import { initTracing, logger } from "@stacklenzz/server";
// Tracing auto-initializes by default, injecting trace_id and span_id into Winston logs
logger.info("Processing order checkout", { orderId: "ORD-9912" });
// Output: {"level":"info","message":"Processing order checkout","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","span_id":"00f067aa0ba902b7"}🐞 Error Intelligence & Event Breadcrumbs
Trace user interactions and operations prior to a failure using event breadcrumbs:
import { addBreadcrumb, logger } from "@stacklenzz/server";
// 1. Record event trail before operations
addBreadcrumb({ category: "auth", message: "User session validated: usr_9921", level: "info" });
addBreadcrumb({ category: "db", message: "SELECT * FROM orders WHERE id = 'ORD-9912'", level: "info" });
// 2. Log error when failure occurs
try {
throw new Error("DatabaseConnectionTimeout: Pool limit reached");
} catch (err) {
// Breadcrumbs recorded above are automatically attached to this error card!
logger.error(err);
}💾 Pluggable Database Crash Log Adaptor
Persist 5xx server crashes directly to your own database (PostgreSQL, MongoDB, Redis, Prisma, TypeORM, DynamoDB, etc.) without sending operational logs to third-party SaaS vendors:
Zero setup or database overhead if omitted. In-memory ring buffers keep working out-of-the-box.
Triggers only for 5xx HTTP errors and uncaught server exceptions. Excludes 4xx client errors and info logs.
Dispatched asynchronously. A failing database write or network rejection will never crash your API app.
import { setupObservability, CrashLogEntry } from "@stacklenzz/server";
setupObservability(app, {
serviceName: "payment-api",
environment: "production",
// Configure pluggable crash log adaptor for database persistence & UI management
crashLogAdaptor: {
// 1. Save 5xx server crash entry
save: async (entry: CrashLogEntry) => {
await db.crashLogs.create({ data: entry });
},
// 2. Query persisted logs for the UI dashboard
list: async () => {
return await db.crashLogs.findMany({ orderBy: { timestamp: "desc" } });
},
// 3. Delete an individual crash log from the UI dashboard
delete: async (id: string) => {
await db.crashLogs.delete({ where: { id } });
},
// 4. Purge all crash logs from the UI dashboard ("Clear All Logs")
clearAll: async () => {
await db.crashLogs.deleteMany({});
},
},
});🔒 Production Auth & Middleware Security
Because the dashboard displays live backend request timings and error logs, ensure the /admin/observability route is protected behind your application authentication layer:
// middleware.ts (Next.js App Router)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(req: NextRequest) {
if (req.nextUrl.pathname.startsWith("/admin/observability")) {
const adminToken = req.cookies.get("admin_session");
if (!adminToken) {
return NextResponse.redirect(new URL("/login", req.url));
}
}
return NextResponse.next();
}🚀 Hosting Live on Vercel / Cloud
Deploying your frontend dashboard and backend services to production:
Set the environment variable NEXT_PUBLIC_OBSERVABILITY_URL to point to your live backend endpoint (e.g. https://api.yourdomain.com/api/observability/stats).
Ensure CORS headers permit requests from your admin dashboard origin in setupObservability or NestJS app.enableCors().
🤝 Contributing
We welcome contributions to improve the documentation and the Stacklenzz ecosystem!
- Documentation Website Repo: https://github.com/ideateGudy/stacklenzz-docs
- Main Monorepo (Source Code): https://github.com/ideateGudy/stacklenzz