Monitoring and Metrics

Expose Health Routes and Prometheus Metrics with prom-client

Monitoring and Metrics

Add liveness and readiness HTTP endpoints plus a /metrics route backed by prom-client so orchestrators and dashboards can observe your Koa service.

4 min read Level 2/5 #koa#production#monitoring
What you'll learn
  • Implement /health/live and /health/ready endpoints for Kubernetes probes
  • Collect default Node.js metrics with prom-client
  • Add a custom HTTP request counter and response-time histogram

Production services need two kinds of observability: health checks that tell orchestrators whether the process is alive and ready to accept traffic, and metrics that tell your dashboard how the service behaves over time.

Health and Readiness Routes

Kubernetes (and most other platforms) distinguishes between a liveness probe — “is the process up?” — and a readiness probe — “is it ready to serve traffic?”

import Koa from "koa";
import Router from "@koa/router";

const app = new Koa();
const router = new Router();

// Liveness: returns 200 as long as the process is running
router.get("/health/live", (ctx) => {
  ctx.body = { status: "ok", uptime: process.uptime() };
});

// Readiness: check dependencies before accepting traffic
let dbReady = false; // set to true after DB pool connects

router.get("/health/ready", async (ctx) => {
  if (!dbReady) {
    ctx.status = 503;
    ctx.body = { status: "not ready", reason: "db not connected" };
    return;
  }
  ctx.body = { status: "ready" };
});

Installing prom-client

npm i prom-client

Enabling Default Metrics

prom-client ships with a set of default Node.js metrics (event loop lag, heap usage, GC duration) that you get for free with one call.

import { collectDefaultMetrics, Registry } from "prom-client";

const register = new Registry();
collectDefaultMetrics({ register });

Exposing /metrics

router.get("/metrics", async (ctx) => {
  ctx.set("Content-Type", register.contentType);
  ctx.body = await register.metrics();
});

Prometheus scrapes this endpoint on its configured interval. Lock it down behind network policy or an API gateway so it is not publicly accessible.

Custom HTTP Metrics

Track request counts and latency per route:

import { Counter, Histogram } from "prom-client";

const httpRequests = new Counter({
  name: "http_requests_total",
  help: "Total HTTP requests",
  labelNames: ["method", "route", "status"],
  registers: [register],
});

const httpDuration = new Histogram({
  name: "http_request_duration_seconds",
  help: "HTTP request duration",
  labelNames: ["method", "route"],
  registers: [register],
});

// Middleware — register before your router
app.use(async (ctx, next) => {
  const end = httpDuration.startTimer({ method: ctx.method, route: ctx.path });
  await next();
  end();
  httpRequests.inc({ method: ctx.method, route: ctx.path, status: ctx.status });
});

Uptime and Process Info

The default metrics include process_uptime_seconds. You can also surface it directly in the liveness response via process.uptime() as shown above, which is useful for quick manual checks with curl.

Up Next

Learn to debug a misbehaving Koa app with the DEBUG flag and the Node.js inspector.

Debugging Koa Apps →