Skip to content
 
 

Repository files navigation

Elysia Prometheus Plugin

A lightweight plugin for Elysia that exposes HTTP metrics for Prometheus using prom-client. Automatically tracks request count, duration, method, status code, and more — with support for custom labels.

Features

  • ✅ Exposes /metrics endpoint (configurable)
  • 📊 Collects request duration and total request count
  • 🏷 Supports static and dynamic labels
  • 🧠 Route normalization for consistent metric names
  • 🪝 Integrates with derive and onAfterHandle lifecycle hooks

Installation

bun install elysia-prometheus

Usage

import { sleep } from 'bun'
import { Elysia, error } from 'elysia'
import prometheusPlugin from 'elysia-prometheus'

const app = new Elysia()
	.use(
		prometheusPlugin({
			metricsPath: '/metrics',
			staticLabels: { service: 'my-app' },
			dynamicLabels: {
				userAgent: (ctx) =>
					ctx.request.headers.get('user-agent') ?? 'unknown'
			}
		})
	)
	.get('/', () => 'GET /')
	.post('/', () => 'POST /')
	.get('/delay', () => {
		sleep(1000)
		return 'GET /delay'
	})
	.get('/error/:code', ({ params }) => {
		return error(Number.parseInt(params.code))
	})
	.listen(3000)

Custom metric prefix

Pass a metricPrefix to namespace every metric (HTTP metrics and the default Node.js process metrics). A trailing underscore is added automatically when omitted:

prometheusPlugin({
	metricPrefix: 'myapp' // or 'myapp_' — both produce the same output
})

With the prefix above, you'll see metrics like:

  • myapp_http_requests_total
  • myapp_http_request_duration_seconds
  • myapp_process_cpu_user_seconds_total
  • …and so on.

Metrics Exposed

HTTP metrics:

  • http_requests_total — Counter of total HTTP requests. Labels: method, path, status + custom.

  • http_request_duration_seconds — Histogram of request durations in seconds. Labels: method, path, status + custom.

  • http_requests_in_flight — Gauge of requests currently being handled. Labels: method + custom.

  • http_request_size_bytes — Histogram of request body sizes in bytes (derived from the Content-Length header; skipped when absent). Labels: method, path + custom.

  • http_response_size_bytes — Histogram of response body sizes in bytes (best-effort: uses Content-Length from ctx.set.headers or the returned Response, otherwise the byte length of string / ArrayBuffer / TypedArray bodies; streams and other shapes are skipped). Labels: method, path, status + custom.

  • http_requests_errors_total — Counter of requests that finished with a status >= 400. Labels: method, path, status, status_class (4xx / 5xx) + custom.

  • http_exceptions_total — Counter of unhandled exceptions captured in Elysia's onError hook. Labels: method, path, error (Elysia error code or Error.name) + custom.

  • http_route_info — Info-style gauge (always 1) emitted the first time each method + path combination is observed. Labels: method, path + static labels.

  • Node.js process metrics (CPU, memory, GC, event-loop lag, etc.) collected via prom-client's collectDefaultMetrics.

Default Labels

  • method – HTTP method (GET, POST, etc.)

  • path – Normalized route path (e.g., /users/:id)

  • status – HTTP status code (200, 404, etc.)

  • status_class – Status-code class bucket (4xx, 5xx) — used on http_requests_errors_total.

  • error – Error code / name — used on http_exceptions_total.

Custom Labels

  • staticLabels: Adds the same label value for every request

  • dynamicLabels: Functions that extract values from each request context

Plugin Options

Option Type Default Description
metricsPath string "/metrics" URL path to expose metrics
metricPrefix string "" Prefix prepended to every metric name, including the default Node.js process metrics. A trailing _ is appended automatically if you don't include one (e.g. "myapp" and "myapp_" both yield myapp_http_requests_total).
durationBuckets number[] [0.003, 0.03, 0.1, 0.3, 1.5, 10] Histogram buckets for request duration
sizeBuckets number[] [64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 5242880] Histogram buckets (bytes) for request/response size
staticLabels Record<string, string> {} Static labels added to all metrics
dynamicLabels Record<string, (ctx: Context) => string> {} Dynamic labels based on request context
useRoutePath boolean true Use route pattern instead of raw URL (e.g. /users/:id instead of /users/123)

⚠️ Label names method, path, status, status_class, and error are reserved and cannot be overridden.

Route Normalization

The plugin automatically normalizes paths like:

/users/123/orders/456 → /users/:id/orders/:id

This prevents metric explosion from unique IDs in URLs.

License

MIT

Contributing

If you want to add or improve the library or its documentation, make a pull request to this repository. Please use bun and format js and ts code with prettier to make everything look nice.

About

Prometheus metrics plugin for Elysia framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages