mirror of
https://github.com/NohamR/prometheus-qbittorrent-exporter.git
synced 2026-01-09 23:58:16 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef12d46431 | ||
|
|
9a19f46b7e | ||
|
|
a53c7ae08b | ||
|
|
17ebcb0834 | ||
|
|
7016e3de2b | ||
|
|
af51fd5b67 | ||
|
|
82151b1d82 | ||
|
|
b6e3131929 | ||
|
|
688fcc54cb | ||
|
|
bc79a0dd52 | ||
|
|
af732087e8 | ||
|
|
15130f1c95 | ||
|
|
53dc38f796 | ||
|
|
3bfc3f0673 | ||
|
|
eee65ec84e | ||
|
|
b4aefff06d | ||
|
|
baf14d495c | ||
|
|
003297ecfd | ||
|
|
2497249b8c | ||
|
|
9e9f4a9ce4 | ||
|
|
40d9bb964e | ||
|
|
0b3fb04728 | ||
|
|
13a52c40f2 | ||
|
|
109924d0da | ||
|
|
b391e5f83a | ||
|
|
b924dd2bbb | ||
|
|
28f1611079 |
29
.github/workflows/docker.yml
vendored
Normal file
29
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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: 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:$GITHUB_REF
|
||||||
26
.github/workflows/pythonpublish.yml
vendored
Normal file
26
.github/workflows/pythonpublish.yml
vendored
Normal 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
19
Dockerfile
Normal 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"]
|
||||||
17
README.md
17
README.md
@@ -20,7 +20,7 @@ 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
|
||||||
```
|
```
|
||||||
|
|
||||||
The application reads configuration using environment variables:
|
The application reads configuration using environment variables:
|
||||||
@@ -33,22 +33,23 @@ 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"}`|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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 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
|
||||||
@@ -77,34 +78,34 @@ class QbittorrentMetricsCollector():
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"name": "up",
|
"name": f"{self.config['metrics_prefix']}_up",
|
||||||
"value": response is None,
|
"value": response is not None,
|
||||||
"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 +117,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 +133,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 +168,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
|
||||||
|
|||||||
4
setup.py
4
setup.py
@@ -6,14 +6,14 @@ 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.0',
|
||||||
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',
|
||||||
|
|||||||
Reference in New Issue
Block a user