Un pipeline de résolution CAPTCHA tombe rarement en panne d'un seul coup. Le solde s'épuise, la latence dérive, un worker se fige — et vous ne le découvrez que lorsque vos scrapers renvoient des erreurs en masse. Cet article montre comment instrumenter votre intégration CaptchaAI avec Datadog pour transformer ces signaux faibles en métriques et en alertes qui se déclenchent avant la rupture. Vous repartez avec le code d'instrumentation (Python et Node.js), un tableau de bord prêt à importer et un jeu d'alertes calibré pour la production.
Ce que Datadog doit surveiller dans un pipeline CAPTCHA
Avant d'écrire la moindre alerte, décidez de ce que vous mesurez. Sept métriques couvrent l'essentiel d'un solveur de CAPTCHA : elles expliquent, à elles seules, pourquoi un scraper ralentit ou s'arrête.
| Métrique | Type | Ce qu'elle révèle |
|---|---|---|
captcha.solve.count |
Compteur | Nombre total de tâches soumises |
captcha.solve.success |
Compteur | Résolutions réussies |
captcha.solve.error |
Compteur | Résolutions en échec, ventilées par code d'erreur |
captcha.solve.latency |
Histogramme | Temps entre la soumission et la solution |
captcha.queue.depth |
Jauge | Tâches en attente dans la file |
captcha.balance |
Jauge | Solde API restant |
captcha.worker.active |
Jauge | Workers actifs |
Bien taguer vos métriques
Taguez chaque métrique par type de CAPTCHA (captcha_type:recaptcha_v2, turnstile, geetest_v3…) pour comparer la latence de reCAPTCHA v2 et de Turnstile sur un même graphique. Quelques règles évitent les mauvaises surprises :
- Taguez par catégorie (
captcha_type,host), jamais par identifiant unique. - Gardez des tags strictement techniques ; n'y injectez aucune donnée personnelle issue des pages parcourues (RGPD).
- Un seul agent DogStatsD par hôte : tous les workers de la machine y envoient leurs métriques.
Exemple concret : avec deux instances OVHcloud en région eu-west taguées par host, vous repérez immédiatement qu'un seul hôte concentre les timeouts — souvent le signe d'un proxy résidentiel défaillant plutôt qu'un problème côté CaptchaAI.
Instrumenter le solveur en Python avec DogStatsD
Le décorateur ci-dessous enveloppe votre fonction de résolution et émet les métriques automatiquement : un compteur par tâche, un incrément de réussite avec histogramme de latence quand la solution arrive, un compteur d'erreur tagué par code sinon. Il fonctionne avec n'importe quel type pris en charge — reCAPTCHA v2, reCAPTCHA v3, Turnstile, GeeTest v3.
import os
import time
import functools
import requests
from datadog import initialize, statsd
# Initialize Datadog
initialize(
statsd_host=os.environ.get("DD_AGENT_HOST", "localhost"),
statsd_port=int(os.environ.get("DD_DOGSTATSD_PORT", "8125"))
)
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
session = requests.Session()
def track_captcha_metrics(captcha_type="recaptcha_v2"):
"""Decorator to track solve metrics."""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
tags = [f"captcha_type:{captcha_type}"]
statsd.increment("captcha.solve.count", tags=tags)
start = time.time()
try:
result = func(*args, **kwargs)
elapsed = time.time() - start
if "solution" in result:
statsd.increment("captcha.solve.success", tags=tags)
statsd.histogram("captcha.solve.latency", elapsed, tags=tags)
else:
error = result.get("error", "unknown")
statsd.increment(
"captcha.solve.error",
tags=tags + [f"error:{error}"]
)
return result
except Exception as e:
statsd.increment(
"captcha.solve.error",
tags=tags + [f"error:{type(e).__name__}"]
)
raise
return wrapper
return decorator
@track_captcha_metrics(captcha_type="recaptcha_v2")
def solve_recaptcha(sitekey, pageurl):
resp = session.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {"error": data.get("request")}
captcha_id = data["request"]
for _ in range(60):
time.sleep(5)
result = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": captcha_id, "json": 1
}).json()
if result.get("status") == 1:
return {"solution": result["request"]}
if result.get("request") != "CAPCHA_NOT_READY":
return {"error": result.get("request")}
return {"error": "TIMEOUT"}
def report_balance():
"""Send balance as a gauge metric."""
resp = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "getbalance", "json": 1
})
data = resp.json()
if data.get("status") == 1:
balance = float(data["request"])
statsd.gauge("captcha.balance", balance)
return balance
return None
def report_queue_depth(depth):
"""Report current queue depth."""
statsd.gauge("captcha.queue.depth", depth)
def report_worker_count(active, total):
"""Report worker health."""
statsd.gauge("captcha.worker.active", active)
statsd.gauge("captcha.worker.total", total)
report_balance() interroge res.php avec action=getbalance et publie le solde comme jauge. Planifiez-le une fois par minute, hors de la boucle de résolution, pour ne pas gonfler vos appels API.
Faire la même chose en Node.js
Si vos workers tournent sous Node.js, la bibliothèque hot-shots fournit le même client DogStatsD. Le préfixe captcha. et les tags globaux (env:production) sont posés une seule fois à la création du client, ce qui garde le reste du code propre.
const { StatsD } = require("hot-shots");
const axios = require("axios");
const API_KEY = process.env.CAPTCHAAI_API_KEY;
const dogstatsd = new StatsD({
host: process.env.DD_AGENT_HOST || "localhost",
port: parseInt(process.env.DD_DOGSTATSD_PORT || "8125", 10),
prefix: "captcha.",
globalTags: [`env:${process.env.NODE_ENV || "development"}`],
});
async function solveCaptchaWithMetrics(sitekey, pageurl, captchaType = "recaptcha_v2") {
const tags = [`captcha_type:${captchaType}`];
dogstatsd.increment("solve.count", 1, tags);
const startTime = Date.now();
try {
const result = await solveCaptcha(sitekey, pageurl);
const elapsed = (Date.now() - startTime) / 1000;
if (result.solution) {
dogstatsd.increment("solve.success", 1, tags);
dogstatsd.histogram("solve.latency", elapsed, tags);
} else {
dogstatsd.increment("solve.error", 1, [...tags, `error:${result.error}`]);
}
return result;
} catch (err) {
dogstatsd.increment("solve.error", 1, [...tags, `error:${err.message}`]);
throw err;
}
}
async function solveCaptcha(sitekey, pageurl) {
const submitResp = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: sitekey,
pageurl: pageurl,
json: 1,
},
});
if (submitResp.data.status !== 1) {
return { error: submitResp.data.request };
}
const captchaId = submitResp.data.request;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const pollResp = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
});
if (pollResp.data.status === 1) return { solution: pollResp.data.request };
if (pollResp.data.request !== "CAPCHA_NOT_READY") {
return { error: pollResp.data.request };
}
}
return { error: "TIMEOUT" };
}
async function reportBalance() {
try {
const resp = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "getbalance", json: 1 },
});
if (resp.data.status === 1) {
const balance = parseFloat(resp.data.request);
dogstatsd.gauge("balance", balance);
return balance;
}
} catch (err) {
console.error("Balance check failed:", err.message);
}
return null;
}
// Report balance every minute
setInterval(reportBalance, 60000);
module.exports = { solveCaptchaWithMetrics, reportBalance };
Ici, reportBalance() s'exécute toutes les 60 secondes via setInterval. Sur un déploiement multi-worker, ne l'activez que dans un seul processus, sinon le solde sera compté en double.
Importer le tableau de bord dans Datadog
Ce modèle crée quatre widgets :
- taux de résolution (réussite contre erreur) ;
- latence aux percentiles p50, p95 et p99 ;
- solde API restant ;
- profondeur de la file d'attente.
Importez-le via New Dashboard → Import Dashboard JSON, puis ajustez les requêtes si vous avez changé le préfixe.
{
"title": "CaptchaAI Pipeline",
"widgets": [
{
"definition": {
"type": "timeseries",
"title": "Solve Rate (Success vs Error)",
"requests": [
{"q": "sum:captcha.solve.success{*}.as_count()"},
{"q": "sum:captcha.solve.error{*}.as_count()"}
]
}
},
{
"definition": {
"type": "timeseries",
"title": "Solve Latency (p50, p95, p99)",
"requests": [
{"q": "avg:captcha.solve.latency{*}"},
{"q": "percentile:captcha.solve.latency{*},0.95"},
{"q": "percentile:captcha.solve.latency{*},0.99"}
]
}
},
{
"definition": {
"type": "query_value",
"title": "API Balance",
"requests": [{"q": "avg:captcha.balance{*}"}]
}
},
{
"definition": {
"type": "timeseries",
"title": "Queue Depth",
"requests": [{"q": "avg:captcha.queue.depth{*}"}]
}
}
]
}
Définir des alertes qui préviennent avant la panne
Une métrique sans alerte ne sert à rien à 3 h du matin. Les seuils ci-dessous couvrent les pannes réelles d'un pipeline de résolution. Adaptez les valeurs à votre volume — un pic à 120 s est anormal pour du Turnstile, banal pour de l'image OCR sous forte charge.
| Alerte | Condition | Gravité |
|---|---|---|
| Solde faible | captcha.balance < 10 |
Avertissement |
| Solde critique | captcha.balance < 2 |
Critique |
| Taux d'erreur élevé | Taux d'erreur > 10 % sur 5 minutes | Avertissement |
| Pic de latence | Latence p95 > 120 s sur 10 minutes | Avertissement |
| File qui s'accumule | Profondeur de file > 100 en hausse sur 5 minutes | Avertissement |
| Worker à l'arrêt | captcha.worker.active == 0 |
Critique |
Créer le monitor via l'API Datadog
Voici l'alerte de solde bas au format attendu par l'API Datadog. Dupliquez le bloc pour chaque condition en ajustant query et message.
# Datadog monitor definition (API create)
- type: metric alert
name: "CaptchaAI Low Balance"
query: "avg(last_5m):avg:captcha.balance{*} < 10"
message: "CaptchaAI balance is low: {{value}}. Top up to avoid solve failures."
tags:
- team:scraping
- service:captcha
Dépannage
| Problème | Cause | Correctif |
|---|---|---|
| Les métriques n'apparaissent pas | L'agent DogStatsD ne tourne pas | Vérifiez DD_AGENT_HOST ; contrôlez docker ps pour le conteneur de l'agent |
| Histogramme de latence vide | Aucune résolution réussie n'a été suivie | Vérifiez que statsd.histogram() est bien appelé sur le chemin de réussite |
| Tags manquants | Mauvais format de tag | Utilisez le format key:value ; pas d'espaces dans les tags |
| Métriques dupliquées | Plusieurs rapporteurs tournent en parallèle | Ne gardez qu'un seul rapporteur de solde par déploiement |
FAQ
Par quelles métriques commencer si je débute ?
Commencez par trois : le taux d'erreur (captcha.solve.error rapporté à captcha.solve.count), la latence p95 et le solde. Elles répondent aux questions qui comptent — est-ce que ça marche, est-ce rapide, vais-je tomber en panne de crédit. Ajoutez la file d'attente et la santé des workers ensuite.
Comment fixer un seuil d'alerte de solde adapté ?
Le bon seuil dépend de votre volume, pas d'une valeur universelle. Réglez l'avertissement sur plusieurs jours de marge et le seuil critique sur quelques heures, pour réagir avant l'interruption. Le débit soutenable dépend aussi de votre plan — par exemple ADVANCE ($90/mois, 50 threads).
Datadog ou Prometheus pour surveiller un pipeline CAPTCHA ?
Les deux fonctionnent : DogStatsD pousse les métriques vers un agent, tandis que Prometheus les scrape depuis un endpoint exposé. Choisissez Datadog pour des alertes managées et une corrélation avec le reste de votre stack ; préférez Prometheus et Grafana si vous êtes déjà auto-hébergé et sensible au coût.
Comment éviter une facture Datadog qui explose ?
Datadog facture à la série temporelle, c'est-à-dire à chaque combinaison unique de nom et de tags. Les sept métriques ci-dessus, avec quelques valeurs de captcha_type, restent dans des limites raisonnables. Le piège classique : taguer par captcha_id ou par URL crée une série par tâche. Taguez par catégorie, jamais par identifiant unique.
Ces métriques marchent-elles pour reCAPTCHA v3 et Turnstile ?
Oui. L'instrumentation est indépendante du type résolu : passez le bon captcha_type au décorateur et vous suivez reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile et GeeTest v3 dans le même tableau de bord, filtrés par tag.
Articles connexes
- Construire un système de surveillance des avis avec CaptchaAI
- Créer un robot de veille des changements de contenu
- Mettre en place un tableau de bord de suivi d'utilisation CaptchaAI
Prochaines étapes
Donnez de la visibilité à votre pipeline CAPTCHA : créez votre clé API CaptchaAI puis connectez vos métriques à Datadog en quelques minutes.
Guides associés :
- Surveillance avec Prometheus et Grafana
- Tableau de bord d'utilisation CaptchaAI
- Gérer les erreurs de callback