Prometheus exporter for Duplicacy backup metrics -- real-time progress, speed, and post-run summaries
Project description
Prometheus exporter for Duplicacy backup metrics -- real-time progress, speed, and post-run summaries for your Grafana dashboards.
Overview
duplicacy-exporter bridges Duplicacy backups and Prometheus, giving you full observability over backup operations. It works with both Duplicacy CLI (via log tailing) and Duplicacy Web UI (via webhook), exposing metrics that Prometheus scrapes and Grafana visualizes.
Key capabilities
- Real-time metrics -- backup speed (bytes/sec), progress (0-100%), chunks uploaded/skipped, updated per chunk
- Post-run summaries -- duration, file counts, bytes uploaded, exit codes, revision numbers
- Prune tracking -- monitors prune operations with completion timestamps
- Two collection modes --
log_tailfor CLI users,webhookfor Web UI users - Smart label resolution -- automatic snapshot ID, storage target, and machine name detection from logs
- Storage host mapping -- translates IPs and Tailscale FQDNs into human-readable names
- Lightweight -- single Python file, one dependency (
prometheus_client), Alpine image (~30 MB)
Architecture
+---------------------+ +----------------------+ +------------+
| | logs | | scrape | |
| Duplicacy CLI +-------->+ duplicacy-exporter +<--------+ Prometheus |
| (Docker / file) | tail | | :9750 | |
+---------------------+ +----------+-----------+ +------+-----+
| |
+---------------------+ POST | | |
| Duplicacy Web UI +-------->+ /webhook endpoint | +------v-----+
| (report_url) | | | | Grafana |
+---------------------+ +----------------------+ +------------+
Log tail mode connects to the Docker Engine API over a Unix socket (or tails a log file) and parses Duplicacy output line-by-line. It extracts chunk-level progress in real time and summary statistics at completion.
Webhook mode receives JSON payloads from Duplicacy Web UI's report_url setting, extracting the same summary metrics without needing Docker socket access.
Quick Start
Docker Compose -- Log Tail Mode (recommended for CLI)
Deploy alongside your Duplicacy CLI container:
services:
duplicacy-exporter:
image: drumsergio/duplicacy-exporter:0.3.4
container_name: duplicacy-exporter
restart: unless-stopped
environment:
- MODE=log_tail
- DOCKER_CONTAINER_NAME=duplicacy-cli-cron
- LISTEN_PORT=9750
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "9750:9750"
Docker Compose -- Webhook Mode (for Web UI)
services:
duplicacy-exporter:
image: drumsergio/duplicacy-exporter:0.3.4
container_name: duplicacy-exporter
restart: unless-stopped
environment:
- MODE=webhook
- LISTEN_PORT=9750
ports:
- "9750:9750"
Then set report_url in Duplicacy Web UI to: http://duplicacy-exporter:9750/webhook
Docker Compose -- Log File Mode
If you write Duplicacy logs to a file instead of using Docker:
services:
duplicacy-exporter:
image: drumsergio/duplicacy-exporter:0.3.4
container_name: duplicacy-exporter
restart: unless-stopped
environment:
- MODE=log_tail
- LOG_FILE=/logs/duplicacy.log
- LISTEN_PORT=9750
volumes:
- /path/to/duplicacy/logs:/logs:ro
ports:
- "9750:9750"
Configuration
All configuration is done through environment variables:
| Variable | Default | Description |
|---|---|---|
MODE |
log_tail |
Collection mode: log_tail or webhook |
DOCKER_CONTAINER_NAME |
duplicacy-cli-cron |
Container name to tail logs from (log_tail mode) |
LOG_FILE |
(empty) | Path to log file; alternative to Docker socket (log_tail mode) |
LISTEN_PORT |
9750 |
Port for the metrics and webhook HTTP server |
WEBHOOK_PATH |
/webhook |
Path for the webhook POST endpoint (webhook mode) |
MACHINE_NAME |
(empty) | Machine name label; auto-detected from logs if not set |
TAILSCALE_DOMAIN |
mango-alpha.ts.net |
Tailscale domain suffix to strip from storage URLs |
STORAGE_HOST_MAP |
(empty) | JSON object mapping hostname/IP to display name |
REPLAY_HOURS |
25 |
Hours of Docker log history to replay on startup |
LOG_LEVEL |
INFO |
Logging verbosity: DEBUG, INFO, WARNING, ERROR |
Storage host mapping example
Map raw IPs or hostnames to friendly names:
STORAGE_HOST_MAP='{"192.168.10.100":"watchtower","192.168.20.5":"geiserct"}'
Metrics
All backup metrics carry labels: snapshot_id, storage_target, machine.
All prune metrics carry labels: storage_target, machine.
Real-time (updated per chunk during backup)
| Metric | Type | Description |
|---|---|---|
duplicacy_backup_running |
Gauge | 1 if backup is in progress, 0 otherwise |
duplicacy_backup_speed_bytes_per_second |
Gauge | Current backup speed |
duplicacy_backup_progress_ratio |
Gauge | Progress from 0.0 to 1.0 |
duplicacy_backup_chunks_uploaded |
Gauge | Chunks uploaded in current run |
duplicacy_backup_chunks_skipped |
Gauge | Chunks skipped in current run |
Post-run summary
| Metric | Type | Description |
|---|---|---|
duplicacy_backup_last_success_timestamp_seconds |
Gauge | Unix timestamp of last successful backup |
duplicacy_backup_last_duration_seconds |
Gauge | Duration of last backup in seconds |
duplicacy_backup_last_files_total |
Gauge | Total files in last backup |
duplicacy_backup_last_files_new |
Gauge | New files in last backup |
duplicacy_backup_last_bytes_uploaded |
Gauge | Bytes uploaded in last backup |
duplicacy_backup_last_bytes_new |
Gauge | New bytes in last backup |
duplicacy_backup_last_chunks_new |
Gauge | New chunks in last backup |
duplicacy_backup_last_exit_code |
Gauge | Exit code: 0 = success, 1 = failure |
duplicacy_backup_last_revision |
Gauge | Revision number of last backup |
duplicacy_backup_bytes_uploaded_total |
Counter | Cumulative bytes uploaded across all runs |
Prune
| Metric | Type | Description |
|---|---|---|
duplicacy_prune_running |
Gauge | 1 if prune is in progress |
duplicacy_prune_last_success_timestamp_seconds |
Gauge | Unix timestamp of last successful prune |
Endpoints
| Path | Method | Description |
|---|---|---|
/metrics |
GET | Prometheus metrics endpoint |
/webhook |
POST | Duplicacy Web UI report endpoint |
/health |
GET | Health check (returns 200 OK) |
Prometheus Configuration
Add the exporter as a scrape target:
scrape_configs:
- job_name: "duplicacy"
static_configs:
- targets: ["duplicacy-exporter:9750"]
labels:
instance: "my-server"
Example alerting rule
groups:
- name: duplicacy
rules:
- alert: DuplicacyBackupFailed
expr: duplicacy_backup_last_exit_code != 0
for: 5m
labels:
severity: warning
annotations:
summary: "Duplicacy backup failed for {{ $labels.snapshot_id }}"
- alert: DuplicacyBackupStale
expr: time() - duplicacy_backup_last_success_timestamp_seconds > 86400
for: 1h
labels:
severity: critical
annotations:
summary: "No successful Duplicacy backup in 24h for {{ $labels.snapshot_id }}"
Grafana Dashboard
A ready-to-import dashboard is included in dashboard.json and published on Grafana.com (#25089).
Import it in Grafana via Dashboards → Import → Upload JSON file or use the dashboard ID 25089.
Troubleshooting
Exporter starts but no metrics appear
- Log tail mode: Verify the Docker socket is mounted (
/var/run/docker.sock:/var/run/docker.sock:ro) and theDOCKER_CONTAINER_NAMEmatches your Duplicacy container exactly. - Log file mode: Confirm the log file path is correct and the volume mount provides read access.
- Webhook mode: Ensure
report_urlin Duplicacy Web UI points tohttp://<exporter-host>:9750/webhook. The exporter must be reachable from the Web UI container.
Metrics show but labels are wrong or missing
- Set
LOG_LEVEL=DEBUGto see how each log line is parsed and which labels are resolved. - If storage targets show as raw IPs, use
STORAGE_HOST_MAPto map them to friendly names. - If machine name is missing, set
MACHINE_NAMEexplicitly.
Docker socket permission denied
The exporter process runs as root inside the container by default. If you run it as a non-root user, ensure the user has access to the Docker socket (typically group docker, GID 999 or similar).
Webhook returns 404
Verify the WEBHOOK_PATH environment variable matches the path you configured in Duplicacy Web UI. The default is /webhook.
Related Projects
duplicacy-container-- Runtime image and Helm chart for the Kubernetes Duplicacy stackduplicacy-cli-cron-- Scripts, wrappers, and backup recipes for Duplicacy CLI- Duplicacy -- Lock-free deduplication cloud backup tool
- Prometheus -- Monitoring and alerting toolkit
- Grafana -- Observability and visualization platform
- awesome-prometheus -- Curated list of Prometheus resources
- prometheus_client (Python) -- Official Prometheus client library for Python
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duplicacy_exporter-0.3.4.tar.gz.
File metadata
- Download URL: duplicacy_exporter-0.3.4.tar.gz
- Upload date:
- Size: 24.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c09b1d9aa15a7481bac3e7894de995491d7d5abf1f0cc8750d50d795921292c
|
|
| MD5 |
1eea21fd0fef1a6864dec99dc3b9ec32
|
|
| BLAKE2b-256 |
851f7ca5843f0fa8882b27846e4b081a893a783cfe0daadb2d9dea81ae03af5d
|
File details
Details for the file duplicacy_exporter-0.3.4-py3-none-any.whl.
File metadata
- Download URL: duplicacy_exporter-0.3.4-py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24acaa0f09386d4dc8237d288ed80d5499e4373f0f93b234f66da3cb17c050f9
|
|
| MD5 |
e7682b948f5f5f5fb546ce5d21bc14eb
|
|
| BLAKE2b-256 |
769334d973b16bb5c744b843a0d77c3576e71a88655dcdbcede29bdc4ce09ffd
|