A TypeScript/Node.js Prometheus client library that lets applications define and collect metrics (counters, gauges, histograms) and expose them in the Prometheus text format.
- âś… Counter - A cumulative metric that only increases
- âś… Gauge - A metric that can go up and down
- âś… Histogram - Samples observations and counts them in configurable buckets
- âś… Labels - Support for multi-dimensional metrics with labels
- âś… Registry - Central management of multiple metrics
- âś… Prometheus Format - Native output in Prometheus text format
- âś… TypeScript - Full TypeScript support with type definitions
- âś… ES Modules - Modern ES module support
npm install promliteimport { Counter, Gauge, Histogram, register } from 'promlite';
// Create metrics
const httpRequestsTotal = new Counter(
'http_requests_total',
'Total number of HTTP requests',
['method', 'status_code']
);
const httpRequestDuration = new Histogram(
'http_request_duration_seconds',
'HTTP request duration in seconds',
[0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10],
['method', 'route']
);
const activeConnections = new Gauge(
'active_connections',
'Number of active connections'
);
// Register metrics
register.register('http_requests_total', httpRequestsTotal);
register.register('http_request_duration_seconds', httpRequestDuration);
register.register('active_connections', activeConnections);
// Use metrics
httpRequestsTotal.inc(['GET', '200']);
httpRequestDuration.observe(['GET', '/api/users'], 0.243);
activeConnections.set(15);
// Export metrics in Prometheus format
console.log(register.metrics());A counter is a cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero.
new Counter(name: string, help: string, labels?: string[])// Increment by 1 (default)
counter.inc();
// Increment by custom amount
counter.inc(5);
// Increment with labels
counter.inc(['GET', '200']);
counter.inc(['GET', '200'], 3);
// Get current value
counter.getValue(); // for metrics without labels
counter.getValue(['GET', '200']); // for metrics with labels
// Reset to zero
counter.reset();
// Export to Prometheus format
counter.toPrometheus();import { Counter } from 'promlite';
const httpRequestsTotal = new Counter(
'http_requests_total',
'Total number of HTTP requests',
['method', 'status_code']
);
// Increment counters
httpRequestsTotal.inc(['GET', '200']);
httpRequestsTotal.inc(['POST', '201'], 3);
httpRequestsTotal.inc(['GET', '404']);
console.log(httpRequestsTotal.getValue(['GET', '200'])); // 1
console.log(httpRequestsTotal.getValue(['POST', '201'])); // 3
console.log(httpRequestsTotal.toPrometheus());A gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
new Gauge(name: string, help: string, labels?: string[])// Set to specific value
gauge.set(42);
gauge.set(['cpu', 'core1'], 85.3);
// Increment
gauge.inc(); // increment by 1
gauge.inc(5); // increment by 5
gauge.inc(['memory'], 1024);
// Decrement
gauge.dec(); // decrement by 1
gauge.dec(5); // decrement by 5
gauge.dec(['disk'], 512);
// Get current value
gauge.get();
gauge.get(['cpu', 'core1']);
// Reset to zero
gauge.reset();
// Export to Prometheus format
gauge.toPrometheus();import { Gauge } from 'promlite';
const memoryUsage = new Gauge(
'memory_usage_bytes',
'Memory usage in bytes',
['type']
);
// Set values
memoryUsage.set(['heap'], 1073741824);
memoryUsage.set(['rss'], 2147483648);
// Increment/decrement
memoryUsage.inc(['heap'], 1024);
memoryUsage.dec(['rss'], 512);
console.log(memoryUsage.get(['heap'])); // 1073742848
console.log(memoryUsage.toPrometheus());A histogram samples observations and counts them in configurable buckets. It also provides a sum of all observed values.
new Histogram(name: string, help: string, buckets: number[], labels?: string[])// Observe a value
histogram.observe(0.5);
histogram.observe(['GET', '/api'], 0.243);
// Get metrics
histogram.get(); // { totalCount: number, totalSum: number }
histogram.get(['GET', '/api']);
// Reset all observations
histogram.reset();
// Export to Prometheus format
histogram.toPrometheus();import { Histogram } from 'promlite';
const httpRequestDuration = new Histogram(
'http_request_duration_seconds',
'HTTP request duration in seconds',
[0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10], // buckets
['method', 'route']
);
// Record observations
httpRequestDuration.observe(['GET', '/api/users'], 0.243);
httpRequestDuration.observe(['POST', '/api/users'], 0.891);
httpRequestDuration.observe(['GET', '/api/health'], 0.034);
const stats = httpRequestDuration.get(['GET', '/api/users']);
console.log(stats); // { totalCount: 1, totalSum: 0.243 }
console.log(httpRequestDuration.toPrometheus());The Registry class manages multiple metrics and provides a central endpoint for collecting all metrics.
import { Registry, Counter, Gauge } from 'promlite';
const registry = new Registry();
const counter = new Counter('my_counter', 'A counter');
const gauge = new Gauge('my_gauge', 'A gauge');
// Register metrics
registry.register('my_counter', counter);
registry.register('my_gauge', gauge);
// Get a metric
const retrievedCounter = registry.getMetric('my_counter');
// Get all metric names
const names = registry.getMetricNames();
// Export all metrics
const allMetrics = registry.metrics();
// Reset all metrics
registry.resetAll();
// Clear registry
registry.clear();The library provides a default registry instance:
import { register, Counter } from 'promlite';
const counter = new Counter('requests_total', 'Total requests');
register.register('requests_total', counter);
// Export all metrics from default registry
console.log(register.metrics());import express from 'express';
import { Counter, Histogram, register } from 'promlite';
const app = express();
// Create metrics
const httpRequestsTotal = new Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'route', 'status_code']
);
const httpRequestDuration = new Histogram(
'http_request_duration_seconds',
'HTTP request duration in seconds',
[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5],
['method', 'route']
);
// Register metrics
register.register('http_requests_total', httpRequestsTotal);
register.register('http_request_duration_seconds', httpRequestDuration);
// Middleware to collect metrics
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = (Date.now() - start) / 1000;
const labels = [req.method, req.route?.path || req.path];
httpRequestsTotal.inc([req.method, req.route?.path || req.path, res.statusCode.toString()]);
httpRequestDuration.observe(labels, duration);
});
next();
});
// Metrics endpoint
app.get('/metrics', (req, res) => {
res.set('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');
res.end(register.metrics());
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('Metrics available at http://localhost:3000/metrics');
});Add this job to your prometheus.yml configuration:
scrape_configs:
- job_name: 'node-app'
static_configs:
- targets: ['localhost:3000']
scrape_interval: 15s
metrics_path: '/metrics'The library throws errors for various invalid operations:
import { Counter } from 'promlite';
const counter = new Counter('test', 'Test counter', ['label1']);
// Label count mismatch
counter.inc(['value1', 'value2']); // Error: Label count mismatch
// Cannot decrement counter
counter.inc(['value1'], -1); // Error: Counter cannot be decreased
// Invalid values
counter.inc(['value1'], NaN); // TypeError: Value is not a valid finite number
counter.inc(['value1'], Infinity); // TypeError: Value is not a valid finite number- Metric Naming: Use descriptive names with units (e.g.,
http_request_duration_seconds) - Labels: Keep cardinality low - avoid high-cardinality labels like user IDs
- Histogram Buckets: Choose buckets appropriate for your use case
- Registry: Use the default registry for simplicity, or create custom registries for isolation
- Error Handling: Always handle potential errors from metric operations
This library is written in TypeScript and provides full type definitions:
import { Counter, Gauge, Histogram, Registry } from 'promlite';
import type { CounterType, GaugeType, HistogramType } from 'promlite';
// Type-safe metric creation
const counter: CounterType = new Counter('name', 'help', ['label']);
const gauge: GaugeType = new Gauge('name', 'help');
const histogram: HistogramType = new Histogram('name', 'help', [0.1, 0.5, 1]);# Clone and install dependencies
git clone https://github.com/iaadi4/Promlite.git
cd prom-client
npm install
# Run all checks (type-check, lint, and format)
npm run check
# Fix linting and formatting issues
npm run lint:fix
npm run format
# Run tests
npm testnpm run check- Run all checks (type-check, lint, format-check)npm run type-check- TypeScript type checkingnpm run lint- ESLint code quality checknpm run lint:fix- Fix ESLint issues automaticallynpm run format- Format code with Prettiernpm run format:check- Check if code is properly formattednpm test- Run test suitenpm run build- Build the project
See CONTRIBUTING.md for detailed development setup and contribution guidelines.