245 lines
7.5 KiB
Markdown
245 lines
7.5 KiB
Markdown
# TeamSpeak 6 Prometheus Exporter
|
|
|
|
[](LICENSE)
|
|
[](https://gitea.zol.oixb.run/oixb.run/ts6-grafana)
|
|
[](#metrics)
|
|
|
|
> Prometheus exporter for TeamSpeak 6 servers. Collects metrics via the WebQuery HTTP API and exposes them for Prometheus scraping, with a ready-to-import Grafana dashboard.
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- 🔍 **15+ metrics** — Server status, clients, bandwidth, channels, bans, quality, and more
|
|
- 📊 **Grafana dashboard included** — Ready to import with time series, gauges, and tables
|
|
- 🐳 **Docker ready** — Run alongside your existing TS6 stack
|
|
- ⚡ **Lightweight** — Python-based, minimal resource usage
|
|
- 🏷️ **Per-client labels** — Track individual clients with nickname, platform, country
|
|
- 🔧 **Fully configurable** — All settings via environment variables
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### 1. Generate a TS6 API Key
|
|
|
|
Connect to your TeamSpeak 6 server via ServerQuery (telnet/SSH) and generate an API key:
|
|
|
|
```bash
|
|
# Connect via SSH Query
|
|
ssh serveradmin@your-ts6-server -p 10022
|
|
|
|
# Or via telnet
|
|
telnet your-ts6-server 10011
|
|
|
|
# Login and generate API key
|
|
login serveradmin YOUR_PASSWORD
|
|
apikeyadd scope=manage lifetime=0
|
|
```
|
|
|
|
Save the returned `apikey` value.
|
|
|
|
### 2. Run with Docker Compose
|
|
|
|
Create a `.env` file:
|
|
|
|
```env
|
|
TS6_API_KEY=your-api-key-here
|
|
```
|
|
|
|
If your TS6 server is in a Docker network (e.g., `ts6-panel_ts6-net`), update the network name in `docker-compose.yml` and run:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
### 3. Run Standalone (Python)
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
|
|
export TS6_HOST=your-ts6-server
|
|
export TS6_QUERY_PORT=10080
|
|
export TS6_API_KEY=your-api-key-here
|
|
|
|
python exporter.py
|
|
```
|
|
|
|
Metrics will be available at `http://localhost:9189/metrics`.
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `TS6_HOST` | `localhost` | TeamSpeak 6 server hostname |
|
|
| `TS6_QUERY_PORT` | `10080` | WebQuery HTTP port |
|
|
| `TS6_API_KEY` | **(required)** | API key for authentication |
|
|
| `TS6_SERVER_ID` | `1` | Virtual server ID |
|
|
| `EXPORTER_PORT` | `9189` | Port for the `/metrics` endpoint |
|
|
| `POLL_INTERVAL` | `15` | Polling interval in seconds |
|
|
| `LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
|
|
| `DISABLE_DEFAULT_COLLECTORS` | `true` | Remove default Python/GC metrics |
|
|
| `METRIC_PREFIX` | `ts6` | Prefix for all metric names |
|
|
|
|
---
|
|
|
|
## Metrics
|
|
|
|
### Server
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_server_up` | Gauge | 1 if server is reachable, 0 otherwise |
|
|
| `ts6_server_uptime_seconds` | Gauge | Server uptime in seconds |
|
|
| `ts6_server_version_info` | Info | Version, build number, platform |
|
|
|
|
### Clients
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_clients_online` | Gauge | Online clients (excluding query clients) |
|
|
| `ts6_clients_max` | Gauge | Maximum allowed clients |
|
|
| `ts6_query_clients_online` | Gauge | Connected query clients |
|
|
| `ts6_client_connected` | Gauge | Per-client info (labels: nickname, platform, version, country, channel_id) |
|
|
|
|
### Channels & Groups
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_channels_total` | Gauge | Total channels |
|
|
| `ts6_server_groups_total` | Gauge | Total server groups |
|
|
|
|
### Bandwidth
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_bytes_sent_total` | Gauge | Total bytes sent |
|
|
| `ts6_bytes_received_total` | Gauge | Total bytes received |
|
|
| `ts6_packets_sent_total` | Gauge | Total packets sent |
|
|
| `ts6_packets_received_total` | Gauge | Total packets received |
|
|
| `ts6_file_transfer_bytes_sent_total` | Gauge | File transfer bytes sent |
|
|
| `ts6_file_transfer_bytes_received_total` | Gauge | File transfer bytes received |
|
|
|
|
### Quality
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_average_ping_seconds` | Gauge | Average client ping |
|
|
| `ts6_average_packet_loss` | Gauge | Average packet loss ratio |
|
|
|
|
### Bans
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_bans_total` | Gauge | Active bans count |
|
|
|
|
### Exporter Health
|
|
|
|
| Metric | Type | Description |
|
|
|---|---|---|
|
|
| `ts6_scrape_duration_seconds` | Gauge | Last scrape duration |
|
|
| `ts6_scrape_errors_total` | Counter | Total scrape errors |
|
|
|
|
---
|
|
|
|
## Grafana Dashboard
|
|
|
|
Import the included dashboard from `grafana/dashboard.json`:
|
|
|
|
1. Open Grafana → **Dashboards** → **Import**
|
|
2. Upload the `grafana/dashboard.json` file or paste its contents
|
|
3. Select your Prometheus data source
|
|
4. Click **Import**
|
|
|
|
### Dashboard Sections
|
|
|
|
| Section | Panels |
|
|
|---|---|
|
|
| **Server Overview** | Status indicator, Uptime, Clients Online, Max Clients, Channels, Active Bans |
|
|
| **Clients** | Clients Online Over Time (graph), Connected Clients (table) |
|
|
| **Bandwidth & Network** | Bandwidth bytes/s, Packets/s |
|
|
| **Quality** | Average Ping (gauge), Packet Loss (gauge), File Transfer bandwidth |
|
|
| **Exporter Health** | Scrape Duration, Scrape Errors, Server Groups, Query Clients |
|
|
|
|
---
|
|
|
|
## Prometheus Configuration
|
|
|
|
Add the exporter as a scrape target in your `prometheus.yml`:
|
|
|
|
```yaml
|
|
scrape_configs:
|
|
- job_name: 'teamspeak6'
|
|
scrape_interval: 15s
|
|
static_configs:
|
|
- targets: ['ts6-exporter:9189']
|
|
```
|
|
|
|
---
|
|
|
|
## Docker Integration
|
|
|
|
### With existing TS6 Docker stack
|
|
|
|
If your TeamSpeak 6 runs in Docker, the exporter can join the same network. Update the `networks` section in `docker-compose.yml` to match your TS6 network name:
|
|
|
|
```yaml
|
|
networks:
|
|
ts6-net:
|
|
external: true
|
|
name: your-ts6-network-name # e.g., ts6_ts6-net
|
|
```
|
|
|
|
### Build from source
|
|
|
|
```bash
|
|
docker build -t ts6-prometheus-exporter .
|
|
docker run -d \
|
|
--name ts6-exporter \
|
|
--network your-ts6-network \
|
|
-p 9189:9189 \
|
|
-e TS6_HOST=ts6-server \
|
|
-e TS6_API_KEY=your-api-key \
|
|
ts6-prometheus-exporter
|
|
```
|
|
|
|
---
|
|
|
|
## How It Works
|
|
|
|
```
|
|
┌─────────────┐ HTTP/API Key ┌─────────────┐ Scrape ┌────────────┐
|
|
│ TeamSpeak 6 │ ◄──────────────── │ TS6 │ ◄──────────── │ Prometheus │
|
|
│ Server │ Port 10080 │ Exporter │ Port 9189 │ │
|
|
│ (WebQuery) │ ──────────────► │ (Python) │ ────────────► │ │
|
|
└─────────────┘ JSON response └─────────────┘ /metrics └────────────┘
|
|
│
|
|
▼
|
|
┌────────────┐
|
|
│ Grafana │
|
|
│ Dashboard │
|
|
└────────────┘
|
|
```
|
|
|
|
1. The **exporter** polls the TS6 WebQuery HTTP API every N seconds
|
|
2. Responses are parsed and converted to **Prometheus metrics**
|
|
3. **Prometheus** scrapes the `/metrics` endpoint
|
|
4. **Grafana** queries Prometheus and renders the dashboard
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
- TeamSpeak 6 server with **WebQuery HTTP enabled** (port 10080)
|
|
- A valid **API key** with `manage` scope
|
|
- Python 3.10+ (for standalone) or Docker
|
|
- Prometheus + Grafana for visualization
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
[MIT](LICENSE)
|