Você não pode consertar o que não pode ver. O Datadog oferece visibilidade em tempo real do pipeline de resolução de CAPTCHA – taxas de resolução, percentis de latência, falhas de erros e alertas de anomalia que são acionados antes da interrupção do pipeline.
Principais métricas a serem rastreadas
| Métrica | Tipo | Por que é importante |
|---|---|---|
captcha.solve.count |
Contador | Total de tarefas enviadas |
captcha.solve.success |
Contador | Soluções bem-sucedidas |
captcha.solve.error |
Contador | Falha na resolução (por tipo de erro) |
captcha.solve.latency |
Histograma | Tempo desde o envio até a solução |
captcha.queue.depth |
Medidor | Tarefas pendentes na fila |
captcha.balance |
Medidor | Saldo restante da API |
captcha.worker.active |
Medidor | Processos de trabalho ativos |
Python — Integração 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 – Integração 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 };
JSON do painel Datadog
Importe este modelo JSON para o Datadog para criar um painel de monitoramento 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{*}"}]
}
}
]
}
Definições de alerta
| Alerta | Condição | Gravidade |
|---|---|---|
| Saldo baixo | captcha.balance < 10 |
Aviso |
| Equilíbrio crítico | captcha.balance < 2 |
Crítico |
| Alta taxa de erro | Taxa de erro > 10% em 5 minutos | Aviso |
| Pico de latência | latência p95 > 120s em 10 minutos | Aviso |
| Backup de fila | Profundidade da fila > 100 crescendo por 5 min | Aviso |
| Trabalhador 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
Solução de problemas
| Problema | Causa | Correção |
|---|---|---|
| Métricas não aparecem | Agente DogStatsD não está em execução | Verifique DD_AGENT_HOST; verifique docker ps para contêiner de agente |
| Histograma de latência vazio | Nenhuma solução bem-sucedida rastreada | Verifique se statsd.histogram() foi chamado no caminho de sucesso |
| Tags faltando | Formato de tag incorreto | Utilize o formato key:value; sem espaços nas tags |
| Métricas duplicadas | Vários repórteres correndo | Garanta apenas um relator de equilíbrio por implantação |
Perguntas frequentes
Preciso de um agente Datadog para cada trabalhador?
Execute um agente DogStatsD por host. Todos os trabalhadores nesse host enviam métricas para o agente local, que encaminha para a entrada do Datadog.
Quanto custam as métricas personalizadas do Datadog?
O Datadog cobra por série temporal de métricas personalizadas. As 7 métricas acima com algumas combinações de tags normalmente ficam dentro dos limites do nível gratuito. Verifique os preços do Datadog para saber os custos exatos.
Posso usar rastreamentos do Datadog APM em vez de métricas personalizadas?
Sim. Envolva sua função de resolução com ddtrace para obter rastreamento automático. No entanto, as métricas personalizadas oferecem mais controle sobre agregação e alertas.
Artigos relacionados
- Construir sistema de monitoramento de revisão Captchaai
- Construir bot de monitoramento de mudança de conteúdo Captchaai
- Construindo monitoramento do painel de uso do Captchaai
Próximas etapas
Obtenha observabilidade em seu pipeline CAPTCHA -comece com uma chave de API CaptchaAIe conecte-se ao Datadog.
Guias relacionados:
- Monitoramento Prometheus e Grafana
- Painel de uso
- Tratamento de erros de retorno de chamada