85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
import os
|
|
import re
|
|
import socket
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
|
|
MONITOR_HOST = os.getenv("MONITOR_HOST", "dark3proxy")
|
|
MONITOR_PORT = int(os.getenv("MONITOR_PORT", "6800"))
|
|
SOCKET_TIMEOUT = float(os.getenv("SOCKET_TIMEOUT", "2"))
|
|
EXPORTER_PORT = int(os.getenv("EXPORTER_PORT", "9100"))
|
|
|
|
|
|
def fetch_monitor_data() -> str:
|
|
with socket.create_connection((MONITOR_HOST, MONITOR_PORT), timeout=SOCKET_TIMEOUT) as sock:
|
|
sock.settimeout(SOCKET_TIMEOUT)
|
|
chunks = []
|
|
while True:
|
|
data = sock.recv(4096)
|
|
if not data:
|
|
break
|
|
chunks.append(data)
|
|
return b"".join(chunks).decode("utf-8", errors="replace")
|
|
|
|
|
|
def metric_name(raw_parts: list[str]) -> str:
|
|
name = "_".join(raw_parts).lower()
|
|
name = re.sub(r"[^a-z0-9_]", "_", name)
|
|
name = re.sub(r"_+", "_", name).strip("_")
|
|
if not name or not name[0].isalpha():
|
|
name = f"m_{name}" if name else "m_value"
|
|
return f"proxy_{name}"
|
|
|
|
|
|
def parse_metrics(text: str) -> dict[str, float]:
|
|
metrics: dict[str, float] = {}
|
|
for line in text.splitlines():
|
|
parts = line.strip().split()
|
|
if len(parts) < 2:
|
|
continue
|
|
value_token = parts[-1].replace(",", ".")
|
|
try:
|
|
value = float(value_token)
|
|
except ValueError:
|
|
continue
|
|
name = metric_name(parts[:-1])
|
|
metrics[name] = value
|
|
return metrics
|
|
|
|
|
|
def render_metrics() -> bytes:
|
|
body_lines = []
|
|
try:
|
|
raw = fetch_monitor_data()
|
|
metrics = parse_metrics(raw)
|
|
body_lines.append("proxy_exporter_up 1")
|
|
for name in sorted(metrics):
|
|
body_lines.append(f"{name} {metrics[name]}")
|
|
except Exception:
|
|
body_lines.append("proxy_exporter_up 0")
|
|
|
|
body = "\n".join(body_lines) + "\n"
|
|
return body.encode("utf-8")
|
|
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def do_GET(self):
|
|
if self.path not in ("/metrics", "/"):
|
|
self.send_response(404)
|
|
self.end_headers()
|
|
return
|
|
|
|
payload = render_metrics()
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "text/plain; version=0.0.4; charset=utf-8")
|
|
self.send_header("Content-Length", str(len(payload)))
|
|
self.end_headers()
|
|
self.wfile.write(payload)
|
|
|
|
def log_message(self, format, *args):
|
|
return
|
|
|
|
|
|
if __name__ == "__main__":
|
|
server = HTTPServer(("0.0.0.0", EXPORTER_PORT), Handler)
|
|
server.serve_forever()
|