An exporter for monitoring file download speeds. When you request the /probe endpoint, the exporter downloads a file from the URL and returns download statistics.
probe_success- download success (1 = success, 0 = error)probe_duration_seconds- download timeprobe_http_status_code- HTTP status code (200, 404, 500...)download_speed_bytes_per_second- download speed in bytes/secdownload_content_length_bytes- file size (from Content-Length)
Note
[WIP] Public Docker image
Create config file:
cp .env.example .envStart the exporter:
docker compose up -dThe exporter will be available at http://localhost:9138
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python exporter.pydocker build -t download-speed-exporter .
docker run -p 9138:9138 download-speed-exporterManual test:
curl "http://localhost:9138/probe?target=http://speedtest.tele2.net/10MB.zip&timeout=30"Example output:
probe_success 1.0
probe_duration_seconds 0.758
probe_http_status_code 200.0
download_speed_bytes_per_second 1.38e+06
download_content_length_bytes 1.048576e+06
The exporter supports configuration via environment variables (see .env.example):
| Variable | Description | Default |
|---|---|---|
EXPORTER_HOST |
Host to bind to | 0.0.0.0 |
EXPORTER_PORT |
Port | 9138 |
LOG_LEVEL |
Log level (DEBUG, INFO, WARNING, ERROR) | INFO |
DEFAULT_TIMEOUT |
Default timeout (seconds) | 10 |
MAX_TIMEOUT |
Maximum timeout (seconds) | 300 |
CHUNK_SIZE |
Download chunk size (bytes) | 8192 |
scrape_configs:
- job_name: 'download-speed'
scrape_interval: 10m
scrape_timeout: 50s
metrics_path: /probe
params:
timeout: ['40']
static_configs:
- targets:
- http://speedtest.tele2.net/10MB.zip
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: <exporter_host>:9138target(required) - URL of the file to downloadtimeout(optional, defaultDEFAULT_TIMEOUT) - download timeout in seconds
Note
The timeout parameter in the request has priority over DEFAULT_TIMEOUT. If not specified, the value from the DEFAULT_TIMEOUT environment variable is used (default 10 seconds).
Important
scrape_timeout in Prometheus must be larger than the exporter's timeout parameter, otherwise Prometheus will cancel the request before the exporter returns metrics.
Incoming traffic is often free, but constantly loading the network is not recommended. Here are traffic usage calculations:
| Interval | Downloads/day | Traffic/day | Traffic/week | Traffic/month |
|---|---|---|---|---|
| 1 minute | 1440 | 43.2 GB | 302.4 GB | 1.3 TB |
| 5 minutes | 288 | 8.64 GB | 60.48 GB | 259.2 GB |
| 10 minutes | 144 | 4.32 GB | 30.24 GB | 129.6 GB |
| 30 minutes | 48 | 1.44 GB | 10.08 GB | 43.2 GB |
| 1 hour | 24 | 0.72 GB | 5.04 GB | 21.6 GB |
# Average download speed over the last hour
avg_over_time(download_speed_bytes_per_second[1h])
# Convert to Mbps
download_speed_bytes_per_second * 8 / 1000000
# Percentage of successful checks
avg_over_time(probe_success[1h]) * 100
# All checks with errors (not 200 OK)
probe_http_status_code{job="download-speed"} != 200
# Number of 404 errors in the last hour
count_over_time((probe_http_status_code == 404)[1h:])
Ready-to-use dashboard is in grafana/download-speed.json.
- Open Grafana → Dashboards → Import
- Upload
grafana/download-speed.jsonfile or copy its content - Select Prometheus datasource in the "Select a Prometheus data source" field
- Click Import
- Set the correct
jobin Grafana Variables and save it as default value. Otherwise graphs may capture metrics from blackbox_exporter due to identical metric names (probe_success,probe_duration_seconds).
- Hetzner (Germany): https://fsn1-speed.hetzner.com/
- Tele2 (EU): http://speedtest.tele2.net/
- OVH (France): https://proof.ovh.net/files/