43 Commits
1.0.1 ... 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
Esteban Sánchez
109924d0da Fixed up metric value and documentation 2020-09-29 13:46:41 +02:00
Esteban Sánchez
b391e5f83a Fixed docker run line 2020-09-29 12:03:26 +02:00
Esteban Sánchez
b924dd2bbb Added Dockerfile 2020-09-29 11:54:26 +02:00
Esteban Sánchez
28f1611079 Fixed first version 2020-09-29 11:52:09 +02:00
9 changed files with 1067 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/*

19
Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM alpine:3.11
# Installing required packages
RUN apk add --update --no-cache \
python3
# Install package
WORKDIR /code
COPY . .
RUN pip3 install .
ENV QBITTORRENT_HOST=""
ENV QBITTORRENT_PORT=""
ENV QBITTORRENT_USER=""
ENV QBITTORRENT_PASS=""
ENV EXPORTER_PORT="8000"
ENV EXPORTER_LOG_LEVEL="INFO"
ENTRYPOINT ["qbittorrent-exporter"]

View File

@@ -20,9 +20,14 @@ qbittorrent-exporter
Another option is run it in a docker container. Another option is run it in a docker container.
``` ```
docker run esanchezm/prometheus-qbittorrent-exporter 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: The application reads configuration using environment variables:
| Environment variable | Default | Description | | Environment variable | Default | Description |
@@ -33,22 +38,29 @@ The application reads configuration using environment variables:
| `QBITTORRENT_PASS` | `""` | qbittorrent password | | `QBITTORRENT_PASS` | `""` | qbittorrent password |
| `EXPORTER_PORT` | `8000` | Exporter listening port | | `EXPORTER_PORT` | `8000` | Exporter listening port |
| `EXPORTER_LOG_LEVEL` | `INFO` | Log level. One of: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` | | `EXPORTER_LOG_LEVEL` | `INFO` | Log level. One of: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` |
| `METRICS_PREFIX` | `qbittorrent` | Prefix to add to all the metrics |
## 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 | | 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 | | `qbittorrent_up` | gauge | Whether if the qBittorrent server is answering requests from this exporter. A `version` label with the server version is added |
| `qbittorrent_connected` | gauge | Whether if the qBittorrent server is connected to the Bittorrent network. | | `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_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_dht_nodes` | gauge | Number of DHT nodes connected to |
| `qbittorrent_dl_info_data` | counter | Data downloaded since the server started, in bytes | | `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_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_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 ## 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 sys
import signal import signal
import faulthandler import faulthandler
from attrdict import AttrDict
from qbittorrentapi import Client, TorrentStates from qbittorrentapi import Client, TorrentStates
from qbittorrentapi.exceptions import APIConnectionError
from prometheus_client import start_http_server from prometheus_client import start_http_server
from prometheus_client.core import GaugeMetricFamily, CounterMetricFamily, REGISTRY from prometheus_client.core import GaugeMetricFamily, CounterMetricFamily, REGISTRY
import logging import logging
@@ -40,6 +42,7 @@ class QbittorrentMetricsCollector():
self.torrents = self.client.torrents.info() self.torrents = self.client.torrents.info()
except Exception as e: except Exception as e:
logger.error(f"Couldn't get server info: {e}") logger.error(f"Couldn't get server info: {e}")
return None
metrics = self.get_qbittorrent_metrics() metrics = self.get_qbittorrent_metrics()
@@ -65,46 +68,49 @@ class QbittorrentMetricsCollector():
return metrics return metrics
def get_qbittorrent_status_metrics(self): def get_qbittorrent_status_metrics(self):
response = {}
version = ""
# Fetch data from API # Fetch data from API
try: try:
response = self.client.transfer.info response = self.client.transfer.info
version = self.client.app.version version = self.client.app.version
self.torrents = self.client.torrents.info() self.torrents = self.client.torrents.info()
except Exception as e: except APIConnectionError as e:
logger.error(f"Couldn't get server info: {e}") logger.error(f"Couldn't get server info: {e.error_message}")
response = None except Exception:
version = "" logger.error(f"Couldn't get server info")
return [ return [
{ {
"name": "up", "name": f"{self.config['metrics_prefix']}_up",
"value": response is None, "value": bool(response),
"labels": {"version": version}, "labels": {"version": version},
"help": "Whether if server is alive or not", "help": "Whether if server is alive or not",
}, },
{ {
"name": "connected", "name": f"{self.config['metrics_prefix']}_connected",
"value": response.get("connection_status", "") == "connected", "value": response.get("connection_status", "") == "connected",
"help": "Whether if server is connected or not", "help": "Whether if server is connected or not",
}, },
{ {
"name": "firewalled", "name": f"{self.config['metrics_prefix']}_firewalled",
"value": response.get("connection_status", "") == "firewalled", "value": response.get("connection_status", "") == "firewalled",
"help": "Whether if server is under a firewall or not", "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), "value": response.get("dht_nodes", 0),
"help": "DHT nodes connected to", "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), "value": response.get("dl_info_data", 0),
"help": "Data downloaded this session (bytes)", "help": "Data downloaded this session (bytes)",
"type": "counter" "type": "counter"
}, },
{ {
"name": "up_info_data", "name": f"{self.config['metrics_prefix']}_up_info_data",
"value": response.get("up_info_data", 0), "value": response.get("up_info_data", 0),
"help": "Data uploaded this session (bytes)", "help": "Data uploaded this session (bytes)",
"type": "counter" "type": "counter"
@@ -116,17 +122,15 @@ class QbittorrentMetricsCollector():
categories = self.client.torrent_categories.categories categories = self.client.torrent_categories.categories
except Exception as e: except Exception as e:
logger.error(f"Couldn't fetch categories: {e}") logger.error(f"Couldn't fetch categories: {e}")
categories = None
if not categories:
return [] return []
if not self.torrents: if not self.torrents:
return [] return []
metrics = [] metrics = []
categories.Uncategorized = AttrDict({'name': 'Uncategorized', 'savePath': ''})
for category in categories: 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: for status in self.TORRENT_STATUSES:
status_prop = f"is_{status}" 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'])) t for t in category_torrents if getattr(TorrentStates, status_prop).fget(TorrentStates(t['state']))
] ]
metrics.append({ metrics.append({
"name": "torrents_count", "name": f"{self.config['metrics_prefix']}_torrents_count",
"value": len(status_torrents), "value": len(status_torrents),
"labels": { "labels": {
"status": status, "status": status,
@@ -169,7 +173,8 @@ def main():
"username": os.environ.get("QBITTORRENT_USER", ""), "username": os.environ.get("QBITTORRENT_USER", ""),
"password": os.environ.get("QBITTORRENT_PASS", ""), "password": os.environ.get("QBITTORRENT_PASS", ""),
"exporter_port": int(os.environ.get("EXPORTER_PORT", "8000")), "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 # Register signal handler

View File

@@ -6,18 +6,18 @@ with open("README.md", "r") as fh:
setup( setup(
name='prometheus-qbittorrent-exporter', name='prometheus-qbittorrent-exporter',
packages=['qbittorrent_exporter'], packages=['qbittorrent_exporter'],
version='1.0.0', version='1.1.2',
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
description='Prometheus exporter for qbittorrent', description='Prometheus exporter for qbittorrent',
author='Esteban Sanchez', author='Esteban Sanchez',
author_email='esteban.sanchez@gmail.com', author_email='esteban.sanchez@gmail.com',
url='https://github.com/esanchezm/prometheus-qbittorrent-exporter', url='https://github.com/esanchezm/prometheus-qbittorrent-exporter',
download_url='https://github.com/spreaker/prometheus-qbittorrent-exporter/archive/1.0.0.tar.gz', download_url='https://github.com/esanchezm/prometheus-qbittorrent-exporter/archive/1.1.0.tar.gz',
keywords=['prometheus', 'qbittorrent'], keywords=['prometheus', 'qbittorrent'],
classifiers=[], classifiers=[],
python_requires='>=3', 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={ entry_points={
'console_scripts': [ 'console_scripts': [
'qbittorrent-exporter=qbittorrent_exporter.exporter:main', 'qbittorrent-exporter=qbittorrent_exporter.exporter:main',