Compare commits

..

7 Commits

Author SHA1 Message Date
√(noham)²
f4543b1969 add netdata + node exporter 2024-02-02 17:56:29 +01:00
√(noham)²
ff9e4cfabd c 2024-01-21 21:25:39 +01:00
√(noham)²
ec6af68f46 new metrics 2024-01-21 21:19:01 +01:00
√(noham)²
6b9c2e5a50 ratio 2024-01-08 22:46:22 +01:00
√(noham)²
2602383484 Update screenshot.png 2024-01-08 22:30:34 +01:00
√(noham)²
62952917be total dl/up 2024-01-08 22:28:58 +01:00
Diego Heras
c10515dc08
Update Python to version 3.12 (#31)
* Python 3.12 has better performance
2023-12-10 10:16:54 +01:00
13 changed files with 1504 additions and 154 deletions

View File

@ -15,7 +15,7 @@ jobs:
checks: write
strategy:
matrix:
python-version: ["3.11"]
python-version: ["3.12"]
steps:
- uses: actions/checkout@v3

View File

@ -12,7 +12,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.11'
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip

1
.gitignore vendored
View File

@ -136,3 +136,4 @@ config.env
# Ignore ruff files
.ruff_cache
.DS_Store

View File

@ -1,4 +1,4 @@
FROM python:3.11-alpine
FROM python:3.12-alpine
# Install package
WORKDIR /code

39
docker-compose.yml Normal file
View File

@ -0,0 +1,39 @@
name: prom-qb-alltime
services:
esanchezm:
cpu_shares: 90
command: []
deploy:
resources:
limits:
memory: 7943M
environment:
- QBITTORRENT_HOST=192.168.1.58
- QBITTORRENT_PASS=Cp3mMdP!#
- QBITTORRENT_PORT=8188
- QBITTORRENT_USER=noham
image: prom-qb-alltime
labels:
icon: https://raw.githubusercontent.com/esanchezm/prometheus-qbittorrent-exporter/master/logo.png
ports:
- target: 8000
published: "9101"
protocol: tcp
restart: unless-stopped
volumes: []
devices: []
cap_add: []
network_mode: bridge
privileged: false
container_name: ""
x-casaos:
author: self
category: self
hostname: ""
icon: https://raw.githubusercontent.com/esanchezm/prometheus-qbittorrent-exporter/master/logo.png
index: /metrics
port_map: "9101"
scheme: http
store_app_id: relaxed_albert
title:
custom: prom-qb-alltime

View File

@ -2,8 +2,10 @@
## 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.
To import the dashboard into your grafana, download the [dashboard.json](https://raw.githubusercontent.com/nohamr/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)
![](./screenshot1.png)
![](./screenshot2.png)
![](./screenshot3.png)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

BIN
grafana/screenshot1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

BIN
grafana/screenshot2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 KiB

BIN
grafana/screenshot3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

View File

@ -1,11 +1,13 @@
import faulthandler
import logging
import os
# from dotenv import load_dotenv
# load_dotenv()
import signal
import sys
import time
from dataclasses import dataclass, field
from enum import StrEnum, auto
from enum import Enum, auto
from typing import Any, Iterable
from prometheus_client import start_http_server
@ -17,8 +19,7 @@ from qbittorrentapi import Client, TorrentStates
faulthandler.enable()
logger = logging.getLogger()
class MetricType(StrEnum):
class MetricType(Enum):
"""
Represents possible metric types (used in this project).
"""
@ -85,20 +86,22 @@ class QbittorrentMetricsCollector:
"""
Returns metrics about the state of the qbittorrent server.
"""
response: dict[str, Any] = {}
maindata: dict[str, Any] = {}
version: str = ""
# Fetch data from API
try:
response = self.client.transfer.info
maindata = self.client.sync_maindata()
version = self.client.app.version
except Exception as e:
logger.error(f"Couldn't get server info: {e}")
server_state = maindata.get('server_state', {})
return [
Metric(
name=f"{self.config['metrics_prefix']}_up",
value=bool(response),
value=bool(server_state),
labels={"version": version},
help_text=(
"Whether the qBittorrent server is answering requests from this"
@ -107,7 +110,7 @@ class QbittorrentMetricsCollector:
),
Metric(
name=f"{self.config['metrics_prefix']}_connected",
value=response.get("connection_status", "") == "connected",
value=server_state.get("connection_status", "") == "connected",
labels={}, # no labels in the example
help_text=(
"Whether the qBittorrent server is connected to the Bittorrent"
@ -116,7 +119,7 @@ class QbittorrentMetricsCollector:
),
Metric(
name=f"{self.config['metrics_prefix']}_firewalled",
value=response.get("connection_status", "") == "firewalled",
value=server_state.get("connection_status", "") == "firewalled",
labels={}, # no labels in the example
help_text=(
"Whether the qBittorrent server is connected to the Bittorrent"
@ -125,24 +128,91 @@ class QbittorrentMetricsCollector:
),
Metric(
name=f"{self.config['metrics_prefix']}_dht_nodes",
value=response.get("dht_nodes", 0),
value=server_state.get("dht_nodes", 0),
labels={}, # no labels in the example
help_text="Number of DHT nodes connected to.",
),
Metric(
name=f"{self.config['metrics_prefix']}_dl_info_data",
value=response.get("dl_info_data", 0),
value=server_state.get("dl_info_data", 0),
labels={}, # no labels in the example
help_text="Data downloaded since the server started, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_up_info_data",
value=response.get("up_info_data", 0),
value=server_state.get("up_info_data", 0),
labels={}, # no labels in the example
help_text="Data uploaded since the server started, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_alltime_dl",
value=server_state.get("alltime_dl", 0),
labels={}, # no labels in the example
help_text="Total data downloaded, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_alltime_ul",
value=server_state.get("alltime_ul", 0),
labels={}, # no labels in the example
help_text="Total data uploaded, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_total_peer_connections",
value=server_state.get("total_peer_connections", 0),
labels={}, # no labels in the example
help_text="total_peer_connections.",
metric_type=MetricType.COUNTER,
),
#### Disk metrics
Metric(
name=f"{self.config['metrics_prefix']}_write_cache_overload",
value=server_state.get("write_cache_overload", 0),
labels={}, # no labels in the example
help_text="write_cache_overload.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_read_cache_overload",
value=server_state.get("read_cache_overload", 0),
labels={}, # no labels in the example
help_text="read_cache_overload.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_read_cache_hits",
value=server_state.get("read_cache_hits", 0),
labels={}, # no labels in the example
help_text="read_cache_hits.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_average_time_queue",
value=server_state.get("average_time_queue", 0),
labels={}, # no labels in the example
help_text="average_time_queue.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_free_space_on_disk",
value=server_state.get("free_space_on_disk", 0),
labels={}, # no labels in the example
help_text="free_space_on_disk.",
metric_type=MetricType.COUNTER,
),
Metric(
name=f"{self.config['metrics_prefix']}_queued_io_jobs",
value=server_state.get("queued_io_jobs", 0),
labels={}, # no labels in the example
help_text="queued_io_jobs.",
metric_type=MetricType.COUNTER,
),
]
def _fetch_categories(self) -> dict:

View File

@ -270,6 +270,20 @@ class TestQbittorrentMetricsCollector(unittest.TestCase):
help_text="Data uploaded since the server started, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name="qbittorrent_alltime_dl",
value=0,
labels={}, # no labels in the example
help_text="Total data downloaded, in bytes.",
metric_type=MetricType.COUNTER,
),
Metric(
name="qbittorrent_alltime_ul",
value=0,
labels={}, # no labels in the example
help_text="Total data uploaded, in bytes.",
metric_type=MetricType.COUNTER,
),
]
metrics = self.collector._get_qbittorrent_status_metrics()