Prometheus Metrics in TypeScript: A Complete Guide
Prometheus is an open-source system for monitoring and alerting that collects metrics from your applications in real time. In this article, we will look at how to integrate Prometheus metrics into TypeScript applications using the prom-client library. You will learn how to create, register, and export metrics, as well as how to set up an endpoint for data collection.
What are Prometheus Metrics?
Prometheus operates on a pull model: it periodically scrapes your application's endpoints to obtain metrics. Metrics are divided into several main types:
- Counter — only increases (e.g., number of requests).
- Gauge — can increase and decrease (e.g., current number of active users).
- Histogram — measures the distribution of values (e.g., response time).
- Summary — similar to a histogram, but calculates quantiles on the client side.
Installing prom-client in TypeScript
To work with Prometheus in TypeScript, we will use the official prom-client library. Install it via npm:
npm install prom-clientAlso install the types for TypeScript:
npm install @types/prom-client --save-devCreating and Registering Metrics
Let's look at a basic example of creating metrics. Create a file metrics.ts:
import client from 'prom-client';
// Create a registry for metrics (global is used by default)const register = new client.Registry();
// Add default metrics (e.g., memory, CPU)client.collectDefaultMetrics({ register });
// Create a Counter for counting requestsconst httpRequestsTotal = new client.Counter({ name: 'http_requests_total', help: 'Total number of HTTP requests', labelNames: ['method', 'status', 'path'], registers: [register],});
// Create a Gauge for active connectionsconst activeConnections = new client.Gauge({ name: 'active_connections', help: 'Number of active connections', registers: [register],});
// Create a Histogram for response timeconst httpRequestDuration = new client.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'path'], buckets: [0.01, 0.05, 0.1, 0.5, 1, 5], registers: [register],});
export { register, httpRequestsTotal, activeConnections, httpRequestDuration };Using Metrics in an Express Application
Now let's create a simple Express application in TypeScript that will use our metrics:
import express from 'express';import { register, httpRequestsTotal, activeConnections, httpRequestDuration } from './metrics';
const app = express();const port = 3000;
// Middleware for counting request timeapp.use((req, res, next) => { const end = httpRequestDuration.startTimer({ method: req.method, path: req.path }); activeConnections.inc();
res.on('finish', () => { httpRequestsTotal.inc({ method: req.method, status: res.statusCode.toString(), path: req.path }); activeConnections.dec(); end(); });
next();});
// Endpoint for Prometheusapp.get('/metrics', async (req, res) => { res.set('Content-Type', register.contentType); res.end(await register.metrics());});
// Example endpointapp.get('/', (req, res) => { res.send('Hello, Prometheus!');});
app.listen(port, () => { console.log(`Server running at http://localhost:${port}`);});Running and Testing
Start the application:
npx ts-node app.tsOpen in