A complete monitoring and observability solution using Prometheus, Grafana, and Blackbox Exporter to track the uptime, performance, and SSL health of www.maffindi.com and www.maffindi.my.
+-------------------+
| www.maffindi.com |
| www.maffindi.my |
+---------+---------+
|
HTTP/HTTPS probes
|
+---------+---------+
| Blackbox Exporter |
| (prom/blackbox- |
| exporter:latest) |
+---------+---------+
|
metrics (port 9115)
|
+---------+---------+
| Prometheus |
| (prom/prometheus |
| :latest) |
+---------+---------+
|
data source query
|
+---------+---------+
| Grafana |
| (grafana/grafana |
| :latest) |
+-------------------+
| Component | Role |
|---|---|
| Blackbox Exporter | Acts as a probing agent. It sends HTTP/HTTPS requests to each configured target (maffindi.com & maffindi.my) and exposes the results as Prometheus metrics. |
| Prometheus | The heart of the stack. It scrapes the Blackbox Exporter every 15 seconds, stores all metrics in a time-series database, and provides a powerful query language (PromQL) to analyze the data. |
| Grafana | The visualization layer. It connects to Prometheus as a data source and renders dashboards with charts, graphs, and status panels for real-time monitoring. |
- Metric:
probe_success - Values:
1= site is up and responding,0= site is down - Granularity: Checked every 15 seconds
- Metric:
probe_http_duration_seconds - Phases measured:
resolve— DNS lookup timeconnect— TCP connection timetls— TLS handshake timetransfer— Time to receive response
- Metric:
probe_ssl_earliest_cert_expiry - What it tracks: When the SSL certificate expires (Unix timestamp)
- Alert use case: Warn when cert expires within 30 days
- Metric:
probe_http_status_code - Expected:
200(OK) - Monitors: Any unexpected codes (404, 500, 502, 301 redirects, etc.)
| Service | URL | Access | Credentials |
|---|---|---|---|
| Prometheus | http://localhost:9090 | Open (no auth) | — |
| Grafana | http://localhost:3000 | Login required | Username: admin, Password: admin |
| Blackbox Exporter | Internal only (Docker network) | Not exposed externally | — |
# Clone the repository
git clone git@github.com:fendi-321/prometheus-lab.git
cd prometheus-lab
# Start all services
docker compose up -d
# Verify everything is running
docker compose ps- Login at http://localhost:3000 (
admin/admin) - Click Dashboards → New → Import
- Enter ID:
7587(Blackbox Exporter Dashboard) - Select Prometheus as the data source
- Click Import
| Query | Purpose |
|---|---|
probe_success{instance="https://www.maffindi.com"} |
Uptime for maffindi.com |
probe_success{instance="https://www.maffindi.my"} |
Uptime for maffindi.my |
probe_http_duration_seconds{phase="connect"} |
TCP connection latency |
probe_http_duration_seconds{phase="tls"} |
TLS handshake latency |
(probe_ssl_earliest_cert_expiry - time()) / 86400 |
Days until SSL cert expires |
probe_http_status_code |
HTTP status codes returned |
prometheus-lab/
├── docker-compose.yml # Orchestrates all services
├── prometheus/
│ └── prometheus.yml # Prometheus scrape configuration
├── blackbox-exporter/
│ └── blackbox.yml # Blackbox probe module definitions
├── grafana/
│ ├── datasources/
│ │ └── datasource.yml # Auto-provisions Prometheus data source
│ └── dashboards/
│ └── dashboards.yml # Dashboard provisioning config
├── .gitignore
└── README.md
Edit prometheus/prometheus.yml and add targets under the blackbox-http job:
static_configs:
- targets:
- https://www.maffindi.com
- https://www.maffindi.my
- https://your-new-site.comThen restart Prometheus:
docker compose restart prometheusEdit the scrape_interval in prometheus/prometheus.yml (default: 15s).
# View container status
docker compose ps
# View live logs
docker compose logs -f
# Stop all services
docker compose down
# Restart a specific service
docker compose restart prometheus
docker compose restart grafana
docker compose restart blackbox-exporterMuhamad Affindi