Si les proxies sont utilisés en production — pour le scraping, l'automatisation des comptes SMM ou le multi-comptage à grande échelle — il arrive un moment où « ça fonctionne » ne suffit plus comme réponse. Des chiffres sont nécessaires : combien de requêtes échouent, dans quelle mesure la latence a augmenté après le changement de pool IP, le quota de trafic du fournisseur est-il épuisé ? Nous examinons 7 métriques à collecter dans Prometheus et à visualiser dans Grafana, afin de détecter les problèmes avant que les utilisateurs ou les comptes bloqués ne les remarquent.
Pourquoi surveiller les proxies en production
Les proxies ne sont pas une infrastructure statique comme un serveur avec une IP fixe. C'est un pool d'adresses en constante évolution, dont le comportement dépend du fournisseur, de la charge, de la région et même de l'heure de la journée. Sans surveillance, vous ne découvrirez un problème que lorsque le parseur Wildberries ou Ozon cesse de fournir des données, lorsque le compte publicitaire Facebook Ads bloque le compte, ou lorsque le script d'automatisation Instagram commence à être submergé par des CAPTCHA.
L'objectif de la surveillance est de transformer le « quelque chose ne va pas » subjectif en chiffres concrets : la part d'erreurs est passée de 2 % à 15 % au cours de la dernière heure, la latence moyenne a triplé, le trafic d'un proxy a dépassé le quota. Cela permet de réagir avant que le problème ne devienne critique — en basculant automatiquement le pool, en changeant de fournisseur ou en réduisant la fréquence des requêtes.
Pour collecter les métriques, nous utilisons la combinaison Prometheus (stockage de séries temporelles) + Grafana (visualisation et alertes). C'est une pile standard en DevOps qui s'intègre facilement avec n'importe quel langage — Python, Node.js, Go. Ci-dessous, des exemples en Python avec la bibliothèque prometheus_client, mais le principe est universel.
Métrique 1 : Taux de réussite — proportion des requêtes réussies
C'est une métrique de base qui signale en premier les problèmes avec le pool de proxies. Elle est calculée comme le rapport des requêtes avec un code de réponse 200-299 au nombre total de requêtes sur une période donnée. Une chute du taux de réussite en dessous de 90 % signifie généralement qu'une partie des IP du pool est bloquée par le site cible ou que le fournisseur fournit des adresses instables.
Exemple d'instrumentation en Python :
from prometheus_client import Counter, start_http_server
import requests
REQUESTS_TOTAL = Counter(
'proxy_requests_total', 'Total des requêtes via le proxy',
['proxy_pool', 'status']
)
def fetch_with_proxy(url, proxy, pool_name="residential"):
try:
resp = requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=10)
status = "success" if resp.status_code < 300 else "failure"
except requests.exceptions.RequestException:
status = "failure"
REQUESTS_TOTAL.labels(proxy_pool=pool_name, status=status).inc()
start_http_server(9100) # point de terminaison pour Prometheus scrape
Requête PromQL pour calculer le taux de réussite au cours des 5 dernières minutes :
sum(rate(proxy_requests_total{status="success"}[5m]))
/
sum(rate(proxy_requests_total[5m])) * 100
Si vous travaillez avec plusieurs types de proxies simultanément — par exemple, des proxies résidentiels pour les réseaux sociaux et des proxies de centres de données pour le scraping — il est judicieux de décomposer le taux de réussite par le label proxy_pool, afin de voir quel pool se dégrade.
Métrique 2 : Latence — délai de réponse
La latence montre à quelle vitesse le proxy répond. Une augmentation soudaine de la latence précède souvent une chute du taux de réussite — le fournisseur est surchargé, ou l'IP est déjà proche du blocage et le serveur cible commence à ralentir intentionnellement les réponses. Pour la latence, il est important de collecter non seulement la valeur moyenne, mais aussi les percentiles — p50, p95, p99, car la moyenne masque les latences extrêmes qui gênent réellement le travail.
from prometheus_client import Histogram
import time
REQUEST_DURATION = Histogram(
'proxy_request_duration_seconds',
'Durée de la requête via le proxy',
['proxy_pool'],
buckets=[0.1, 0.25, 0.5, 1, 2, 5, 10]
)
def fetch_timed(url, proxy, pool_name="mobile"):
start = time.time()
try:
requests.get(url, proxies={"http": proxy, "https": proxy}, timeout=10)
finally:
REQUEST_DURATION.labels(proxy_pool=pool_name).observe(time.time() - start)
PromQL pour la latence p95 :
histogram_quantile(0.95,
sum(rate(proxy_request_duration_seconds_bucket[5m])) by (le, proxy_pool)
)
Pour les tâches où la vitesse est critique — par exemple, lors de l'automatisation des publicités TikTok, où chaque seconde de chargement de la page augmente le risque de timeout dans un navigateur anti-détection — il est conseillé de définir une alerte sur p95 supérieur à 3-4 secondes.
Métrique 3 : Taux d'erreur par types d'erreurs
Un simple succès/échec n'est pas suffisant pour le diagnostic. Il est nécessaire de séparer les erreurs par types : 407 (Proxy Authentication Required) signifie un problème d'authentification, 429 (Too Many Requests) — dépassement du quota de requêtes, les timeouts — un problème de réseau, 403 — blocage par la protection anti-bot du site cible. Chaque type d'erreur nécessite une réaction différente.
ERROR_BY_TYPE = Counter(
'proxy_errors_total', 'Erreurs de proxy par type',
['proxy_pool', 'error_type']
)
def classify_error(resp=None, exc=None):
if exc:
if isinstance(exc, requests.exceptions.Timeout):
return "timeout"
return "connection_error"
if resp.status_code == 407:
return "auth_error"
if resp.status_code == 429:
return "rate_limited"
if resp.status_code == 403:
return "blocked_by_target"
return "other"
Tableau des erreurs typiques et de leurs causes :
| Code/type | Cause probable | À vérifier |
|---|---|---|
| 407 | Identifiants incorrects ou session expirée | Identifiant/mot de passe du proxy, format de la chaîne de connexion |
| 429 | Quota de requêtes dépassé sur l'IP | Fréquence des requêtes, taille du pool |
| 403 | Protection anti-bot du site cible | User-Agent, empreinte, type de proxy |
| timeout | Surcharge du fournisseur ou du réseau | Charge sur le pool, paramètres de timeout du client |
Métrique 4 : Vitesse de rotation et longévité des IP
Si vous utilisez des proxies rotatifs, il est important de savoir à quelle fréquence l'IP change et combien de requêtes peuvent passer avant que l'adresse ne « brûle » (soit bloquée par le site cible). Cette métrique est particulièrement critique pour le multi-comptage — par exemple, lors de la création de comptes Facebook Ads via Dolphin Anty ou AdsPower, où un changement prématuré d'IP peut interrompre la session et déclencher une vérification de sécurité.
from prometheus_client import Gauge
IP_LIFETIME = Gauge(
'proxy_ip_lifetime_seconds', 'Durée de vie de l\'IP avant rotation',
['proxy_pool']
)
IP_REQUESTS_BEFORE_BAN = Histogram(
'proxy_requests_before_ban',
'Nombre de requêtes passées avant le ban de l\'IP',
['proxy_pool'],
buckets=[10, 50, 100, 500, 1000, 5000]
)
Pour les proxies mobiles, cette métrique se comporte différemment que pour les résidentielles — la rotation via le changement de station de base de l'opérateur fournit des IP plus « propres » avec un risque de ban réduit. Si votre tâche est l'automatisation SMM avec une sensibilité élevée aux bans, il est judicieux de comparer les indicateurs de longévité des IP entre les proxies mobiles et les résidentiels sur des données réelles de votre tableau de bord, plutôt que de se fier aux recommandations générales.
Métrique 5 : Bande passante — consommation de trafic
La plupart des tarifs de proxy sont calculés en fonction du volume de trafic, et non du nombre de requêtes. Sans surveillance, il est facile de manquer le moment où le quota est presque épuisé — surtout si la tâche implique le téléchargement d'images ou de vidéos, par exemple lors du scraping des fiches produits Wildberries avec un grand nombre de photos.
BANDWIDTH_USED = Counter(
'proxy_bandwidth_bytes_total', 'Trafic consommé via le proxy',
['proxy_pool', 'direction'] # direction : upload/download
)
def track_bandwidth(resp, pool_name):
size = len(resp.content)
BANDWIDTH_USED.labels(proxy_pool=pool_name, direction="download").inc(size)
Sur le tableau de bord Grafana, il est utile de construire non pas la valeur absolue du trafic, mais la vitesse de consommation (taux) — cela aide à prévoir quand le quota sera épuisé et à planifier à l'avance l'achat ou le changement vers un autre pool.
Métrique 6 : Répartition géographique et conformité régionale
Pour les marketeurs testant des publicités provenant de différents pays, et pour les arbitragistes travaillant avec le ciblage géographique dans Google Ads ou TikTok Ads, il est crucial que l'IP corresponde réellement à la région déclarée. Une erreur de géolocalisation peut entraîner l'affichage de publicités à un public inapproprié ou le blocage d'un compte pour non-conformité aux paramètres géographiques.
GEO_MISMATCH = Counter(
'proxy_geo_mismatch_total',
'Cas de non-conformité entre la géo déclarée et réelle',
['expected_country', 'actual_country']
)
def verify_geo(proxy, expected_country):
resp = requests.get("https://ipapi.co/json/", proxies={"https": proxy}, timeout=5)
actual = resp.json().get("country_code")
if actual != expected_country:
GEO_MISMATCH.labels(expected_country=expected_country, actual_country=actual).inc()
Il est recommandé de vérifier la géo non pas à chaque requête (ce qui est coûteux en trafic et en temps), mais périodiquement — une fois par heure sur un échantillon d'IP du pool suffisant pour une confiance statistique.
Métrique 7 : Connexions simultanées — sessions parallèles
Le nombre de connexions simultanées via le proxy montre la charge réelle sur le pool. Si le nombre de sessions parallèles dépasse le nombre d'IP que le pool peut traiter sans dégradation, cela entraîne directement une augmentation de la latence et du taux d'erreur des points précédents. Cette métrique est particulièrement importante lors de la mise à l'échelle — lorsque l'agence SMM augmente le nombre de comptes clients actifs simultanément de 10 à 50.
from prometheus_client import Gauge
ACTIVE_CONNECTIONS = Gauge(
'proxy_active_connections', 'Connexions actives actuelles via le proxy',
['proxy_pool']
)
def on_request_start(pool_name):
ACTIVE_CONNECTIONS.labels(proxy_pool=pool_name).inc()
def on_request_end(pool_name):
ACTIVE_CONNECTIONS.labels(proxy_pool=pool_name).dec()
La mise en correspondance de cette métrique avec le taux d'erreur sur un même graphique dans Grafana montrera rapidement la corrélation : dès que le nombre de sessions parallèles dépasse un certain seuil, les erreurs commencent à augmenter de manière non linéaire.
Configuration du tableau de bord dans Grafana : étape par étape
Une fois que les métriques sont instrumentées et que Prometheus les collecte, il faut visualiser les données dans Grafana. Voici les étapes à suivre :
- Ajoutez Prometheus comme source de données : Configuration → Sources de données → Ajouter une source de données → Prometheus, indiquez l'URL de votre serveur Prometheus (généralement
http://localhost:9090). - Créez un nouveau tableau de bord : Créer → Tableau de bord → Ajouter un nouveau panneau.
- Pour le panneau Taux de réussite, utilisez la requête PromQL de la section sur la métrique 1, type de visualisation — Gauge ou Séries temporelles.
- Pour la Latence, créez un panneau avec le type Heatmap, afin de voir la répartition de p50/p95/p99 dans le temps.
- Pour le Taux d'erreur, construisez un graphique à barres empilées avec une répartition par le label
error_type— cela montrera clairement quel type d'erreur domine. - Ajoutez une variable de tableau de bord (Paramètres du tableau de bord → Variables) pour
proxy_pool, afin de passer d'un pool à l'autre sans créer de tableaux de bord séparés. - Enregistrez le tableau de bord et configurez la mise à jour automatique toutes les 30 secondes pour une surveillance quasi temps réel.
Le JSON du tableau de bord prêt peut être exporté via Partager → Exporter → Enregistrer dans un fichier et réutilisé pour différents pools de proxies — résidentiels, mobiles et de centres de données, en ne changeant que la valeur de la variable.
Alertes : quand il est temps d'agir
Un tableau de bord est inutile si personne ne le regarde au moment de l'incident. Il est donc crucial de configurer des alertes dans Grafana (Alertes → Règles d'alerte) avec les seuils suivants, adaptés à la plupart des scénarios de production :
| Métrique | Seuil d'alerte | Action |
|---|---|---|
| Taux de réussite | en dessous de 85 % pendant 5 minutes | Vérifier le pool, basculer vers le secours |
| p95 Latence | au-dessus de 5 secondes | Réduire le parallélisme, vérifier le fournisseur |
| Taux 429 | au-dessus de 10 % des requêtes | Réduire la fréquence des requêtes, augmenter le pool IP |
| Taux de bande passante | prévision d'épuisement du quota dans 24h | Acheter du trafic ou optimiser les requêtes |
Il est préférable d'envoyer les alertes sur Telegram ou Slack via webhook — cela assure une réaction immédiate, plutôt que de vérifier le tableau de bord une fois par jour.
Conclusion
Sept métriques — taux de réussite, latence, taux d'erreur par types, longévité des IP, trafic, conformité géographique et concurrence des connexions — donnent une image complète de la santé de l'infrastructure proxy en production. La combinaison Prometheus + Grafana permet non seulement de fixer le problème a posteriori, mais aussi de voir les tendances et de réagir avant que la dégradation du pool n'entraîne des bans de comptes ou l'arrêt du scraping.
Le choix du type de proxy influence directement les métriques qui seront prioritaires : pour les tâches avec une sensibilité élevée aux bans, telles que le multi-comptage sur Instagram ou TikTok, il est conseillé de surveiller en priorité la longévité des IP et le taux de réussite, en utilisant des proxies résidentiels pour une similarité maximale avec le trafic réel des utilisateurs. Pour les tâches où la vitesse et le volume sont importants — le scraping massif d'Ozon, Avito ou Yandex.Market — la latence et la bande passante deviennent primordiales, et ici, les proxies de centres de données fonctionnent souvent plus efficacement grâce à leur capacité de bande passante supérieure.