# TeamSpeak 6 Prometheus Exporter [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Docker](https://img.shields.io/badge/Docker-ready-2496ED?logo=docker&logoColor=white)](https://gitea.zol.oixb.run/oixb.run/ts6-grafana) [![Prometheus](https://img.shields.io/badge/Prometheus-exporter-E6522C?logo=prometheus&logoColor=white)](#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)