""" ner_exporter.py Sonde l'API NER toutes les 30s et expose les métriques sur :9100/metrics pour que Prometheus puisse les collecter. """ import time import requests from prometheus_client import start_http_server, Gauge, Counter # ─── Config ──────────────────────────────────────────────────────────────────── NER_URL = "https://kahouli-magento-ner-api.hf.space/ner" TEST_PAYLOAD = {"text": "je veux 4 Fusion Backpack et 5 Impulse Duffle"} INTERVAL = 30 # secondes entre chaque sonde EXPORTER_PORT = 9100 # ─── Métriques Prometheus ────────────────────────────────────────────────────── response_time_gauge = Gauge( "ner_response_time_ms", "Temps de traitement NER retourné par l'API (processing_time_ms)" ) http_latency_gauge = Gauge( "ner_http_latency_ms", "Latence HTTP totale mesurée côté client (aller-retour complet)" ) availability_gauge = Gauge( "ner_availability", "Disponibilité de l'API : 1 = UP, 0 = DOWN" ) entities_count_gauge = Gauge( "ner_entities_count", "Nombre d'entités NER extraites lors de la dernière sonde" ) request_counter = Counter( "ner_requests_total", "Nombre total de requêtes envoyées à l'API NER" ) error_counter = Counter( "ner_errors_total", "Nombre total d'erreurs (HTTP non-200 ou exception réseau)" ) # ─── Sonde ───────────────────────────────────────────────────────────────────── def probe(): request_counter.inc() try: t0 = time.time() r = requests.post(NER_URL, json=TEST_PAYLOAD, timeout=20) latency_ms = (time.time() - t0) * 1000 http_latency_gauge.set(latency_ms) if r.status_code == 200: data = r.json() # Disponibilité availability_gauge.set(1) # Temps de traitement NER interne proc_ms = data.get("processing_time_ms", 0) response_time_gauge.set(proc_ms) # Nombre d'entités extraites entities = data.get("entities", []) entities_count_gauge.set(len(entities)) print( f"[OK] latence={latency_ms:.1f}ms | " f"NER={proc_ms}ms | " f"entités={len(entities)} | " f"payload={[e['label'] for e in entities]}" ) else: availability_gauge.set(0) error_counter.inc() print(f"[WARN] HTTP {r.status_code} — {r.text[:200]}") except requests.exceptions.Timeout: availability_gauge.set(0) http_latency_gauge.set(0) error_counter.inc() print("[ERROR] Timeout — le Space HF ne répond pas") except Exception as e: availability_gauge.set(0) http_latency_gauge.set(0) error_counter.inc() print(f"[ERROR] Exception : {e}") # ─── Main ────────────────────────────────────────────────────────────────────── if __name__ == "__main__": print(f"Démarrage de l'exporter NER sur le port {EXPORTER_PORT}...") start_http_server(EXPORTER_PORT) print(f"Métriques disponibles sur http://localhost:{EXPORTER_PORT}/metrics") print(f"Sonde toutes les {INTERVAL}s → {NER_URL}") # Première sonde immédiate probe() while True: time.sleep(INTERVAL) probe()