Um Ihre CaptchaAI-Pipeline in Datadog zu überwachen, senden Sie vier Kennzahlen als eigene Metriken: Lösungsrate, Latenz, Fehlerrate und Guthaben. Aus diesen Metriken bauen Sie Dashboards und definieren Alerts, die anschlagen, bevor die Pipeline steht. Eine CAPTCHA-Pipeline fällt selten mit einem lauten Knall aus – sie wird langsam schlechter: Die Latenz steigt, die Erfolgsquote sinkt, und irgendwann ist das Guthaben leer, ohne dass jemand rechtzeitig hinsieht. Dieser Leitfaden zeigt die Instrumentierung in Python und Node.js, eine fertige Dashboard-Vorlage und die passenden Schwellenwert-Alerts.
Voraussetzungen
Bevor Metriken in Datadog auflaufen, brauchen Sie drei Dinge:
- Einen laufenden Datadog-Agent mit aktiviertem DogStatsD (UDP-Port 8125).
- Einen CaptchaAI-API-Schlüssel, hinterlegt als Umgebungsvariable
CAPTCHAAI_API_KEY. - Worker in Python oder Node.js, in die Sie die Instrumentierung einsetzen.
Steht diese Basis, senden die folgenden Beispiele ihre Werte an den lokalen Agent, der sie an die Datadog-Intake weiterreicht.
Die wichtigsten CaptchaAI-Metriken
Diese sieben Metriken decken die gesamte Pipeline ab – von der übermittelten Aufgabe bis zum verbleibenden Guthaben. Der Datadog-Metriktyp (Counter, Gauge, Histogram) bestimmt, wie Datadog den Wert aggregiert.
| Metrik | Typ | Wozu sie dient |
|---|---|---|
captcha.solve.count |
Counter | Gesamtzahl der übermittelten Aufgaben |
captcha.solve.success |
Counter | Erfolgreich gelöste CAPTCHAs |
captcha.solve.error |
Counter | Fehlgeschlagene Lösungen, aufgeschlüsselt nach Fehlertyp |
captcha.solve.latency |
Histogram | Dauer von der Übermittlung bis zur Lösung |
captcha.queue.depth |
Gauge | Offene Aufgaben in der Warteschlange |
captcha.balance |
Gauge | Verbleibendes API-Guthaben |
captcha.worker.active |
Gauge | Aktive Worker-Prozesse |
Ein typisches Szenario aus der Praxis: Ein Scraping-Team betreibt seine Worker auf mehreren Hetzner-Servern und startet den Guthaben-Check als Cron-Job in GitLab CI. Fällt die Erfolgsquote nachts unter den üblichen Bereich oder staut sich die Warteschlange, meldet Datadog das an den Bereitschaftsdienst, lange bevor am Morgen die ersten Aufträge auflaufen.
Metriken aus Python senden (DogStatsD)
Ein Decorator um Ihre Lösungsfunktion erledigt die Instrumentierung an einer einzigen Stelle: Er zählt jede Übermittlung, misst die Latenz erfolgreicher Lösungen und schlüsselt Fehler nach Typ auf. Das Guthaben senden Sie separat als Gauge.
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)
Der Tag captcha_type trennt reCAPTCHA v2, Cloudflare Turnstile und Bild-CAPTCHAs in denselben Metriken – so werten Sie später jeden Typ einzeln aus, ohne zusätzliche Metriknamen zu pflegen.
Metriken aus Node.js senden (hot-shots)
Für Node.js-Worker übernimmt die Bibliothek hot-shots denselben Job. Das prefix setzt den gemeinsamen Namensraum captcha., die globalen Tags kennzeichnen die Umgebung. Die Wrapper-Funktion zählt, misst und meldet Fehler analog zur Python-Variante.
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 };
Dashboard per JSON-Vorlage importieren
Sobald Metriken einlaufen, brauchen Sie eine Ansicht. Importieren Sie diese JSON-Vorlage in Datadog, um in einem Schritt ein CAPTCHA-Dashboard mit Lösungsrate, Latenzperzentilen, Guthaben und Warteschlangentiefe anzulegen:
{
"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{*}"}]
}
}
]
}
Alerts definieren
Ein Dashboard zeigt Probleme erst, wenn jemand hinschaut. Alerts holen Sie aktiv ab. Die folgenden sechs Regeln decken die häufigsten Ausfallmuster ab – vom leeren Guthaben bis zum ausgefallenen Worker.
| Alert | Bedingung | Schweregrad |
|---|---|---|
| Niedriges Guthaben | captcha.balance < 10 |
Warnung |
| Kritisches Guthaben | captcha.balance < 2 |
Kritisch |
| Hohe Fehlerquote | Fehlerquote > 10 % über 5 Minuten | Warnung |
| Latenzspitze | p95-Latenz > 120 Sekunden über 10 Minuten | Warnung |
| Warteschlangen-Rückstau | Warteschlangentiefe > 100, 5 Minuten steigend | Warnung |
| Worker ausgefallen | captcha.worker.active == 0 |
Kritisch |
Den Guthaben-Alert legen Sie direkt über die Datadog-Monitor-API an:
# 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
Fehlersuche
Die meisten Anlaufprobleme liegen an der Verbindung zum Datadog-Agent oder an falschen Tags – nicht an CaptchaAI selbst.
| Problem | Ursache | Lösung |
|---|---|---|
| Metriken erscheinen nicht in Datadog | API-Key fehlt oder statsd-Port nicht erreichbar |
Datadog-Agent-Status prüfen, UDP-Port 8125 freigeben |
| Latenz-Alerts erzeugen zu viele Fehlalarme | Schwellenwert zu niedrig für die normale Varianz | P95-Baseline über einige Tage messen, Schwellenwert entsprechend anheben |
| Dashboard zeigt keine Daten | Tag-Filter oder Metrikname falsch | Namen und Tags im Datadog-Metrics-Explorer prüfen |
| Alert löst nicht aus | Auswertungsfenster zu kurz | Fenster auf mindestens 5 Minuten setzen, rollup-Methode kontrollieren |
Häufige Fragen
Welche CaptchaAI-Metriken sollte ich zuerst überwachen?
Guthaben, Erfolgsquote und p95-Latenz. Diese drei zeigen am schnellsten, ob die Pipeline gesund ist: Ein leeres Guthaben stoppt jede Lösung, eine fallende Erfolgsquote deutet auf falsche Sitekeys oder ein Problem beim Anbieter hin, und steigende Latenz kündigt Engpässe an, bevor die Warteschlange überläuft.
Kann ich verschiedene CAPTCHA-Typen in Datadog getrennt auswerten?
Ja. Der Tag captcha_type im Beispielcode trennt reCAPTCHA v2, Cloudflare Turnstile und Bild-CAPTCHAs innerhalb derselben Metriken. In Dashboards und Alerts filtern oder gruppieren Sie dann per captcha_type:..., ohne zusätzliche Metriknamen anlegen zu müssen.
Wie vermeide ich Fehlalarme bei Latenz-Alerts?
Messen Sie zuerst eine Baseline. Beobachten Sie die p95-Latenz über einige Tage, setzen Sie den Schwellenwert deutlich darüber und werten Sie über ein Fenster von mindestens 5 Minuten aus – so löst ein einzelner Ausreißer keinen Alarm aus.
Warnt mich Datadog rechtzeitig vor leerem Guthaben?
Ja, über einen Schwellenwert-Alert auf captcha.balance. Ein zweistufiges Setup – Warnung unter 10, kritisch unter 2 – gibt Ihnen genug Vorlauf zum Aufladen, bevor die ersten Lösungen fehlschlagen.