cloudflared icon indicating copy to clipboard operation
cloudflared copied to clipboard

💡Add tunnel name to the Prometheus Metrics

Open svenvg93 opened this issue 1 year ago • 1 comments

Describe the feature you'd like When running multiple tunnels I would like to have the tunnel name added the prometheus metrics, so it can used as a variable in the Grafana dashboards for filtering.

Describe alternatives you've considered N/A

Additional context N/A

svenvg93 avatar Jun 29 '24 16:06 svenvg93


from prometheus_client import start_http_server, Counter, Gauge
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
import threading
import random

# Prometheus metrics with tunnel_name label
REQUEST_COUNT = Counter(
    'tunnel_requests_total',
    'Total requests processed by the tunnel',
    ['tunnel_name']
)
TUNNEL_STATUS = Gauge(
    'tunnel_status',
    'Status of the tunnel (1 = up, 0 = down)',
    ['tunnel_name']
)

# Simulated tunnel class
class Tunnel:
    def __init__(self, name):
        self.name = name
        self.running = False
        self.thread = None

    def start(self):
        print(f"Starting tunnel: {self.name}")
        self.running = True
        TUNNEL_STATUS.labels(tunnel_name=self.name).set(1)
        self.thread = threading.Thread(target=self.run)
        self.thread.start()

    def stop(self):
        print(f"Stopping tunnel: {self.name}")
        self.running = False
        TUNNEL_STATUS.labels(tunnel_name=self.name).set(0)
        if self.thread:
            self.thread.join()

    def run(self):
        while self.running:
            # Simulate processing requests
            REQUEST_COUNT.labels(tunnel_name=self.name).inc(random.randint(0, 5))
            time.sleep(1)

# HTTP server to simulate tunnel endpoints
class TunnelHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        tunnel_name = self.path.strip('/')
        if tunnel_name in tunnels:
            REQUEST_COUNT.labels(tunnel_name=tunnel_name).inc()
            self.send_response(200)
            self.end_headers()
            self.wfile.write(f"Tunnel {tunnel_name} is active".encode())
        else:
            self.send_response(404)
            self.end_headers()
            self.wfile.write(b"Tunnel not found")

# Manage multiple tunnels
tunnels = {}

def start_tunnel_server(port=8080):
    server = HTTPServer(('localhost', port), TunnelHandler)
    print(f"Starting tunnel server on port {port}")
    server.serve_forever()

def main():
    # Start Prometheus metrics server
    start_http_server(9090)
    print("Prometheus metrics available at http://localhost:9090/metrics")

    # Start tunnel HTTP server in a separate thread
    threading.Thread(target=start_tunnel_server, daemon=True).start()

    # Create and start multiple tunnels
    tunnel_names = ['tunnel1', 'tunnel2', 'tunnel3']
    for name in tunnel_names:
        tunnel = Tunnel(name)
        tunnels[name] = tunnel
        tunnel.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Shutting down...")
        for tunnel in tunnels.values():
            tunnel.stop()

if __name__ == "__main__":
    main()

ljluestc avatar Jun 01 '25 20:06 ljluestc