README
ΒΆ
Hysteria2 Exporter
A Prometheus exporter for Hysteria2 proxy server metrics. This exporter collects statistics from multiple Hysteria2 instances via their Traffic Stats API and exposes them as Prometheus metrics.
Features
- π Multi-instance Support: Monitor multiple Hysteria2 servers from a single exporter
- π Comprehensive Metrics: Traffic, connection, and optional stream-level statistics
- π Health Monitoring: Node availability and API response metrics
- π§ Configurable: Flexible scraping intervals, timeouts, and retry logic
- π Production Ready: Built-in error handling, logging, and graceful shutdown
- π Prometheus Compatible: Standard metrics format with proper labels
Quick Start
Installation
Option 1: Download Binary
# Download the latest release
wget https://github.com/cadl/hysteria2-exporter/releases/latest/download/hysteria2-exporter-linux-amd64
chmod +x hysteria2-exporter-linux-amd64
sudo mv hysteria2-exporter-linux-amd64 /usr/local/bin/hysteria2-exporter
Option 2: Build from Source
git clone https://github.com/cadl/hysteria2-exporter.git
cd hysteria2-exporter
go build -o hysteria2-exporter
Option 3: Docker
docker run -d \
--name hysteria2-exporter \
-p 9090:9090 \
-v $(pwd)/config.yaml:/app/config.yaml \
cadl/hysteria2-exporter:latest
Configuration
Create a configuration file config.yaml:
listen: ":9090"
scrape:
interval: 30s
timeout: 10s
enable_streams: false
stream_metrics_ttl: 5m
max_retries: 3
instances:
- name: "server1"
stats_endpoint: "http://127.0.0.1:9999"
secret: "your-api-secret"
- name: "server2"
stats_endpoint: "http://192.168.1.100:8888"
secret: "another-secret"
Running
# Start the exporter
./hysteria2-exporter -config config.yaml
# Check if it's working
curl http://localhost:9090/metrics
Metrics
The exporter provides the following metrics:
Node Status Metrics
| Metric | Type | Description | Labels |
|---|---|---|---|
hysteria2_up |
Gauge | Whether the node is up and responding | instance, endpoint |
hysteria2_api_response_duration_seconds |
Histogram | API request duration | instance, endpoint, api_path, status |
hysteria2_api_requests_total |
Counter | Total API requests | instance, endpoint, api_path, status |
Traffic Metrics
| Metric | Type | Description | Labels |
|---|---|---|---|
hysteria2_client_bytes_transmitted_total |
Counter | Total bytes transmitted by clients | instance, endpoint, client_id |
hysteria2_client_bytes_received_total |
Counter | Total bytes received by clients | instance, endpoint, client_id |
Connection Metrics
| Metric | Type | Description | Labels |
|---|---|---|---|
hysteria2_client_connections |
Gauge | Number of connections per client | instance, endpoint, client_id |
hysteria2_clients_online_total |
Gauge | Total number of online clients | instance, endpoint |
Stream Metrics (Optional)
When enable_streams: true is set:
| Metric | Type | Description | Labels |
|---|---|---|---|
hysteria2_stream_bytes_transmitted_total |
Counter | Bytes transmitted by streams | instance, endpoint, client_id, state, req_addr, hooked_addr |
hysteria2_stream_bytes_received_total |
Counter | Bytes received by streams | instance, endpoint, client_id, state, req_addr, hooked_addr |
hysteria2_streams_active_total |
Gauge | Number of active streams | instance, endpoint, state |
hysteria2_stream_lifetime_seconds |
Gauge | Stream lifetime in seconds | instance, endpoint, client_id, state, req_addr |
hysteria2_stream_idle_seconds |
Gauge | Stream idle time in seconds | instance, endpoint, client_id, state, req_addr |
Scrape Metrics
| Metric | Type | Description | Labels |
|---|---|---|---|
hysteria2_scrape_duration_seconds |
Gauge | Duration of the last scrape | instance, endpoint |
hysteria2_scrape_success |
Gauge | Whether the last scrape was successful | instance, endpoint |
hysteria2_last_scrape_timestamp |
Gauge | Unix timestamp of last scrape | instance, endpoint |
Configuration Reference
Main Configuration
# HTTP server listen address (default: ":9090")
listen: ":9090"
# Scrape configuration
scrape:
# How often to scrape metrics (default: 30s)
interval: 30s
# Timeout for API requests (default: 10s)
timeout: 10s
# Enable detailed stream metrics (default: false)
# WARNING: May generate high cardinality metrics
enable_streams: false
# TTL for stream metrics by req_addr (default: 5m)
# Stream metrics for a req_addr will be cleaned up if no new streams
# for that req_addr are seen within this duration
stream_metrics_ttl: 5m
# Maximum retries for failed requests (default: 3)
max_retries: 3
# Hysteria2 instances to monitor
instances:
- name: "unique-name" # Required: unique identifier
stats_endpoint: "http://..." # Required: full API endpoint URL
secret: "api-secret" # Optional: API secret if configured
Hysteria2 Server Configuration
To enable the Traffic Stats API on your Hysteria2 server, add this to your server configuration:
# hysteria2 server config
trafficStats:
listen: ":9999"
secret: "your-api-secret" # Optional but recommended
Prometheus Configuration
Add this job to your prometheus.yml:
scrape_configs:
- job_name: 'hysteria2'
static_configs:
- targets: ['localhost:9090']
scrape_interval: 30s
metrics_path: /metrics
Example Queries
Traffic Analysis
# Top clients by bandwidth usage
topk(10, rate(hysteria2_client_bytes_transmitted_total[5m]) + rate(hysteria2_client_bytes_received_total[5m]))
# Total bandwidth per instance
sum by (instance) (rate(hysteria2_client_bytes_transmitted_total[5m]) + rate(hysteria2_client_bytes_received_total[5m]))
Connection Monitoring
# Online clients per instance
hysteria2_clients_online_total
# Client connection distribution
histogram_quantile(0.95, sum by (instance, le) (hysteria2_client_connections))
Health Monitoring
# Down instances
hysteria2_up == 0
# API response time
histogram_quantile(0.95, hysteria2_api_response_duration_seconds)
Alerting Rules
Example Prometheus alerting rules:
groups:
- name: hysteria2
rules:
- alert: Hysteria2NodeDown
expr: hysteria2_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Hysteria2 node {{ $labels.instance }} is down"
description: "Hysteria2 node {{ $labels.instance }} has been down for more than 1 minute"
- alert: Hysteria2HighLatency
expr: histogram_quantile(0.95, hysteria2_api_response_duration_seconds) > 5
for: 2m
labels:
severity: warning
annotations:
summary: "High API latency for {{ $labels.instance }}"
description: "95th percentile latency is {{ $value }}s for {{ $labels.instance }}"
- alert: Hysteria2HighTraffic
expr: sum by (instance) (rate(hysteria2_client_bytes_transmitted_total[5m]) + rate(hysteria2_client_bytes_received_total[5m])) > 100*1024*1024
for: 5m
labels:
severity: warning
annotations:
summary: "High traffic on {{ $labels.instance }}"
description: "Traffic rate is {{ $value | humanize }}B/s on {{ $labels.instance }}"
Docker Compose
Example docker-compose.yml:
version: '3.8'
services:
hysteria2-exporter:
image: cadl/hysteria2-exporter:latest
ports:
- "9090:9090"
volumes:
- ./config.yaml:/app/config.yaml:ro
restart: unless-stopped
prometheus:
image: prom/prometheus:latest
ports:
- "9091:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
restart: unless-stopped
Development
Building
# Build for current platform
go build -o hysteria2-exporter
# Build for multiple platforms
make build-all
# Build Docker image
docker build -t hysteria2-exporter .
Testing
# Run tests
go test ./...
# Test with real Hysteria2 instance
./hysteria2-exporter -config config.yaml.example
Performance Considerations
- Stream Metrics: Disable
enable_streamsin production unless needed, as it can create high cardinality metrics - Stream Metrics TTL: Configure
stream_metrics_ttlto automatically clean up expired metrics and prevent memory leaks - Scrape Interval: Balance between data freshness and system load
- Timeouts: Set appropriate timeouts based on network conditions
- Retries: Configure retries to handle temporary network issues
Troubleshooting
Common Issues
-
Connection Refused
- Check if Hysteria2 Traffic Stats API is enabled
- Verify endpoint URL and port
- Check firewall rules
-
Authentication Failed
- Verify the API secret matches server configuration
- Check if secret is required on server
-
High Memory Usage
- Disable stream metrics if not needed
- Reduce scrape frequency
- Check for metric label cardinality
Debugging
Enable debug logging:
./hysteria2-exporter -config config.yaml -v
Check exporter status:
curl http://localhost:9090/health
curl http://localhost:9090/
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Hysteria2 - The fast, secure and reliable proxy
- Prometheus - Monitoring and alerting toolkit
- Go - The programming language
Documentation
ΒΆ
There is no documentation for this package.