39 Commits
1.0.2 ... 1.1.2

Author SHA1 Message Date
Esteban Sánchez
0ff6a56f18 Version 1.1.2 2021-07-03 23:33:39 +02:00
Esteban Sánchez
2d968bc8e8 Added attrdict as requirement 2021-07-03 20:59:50 +02:00
Esteban Sánchez
8ab307a630 Version 1.1.1 2021-07-02 16:18:11 +02:00
Esteban Sánchez
de00864f11 Small fixes 2021-07-02 16:07:53 +02:00
Esteban Sanchez
03d332979b Merge pull request #4 from angristan/update-api-dep
Update qbittorrent-api to 2021.3.18
2021-07-02 16:03:54 +02:00
Esteban Sanchez
1f6e8aa380 Merge pull request #6 from ndragon798/patch-1
Added info for prometheus.yml
2021-07-02 16:03:39 +02:00
Nathan Easton
ef00d90e2f Added info for prometheus.yml
As requested by #5
2021-07-01 14:05:50 -04:00
Stanislas
7f783f0b0a Update qbittorrent-api to 2021.3.18
To include 72687ca614 
in order to fix https://github.com/esanchezm/prometheus-qbittorrent-exporter/issues/3
2021-03-14 10:45:08 +01:00
Esteban Sánchez
345888ef68 Fixed category variable 2020-10-26 18:23:09 +01:00
Esteban Sánchez
0e4c4a97ea Added screenshot 2020-10-26 18:15:22 +01:00
Esteban Sánchez
d144f412ca Added screenshot and instructions 2020-10-26 18:02:40 +01:00
Esteban Sanchez
9002a709b7 Added grafana dashboard 2020-10-26 17:51:39 +01:00
Esteban Sánchez
b91bff0f0c Fixed output reference 2020-10-24 11:36:24 +02:00
Esteban Sánchez
ed44d88c5b Debug 2020-10-24 11:33:14 +02:00
Esteban Sánchez
8f0a0381d3 Get tag when it's a version release 2020-10-24 11:30:51 +02:00
Esteban Sanchez
b3e5e69f1f Get branch name to push 2020-10-24 10:52:22 +02:00
Esteban Sánchez
ef12d46431 Create docker image on release 2020-10-24 10:40:20 +02:00
Esteban Sánchez
9a19f46b7e Release 1.1.0 2020-10-24 10:39:49 +02:00
Esteban Sánchez
a53c7ae08b Install from src and not pip package 2020-10-24 10:39:40 +02:00
Esteban Sanchez
17ebcb0834 Setup buildx 2020-10-24 10:30:21 +02:00
Esteban Sanchez
7016e3de2b Set tags from a list 2020-10-24 10:13:39 +02:00
Esteban Sanchez
af51fd5b67 Set labels 2020-10-23 22:07:01 +02:00
Esteban Sanchez
82151b1d82 Setting tag 2020-10-23 22:04:55 +02:00
Esteban Sanchez
b6e3131929 Push to docker hub 2020-10-23 22:04:10 +02:00
Esteban Sanchez
688fcc54cb Testing 2020-10-23 22:02:24 +02:00
Esteban Sanchez
bc79a0dd52 Create pythonpublish.yml 2020-10-23 21:56:46 +02:00
Esteban Sanchez
af732087e8 Fixed version 2020-10-23 21:51:55 +02:00
Esteban Sanchez
15130f1c95 Added action to push to dockerhub 2020-10-23 21:49:29 +02:00
Esteban Sanchez
53dc38f796 Merge pull request #1 from Gabisonfire/master
Added the ability to include uncategorized torrents.
2020-10-22 23:11:35 +02:00
Gab
3bfc3f0673 Removed unused config 2020-10-21 18:58:17 -04:00
Esteban Sánchez
eee65ec84e Allow setting a metrics prefix 2020-10-21 08:05:51 +02:00
Gab
b4aefff06d Changed readme 2020-10-20 11:57:33 -04:00
Gab
baf14d495c Removed now useless logging message 2020-10-20 11:46:50 -04:00
Gab
003297ecfd Removed uncategorized from config 2020-10-20 11:45:48 -04:00
Gab
2497249b8c Fixed indentation 2020-10-20 02:10:39 -04:00
Gab
9e9f4a9ce4 Added scraping for uncategorized torrents 2020-10-20 02:10:04 -04:00
Gab
40d9bb964e Added scraping for uncategorized torrents 2020-10-20 02:05:17 -04:00
Esteban Sánchez
0b3fb04728 Removed unneded code and return earlier 2020-10-01 10:14:56 +02:00
Esteban Sánchez
13a52c40f2 New version 2020-09-29 13:47:32 +02:00
9 changed files with 1050 additions and 29 deletions

40
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Docker
on:
push:
branches: [ master ]
release:
types: [ created ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Extract branch name
shell: bash
run: |
tag=${GITHUB_REF#refs/tags/}
tag=${tag#refs/heads/}
if echo $tag | grep -q -E "[0-9]+\.[0-9]+\.[0-9]+"; then
tag="v$tag"
fi
echo "##[set-output name=tag;]$tag"
id: extract_branch
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push docker
uses: docker/build-push-action@v2
with:
push: true
tags: esanchezm/prometheus-qbittorrent-exporter:latest,esanchezm/prometheus-qbittorrent-exporter:${{ steps.extract_branch.outputs.tag }}

26
.github/workflows/pythonpublish.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Upload Python Package
on:
release:
types: [created]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.6'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist
twine upload dist/*

View File

@@ -5,7 +5,9 @@ RUN apk add --update --no-cache \
python3
# Install package
RUN pip3 install prometheus-qbittorrent-exporter==1.0.1
WORKDIR /code
COPY . .
RUN pip3 install .
ENV QBITTORRENT_HOST=""
ENV QBITTORRENT_PORT=""

View File

@@ -22,7 +22,12 @@ Another option is run it in a docker container.
```
docker run -e QBITTORRENT_PORT=8080 -e QBITTORRENT_HOST=myserver.local -p 8000:8000 esanchezm/prometheus-qbittorrent-exporter
```
Add this to your prometheus.yml
```
- job_name: "qbittorrent_exporter"
static_configs:
- targets: ['yourqbittorrentexporter:port']
```
The application reads configuration using environment variables:
| Environment variable | Default | Description |
@@ -33,22 +38,29 @@ The application reads configuration using environment variables:
| `QBITTORRENT_PASS` | `""` | qbittorrent password |
| `EXPORTER_PORT` | `8000` | Exporter listening port |
| `EXPORTER_LOG_LEVEL` | `INFO` | Log level. One of: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |
| `METRICS_PREFIX` | `qbittorrent` | Prefix to add to all the metrics |
## Metrics
These are the metrics this program exports:
These are the metrics this program exports, assuming the `METRICS_PREFIX` is `qbittorrent`:
| Metric name | Type | Description |
| --------------------------------------------------- | -------- | ---------------- |
| `qbittorrent_up` | gauge | Whether if the qBittorrent server is answering requests from this exporter. A `version` label with the server version is added |
| `connected` | gauge | Whether if the qBittorrent server is connected to the Bittorrent network. |
| `firewalled` | gauge | Whether if the qBittorrent server is connected to the Bittorrent network but is behind a firewall. |
| `dht_nodes` | gauge | Number of DHT nodes connected to |
| `dl_info_data` | counter | Data downloaded since the server started, in bytes |
| `up_info_data` | counter | Data uploaded since the server started, in bytes |
| `torrents_count` | gauge | Number of torrents for each `category` and `status`. Example: `torrents_count{category="movies",status="downloading"}`|
| `qbittorrent_connected` | gauge | Whether if the qBittorrent server is connected to the Bittorrent network. |
| `qbittorrent_firewalled` | gauge | Whether if the qBittorrent server is connected to the Bittorrent network but is behind a firewall. |
| `qbittorrent_dht_nodes` | gauge | Number of DHT nodes connected to |
| `qbittorrent_dl_info_data` | counter | Data downloaded since the server started, in bytes |
| `qbittorrent_up_info_data` | counter | Data uploaded since the server started, in bytes |
| `qbittorrent_torrents_count` | gauge | Number of torrents for each `category` and `status`. Example: `qbittorrent_torrents_count{category="movies",status="downloading"}`|
## Screenshot
![](./grafana/screenshot.png)
[More info](./grafana/README.md)
## License

9
grafana/README.md Normal file
View File

@@ -0,0 +1,9 @@
# Grafana dashboard
## Import
To import the dashboard into your grafana, download the [dashboard.json](https://raw.githubusercontent.com/esanchezm/prometheus-qbittorrent-exporter/master/grafana/dashboard.json) file and import it into your server. Select your prometheus instance and that should be all.
## Screenshot
![](./screenshot.png)

927
grafana/dashboard.json Normal file
View File

@@ -0,0 +1,927 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "Prometheus",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__requires": [
{
"type": "panel",
"id": "gauge",
"name": "Gauge",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "7.2.2"
},
{
"type": "panel",
"id": "grafana-piechart-panel",
"name": "Pie Chart",
"version": "1.6.1"
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "stat",
"name": "Stat",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1603732792335,
"links": [],
"panels": [
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [
{
"from": "",
"id": 0,
"text": "Online",
"to": "",
"type": 1,
"value": "1"
},
{
"from": "",
"id": 1,
"text": "Offline",
"to": "",
"type": 1,
"value": "0"
},
{
"from": "",
"id": 2,
"text": "Unknown",
"to": "",
"type": 1,
"value": "null"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "yellow",
"value": null
},
{
"color": "semi-dark-red",
"value": 0
},
{
"color": "semi-dark-green",
"value": 1
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "qbittorrent_up",
"format": "time_series",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Qbittorrent Status",
"transformations": [],
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [
{
"from": "",
"id": 0,
"text": "Connected",
"to": "",
"type": 1,
"value": "1"
},
{
"from": "",
"id": 1,
"text": "Disconnected",
"to": "",
"type": 1,
"value": "0"
},
{
"from": "",
"id": 2,
"text": "Firewalled",
"to": "",
"type": 1,
"value": "-1"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "yellow",
"value": null
},
{
"color": "dark-red",
"value": 0
},
{
"color": "semi-dark-green",
"value": 1
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 3,
"y": 0
},
"id": 3,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "qbittorrent_connected - qbittorrent_firewalled",
"format": "time_series",
"instant": true,
"interval": "",
"legendFormat": "Status",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Bittorrent network",
"transformations": [],
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [
{
"from": "",
"id": 1,
"text": "No DHT",
"to": "",
"type": 1,
"value": "0"
},
{
"from": "",
"id": 2,
"text": "Firewalled",
"to": "",
"type": 1,
"value": "-1"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "yellow",
"value": null
},
{
"color": "dark-red",
"value": 0
},
{
"color": "semi-dark-green",
"value": 100
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 6,
"y": 0
},
"id": 13,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "qbittorrent_dht_nodes",
"instant": true,
"interval": "",
"legendFormat": "DHT nodes",
"refId": "B"
}
],
"timeFrom": null,
"timeShift": null,
"title": "DHT nodes",
"transformations": [],
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "decbytes"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 9,
"y": 0
},
"id": 5,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "increase(qbittorrent_dl_info_data_total[100y])",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Data downloaded",
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "decbytes"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 12,
"y": 0
},
"id": 6,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "increase(qbittorrent_up_info_data_total[100y])",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Data uploaded",
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 15,
"y": 0
},
"id": 7,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "increase(qbittorrent_up_info_data_total[100y]) / increase(qbittorrent_dl_info_data_total[100y])",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Accumulated ratio",
"type": "stat"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"decimals": 1,
"mappings": [],
"max": 48000000,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "dark-red",
"value": null
},
{
"color": "dark-green",
"value": 8000000
}
]
},
"unit": "binBps"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 18,
"y": 0
},
"id": 16,
"options": {
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "rate(qbittorrent_dl_info_data_total[1m])",
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Download speed",
"type": "gauge"
},
{
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {},
"decimals": 1,
"mappings": [
{
"from": "",
"id": 1,
"text": "",
"to": "",
"type": 1
}
],
"max": 18000000,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "dark-red",
"value": null
},
{
"color": "dark-green",
"value": 4000000
}
]
},
"unit": "binBps"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 3,
"x": 21,
"y": 0
},
"id": 17,
"options": {
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "7.2.2",
"targets": [
{
"expr": "rate(qbittorrent_up_info_data_total[1m])",
"hide": false,
"instant": false,
"interval": "",
"legendFormat": "",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Upload speed",
"type": "gauge"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 10,
"w": 24,
"x": 0,
"y": 4
},
"hiddenSeries": false,
"id": 15,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "rate(qbittorrent_dl_info_data_total[1m])",
"interval": "",
"legendFormat": "Download",
"refId": "A"
},
{
"expr": "rate(qbittorrent_up_info_data_total[1m])",
"interval": "",
"legendFormat": "Upload",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Transfer ratio",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "binBps",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "binBps",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": true,
"cacheTimeout": null,
"dashLength": 10,
"dashes": false,
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 10,
"w": 14,
"x": 0,
"y": 14
},
"hiddenSeries": false,
"id": 11,
"interval": null,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": false,
"linewidth": 0,
"links": [],
"nullPointMode": "null as zero",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": true,
"steppedLine": true,
"targets": [
{
"expr": "sum(qbittorrent_torrents_count{category=~\"${categories}\", status!=\"complete\"}) by (status)",
"interval": "",
"legendFormat": "{{status}}",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Torrents by status",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"breakPoint": "50%",
"cacheTimeout": null,
"combine": {
"label": "Others",
"threshold": 0
},
"datasource": "${DS_PROMETHEUS}",
"fieldConfig": {
"defaults": {
"custom": {
"align": null,
"filterable": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
}
},
"overrides": []
},
"fontSize": "80%",
"format": "short",
"gridPos": {
"h": 10,
"w": 10,
"x": 14,
"y": 14
},
"id": 12,
"interval": null,
"legend": {
"percentage": true,
"show": true,
"sideWidth": null,
"values": true
},
"legendType": "Right side",
"links": [],
"nullPointMode": "connected",
"pieType": "donut",
"pluginVersion": "7.2.0",
"strokeWidth": 1,
"targets": [
{
"expr": "sum(qbittorrent_torrents_count{category=~\"${categories}\",status!=\"complete\"}) by (category)",
"interval": "",
"legendFormat": "{{category}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Torrents by categories",
"type": "grafana-piechart-panel",
"valueName": "current"
}
],
"refresh": "30s",
"schemaVersion": 26,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"allValue": ".*",
"current": {},
"datasource": "${DS_PROMETHEUS}",
"definition": "label_values(qbittorrent_torrents_count, category)",
"hide": 0,
"includeAll": true,
"label": "Categories",
"multi": true,
"name": "categories",
"options": [],
"query": "label_values(qbittorrent_torrents_count, category)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Qbittorrent",
"uid": "eKyTETFMk",
"version": 40
}

BIN
grafana/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

View File

@@ -3,7 +3,9 @@ import os
import sys
import signal
import faulthandler
from attrdict import AttrDict
from qbittorrentapi import Client, TorrentStates
from qbittorrentapi.exceptions import APIConnectionError
from prometheus_client import start_http_server
from prometheus_client.core import GaugeMetricFamily, CounterMetricFamily, REGISTRY
import logging
@@ -40,6 +42,7 @@ class QbittorrentMetricsCollector():
self.torrents = self.client.torrents.info()
except Exception as e:
logger.error(f"Couldn't get server info: {e}")
return None
metrics = self.get_qbittorrent_metrics()
@@ -65,46 +68,49 @@ class QbittorrentMetricsCollector():
return metrics
def get_qbittorrent_status_metrics(self):
response = {}
version = ""
# Fetch data from API
try:
response = self.client.transfer.info
version = self.client.app.version
self.torrents = self.client.torrents.info()
except Exception as e:
logger.error(f"Couldn't get server info: {e}")
response = None
version = ""
except APIConnectionError as e:
logger.error(f"Couldn't get server info: {e.error_message}")
except Exception:
logger.error(f"Couldn't get server info")
return [
{
"name": "qbittorrent_up",
"value": response is not None,
"name": f"{self.config['metrics_prefix']}_up",
"value": bool(response),
"labels": {"version": version},
"help": "Whether if server is alive or not",
},
{
"name": "connected",
"name": f"{self.config['metrics_prefix']}_connected",
"value": response.get("connection_status", "") == "connected",
"help": "Whether if server is connected or not",
},
{
"name": "firewalled",
"name": f"{self.config['metrics_prefix']}_firewalled",
"value": response.get("connection_status", "") == "firewalled",
"help": "Whether if server is under a firewall or not",
},
{
"name": "dht_nodes",
"name": f"{self.config['metrics_prefix']}_dht_nodes",
"value": response.get("dht_nodes", 0),
"help": "DHT nodes connected to",
},
{
"name": "dl_info_data",
"name": f"{self.config['metrics_prefix']}_dl_info_data",
"value": response.get("dl_info_data", 0),
"help": "Data downloaded this session (bytes)",
"type": "counter"
},
{
"name": "up_info_data",
"name": f"{self.config['metrics_prefix']}_up_info_data",
"value": response.get("up_info_data", 0),
"help": "Data uploaded this session (bytes)",
"type": "counter"
@@ -116,17 +122,15 @@ class QbittorrentMetricsCollector():
categories = self.client.torrent_categories.categories
except Exception as e:
logger.error(f"Couldn't fetch categories: {e}")
categories = None
if not categories:
return []
if not self.torrents:
return []
metrics = []
categories.Uncategorized = AttrDict({'name': 'Uncategorized', 'savePath': ''})
for category in categories:
category_torrents = [t for t in self.torrents if t['category'] == category]
category_torrents = [t for t in self.torrents if t['category'] == category or (category == "Uncategorized" and t['category'] == "")]
for status in self.TORRENT_STATUSES:
status_prop = f"is_{status}"
@@ -134,7 +138,7 @@ class QbittorrentMetricsCollector():
t for t in category_torrents if getattr(TorrentStates, status_prop).fget(TorrentStates(t['state']))
]
metrics.append({
"name": "torrents_count",
"name": f"{self.config['metrics_prefix']}_torrents_count",
"value": len(status_torrents),
"labels": {
"status": status,
@@ -169,7 +173,8 @@ def main():
"username": os.environ.get("QBITTORRENT_USER", ""),
"password": os.environ.get("QBITTORRENT_PASS", ""),
"exporter_port": int(os.environ.get("EXPORTER_PORT", "8000")),
"log_level": os.environ.get("EXPORTER_LOG_LEVEL", "INFO")
"log_level": os.environ.get("EXPORTER_LOG_LEVEL", "INFO"),
"metrics_prefix": os.environ.get("METRICS_PREFIX", "qbittorrent"),
}
# Register signal handler

View File

@@ -6,18 +6,18 @@ with open("README.md", "r") as fh:
setup(
name='prometheus-qbittorrent-exporter',
packages=['qbittorrent_exporter'],
version='1.0.1',
version='1.1.2',
long_description=long_description,
long_description_content_type="text/markdown",
description='Prometheus exporter for qbittorrent',
author='Esteban Sanchez',
author_email='esteban.sanchez@gmail.com',
url='https://github.com/esanchezm/prometheus-qbittorrent-exporter',
download_url='https://github.com/esanchezm/prometheus-qbittorrent-exporter/archive/1.0.1.tar.gz',
download_url='https://github.com/esanchezm/prometheus-qbittorrent-exporter/archive/1.1.0.tar.gz',
keywords=['prometheus', 'qbittorrent'],
classifiers=[],
python_requires='>=3',
install_requires=['qbittorrent-api==2020.9.9', 'prometheus_client==0.8.0', 'python-json-logger==0.1.5'],
install_requires=['attrdict==2.0.1', 'qbittorrent-api==2021.3.18', 'prometheus_client==0.8.0', 'python-json-logger==0.1.5'],
entry_points={
'console_scripts': [
'qbittorrent-exporter=qbittorrent_exporter.exporter:main',