A Node.js Express application with integrated monitoring using Prometheus for metrics collection and Grafana for visualization.
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Express │─────▶│ Prometheus │─────▶│ Grafana │
│ App │ │ (Scraper) │ │ (Dashboard) │
│ Port 3000 │ │ Port 9090 │ │ Port 3001 │
└─────────────┘ └──────────────┘ └─────────────┘
│ │ │
│ │ │
└───────────────────────┴──────────────────────┘
Metrics Flow
- The Express app uses
prom-clientlibrary to collect and expose metrics - Metrics Collection:
- HTTP request duration (latency) is tracked using a Histogram metric
- Default Node.js metrics (CPU, memory, event loop, etc.) are automatically collected
- Metrics are labeled by HTTP method, route, and status code
- Metrics Endpoint: The app exposes metrics at
/metricsendpoint in Prometheus format - Middleware: A custom middleware tracks every HTTP request and records its duration
- Prometheus acts as a time-series database and metrics collector
- Scraping: Prometheus periodically scrapes the
/metricsendpoint from the Express app - Configuration:
- Scrape interval: Every 5 seconds (configured in
prometheus.yml) - Target:
app:3000/metrics
- Scrape interval: Every 5 seconds (configured in
- Storage: Prometheus stores all collected metrics in its time-series database
- Query Interface: Prometheus provides a query language (PromQL) to query metrics
- Grafana connects to Prometheus as a data source
- Data Source: Configured to pull metrics from Prometheus
- Dashboards: Creates visual dashboards with graphs, charts, and alerts
- Real-time Monitoring: Displays real-time metrics and historical trends
- Visualization: Converts raw metrics data into meaningful visual representations
- User Request → Express app receives HTTP request
- Middleware Tracking → Request duration timer starts
- Response → Express sends response, timer stops and records metric
- Metrics Exposure → Metrics available at
http://app:3000/metrics - Prometheus Scrape → Prometheus fetches metrics every 5 seconds
- Storage → Prometheus stores metrics in time-series database
- Grafana Query → Grafana queries Prometheus for metrics data
- Visualization → Grafana displays metrics in dashboards
- Express App (
app): Node.js application on port 3000 - Redis (
redis): Redis server on port 6379 - Prometheus (
prometheus): Metrics server on port 9090 - Grafana (
grafana): Dashboard on port 3001
- Docker and Docker Compose installed
-
Start all services:
docker-compose up -d
-
Access the services:
- Express App: http://localhost:3000
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3001 (default login: admin/admin)
- Redis: localhost:6379
-
View metrics:
- Express metrics endpoint: http://localhost:3000/metrics
- Prometheus query interface: http://localhost:9090
- Login to Grafana at http://localhost:3001
- Add Prometheus as a data source:
- URL:
http://prometheus:9090 - Access: Server (default)
- URL:
- Create dashboards to visualize your metrics
http_request_duration_seconds: HTTP request latency histogram- Default Node.js metrics (CPU, memory, event loop, etc.)
.
├── app/
│ ├── db/
│ │ └── init.redis.js # Redis client initialization
│ ├── metrics.js # Prometheus metrics configuration
│ ├── server.js # Express application
│ ├── Dockerfile # App container definition
│ └── package.json # Node.js dependencies
├── docker-compose.yml # Service orchestration
├── prometheus.yml # Prometheus configuration
└── README.md # This file
- Scrapes Express app metrics every 5 seconds
- Target endpoint:
app:3000/metrics
REDIS_URL: Redis connection URL (default:redis://redis:6379)
docker-compose downTo remove volumes (including Redis data):
docker-compose down -v