Observability Stack
Prometheus Metrics
import { Counter, Histogram, register } from 'prom-client';
const httpRequests = new Counter({ name: 'http_requests_total', help: 'Total HTTP requests', labelNames: ['method', 'path', 'status'] });
const httpDuration = new Histogram({ name: 'http_duration_seconds', help: 'Request duration', labelNames: ['method', 'path'] });
app.use((req, res, next) => {
const end = httpDuration.startTimer({ method: req.method, path: req.path });
res.on('finish', () => {
httpRequests.inc({ method: req.method, path: req.path, status: res.statusCode });
end();
});
next();
});
app.get('/metrics', async (req, res) => { res.set('Content-Type', register.contentType); res.send(await register.metrics()); });
Docker Compose Stack
Grafana (dashboards) + Prometheus (metrics) + Loki (logs) + Tempo (traces)
Key Metrics: request rate, error rate, latency (p50/p95/p99), saturation
1---2name: observability-stack3description: Observability Stack4---5# Observability Stack67## Prometheus Metrics8```typescript9import { Counter, Histogram, register } from 'prom-client';10const httpRequests = new Counter({ name: 'http_requests_total', help: 'Total HTTP requests', labelNames: ['method', 'path', 'status'] });11const httpDuration = new Histogram({ name: 'http_duration_seconds', help: 'Request duration', labelNames: ['method', 'path'] });1213app.use((req, res, next) => {14 const end = httpDuration.startTimer({ method: req.method, path: req.path });15 res.on('finish', () => {16 httpRequests.inc({ method: req.method, path: req.path, status: res.statusCode });17 end();18 });19 next();20});21app.get('/metrics', async (req, res) => { res.set('Content-Type', register.contentType); res.send(await register.metrics()); });22```2324## Docker Compose Stack25Grafana (dashboards) + Prometheus (metrics) + Loki (logs) + Tempo (traces)2627## Key Metrics: request rate, error rate, latency (p50/p95/p99), saturation