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()