No puedes arreglar lo que no puedes ver. Datadog le brinda visibilidad en tiempo real de su proceso de resolución de CAPTCHA: tasas de resolución, percentiles de latencia, desgloses de errores y alertas de anomalías que se activan antes de que se rompa el proceso.
Métricas clave para realizar un seguimiento
| Métrica | Tipo | Por qué es importante |
|---|---|---|
captcha.solve.count |
Contador | Total de tareas enviadas |
captcha.solve.success |
Contador | Resoluciones exitosas |
captcha.solve.error |
Contador | Resoluciones fallidas (por tipo de error) |
captcha.solve.latency |
histograma | Tiempo desde el envío hasta la solución |
captcha.queue.depth |
Calibre | Tareas pendientes en cola |
captcha.balance |
Calibre | Saldo API restante |
captcha.worker.active |
Calibre | Procesos de trabajadores activos |
Python: integración de DogStatsD
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)
JavaScript: integración de Datadog
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 };
Panel de control JSON de Datadog
Importe esta plantilla JSON a Datadog para crear un panel de monitoreo CAPTCHA:
{
"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{*}"}]
}
}
]
}
Definiciones de alerta
| Alerta | Condición | Gravedad |
|---|---|---|
| saldo bajo | captcha.balance < 10 |
Advertencia |
| equilibrio crítico | captcha.balance < 2 |
Crítico |
| Alta tasa de error | Tasa de error > 10 % en 5 minutos | Advertencia |
| Pico de latencia | Latencia p95 > 120 s durante 10 minutos | Advertencia |
| copia de seguridad de cola | Profundidad de cola > 100 creciendo durante 5 min | Advertencia |
| Trabajador caído | captcha.worker.active == 0 |
Crítico |
# 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
Solución de problemas
| Problema | causa | Solución |
|---|---|---|
| Las métricas no aparecen | El agente DogStatsD no se ejecuta | Verificar DD_AGENT_HOST; marque docker ps para el contenedor del agente |
| Histograma de latencia vacío | No se han realizado seguimientos de soluciones exitosas | Compruebe que se llame a statsd.histogram() en la ruta exitosa |
| Faltan etiquetas | Formato de etiqueta incorrecto | Utilice el formato key:value; sin espacios en las etiquetas |
| Métricas duplicadas | Varios reporteros corriendo | Asegúrese de que solo haya un reportero de saldo por implementación |
Preguntas frecuentes
¿Necesito un agente de Datadog para cada trabajador?
Ejecute un agente DogStatsD por host. Todos los trabajadores de ese host envían métricas al agente local, que las reenvía a la entrada de Datadog.
¿Cuánto cuestan las métricas personalizadas de Datadog?
Cargos de Datadog por serie temporal de métricas personalizadas. Las 7 métricas anteriores con algunas combinaciones de etiquetas generalmente se mantienen dentro de los límites del nivel gratuito. Consulte los precios de Datadog para conocer los costos exactos.
¿Puedo utilizar seguimientos de Datadog APM en lugar de métricas personalizadas?
Sí. Envuelva su función de resolución con ddtrace para obtener un seguimiento automático. Sin embargo, las métricas personalizadas le brindan más control sobre la agregación y las alertas.
Artículos relacionados
- Construir sistema de monitoreo de revisión Captchaai
- Crea un bot de monitoreo de cambios de contenido con CaptchaAI
- Panel de uso de CaptchaAI
Conecta CaptchaAI a Datadog
Obtén visibilidad en tu pipeline CAPTCHA: empieza con una clave API CaptchaAI y conectáte a Datadog.
Guías relacionadas:
- Monitoreo con Prometheus y Grafana
- Panel de uso de CaptchaAI
- Manejo de errores en callbacks