Spaces:
Sleeping
Sleeping
| """ | |
| 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() | |