Anda tidak bisa memperbaiki apa yang tidak bisa Anda lihat. Datadog memberi visibilitas real-time ke dalam pipeline solve CAPTCHA Anda — solve rate, latency percentile, breakdown error, dan alert anomali yang aktif sebelum pipeline rusak.
Metrik Utama yang Perlu Dilacak
| Metrik | Tipe | Mengapa Penting |
|---|---|---|
captcha.solve.count |
Counter | Total task yang di-submit |
captcha.solve.success |
Counter | Solve yang berhasil |
captcha.solve.error |
Counter | Solve yang gagal (per jenis error) |
captcha.solve.latency |
Histogram | Waktu dari submit hingga solusi |
captcha.queue.depth |
Gauge | Task yang pending dalam queue |
captcha.balance |
Gauge | Sisa saldo API |
captcha.worker.active |
Gauge | Worker process yang aktif |
Python – Integrasi 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 – Integrasi 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 };
Template Dashboard JSON Datadog
Import template JSON ini ke Datadog untuk membuat dashboard monitoring 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{*}"}]
}
}
]
}
Definisi Alert
| Alert | Kondisi | Severity |
|---|---|---|
| Saldo rendah | captcha.balance < 10 |
Warning |
| Saldo kritis | captcha.balance < 2 |
Critical |
| Error rate tinggi | Error rate > 10% selama 5 menit | Warning |
| Latency spike | p95 latency > 120 detik selama 10 menit | Warning |
| Queue menumpuk | Queue depth > 100 selama 5 menit | Warning |
| Worker down | captcha.worker.active == 0 |
Critical |
# 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
Pemecahan Masalah
| Masalah | Penyebab | Solusi |
|---|---|---|
| Metrik tidak muncul | DogStatsD agent tidak berjalan | Verifikasi DD_AGENT_HOST; cek docker ps untuk container agent |
| Histogram latency kosong | Tidak ada solve sukses yang terlacak | Periksa apakah statsd.histogram() dipanggil di jalur sukses |
| Tag hilang | Format tag salah | Gunakan format key:value; tidak ada spasi dalam tag |
| Metrik duplikat | Multiple reporter berjalan | Pastikan hanya satu balance reporter per deployment |
Pertanyaan Umum
Apakah saya perlu Datadog agent di setiap worker?
Jalankan satu DogStatsD agent per host. Semua worker di host tersebut mengirim metrik ke agent lokal, yang meneruskannya ke Datadog intake.
Berapa biaya custom metric Datadog?
Datadog mengenakan biaya per metric time series kustom. Tujuh metrik di atas dengan beberapa kombinasi tag biasanya masih dalam batas free tier. Cek harga Datadog untuk biaya pastinya.
Bisakah saya menggunakan Datadog APM tracing alih-alih custom metric?
Ya. Wrap fungsi solve Anda dengan ddtrace untuk mendapatkan tracing otomatis. Namun, custom metric memberi Anda kontrol lebih besar atas agregasi dan alert.
Artikel Terkait
- Dashboard Monitoring Penggunaan CaptchaAI
- Monitoring dengan Prometheus dan Grafana
- Pola Penanganan Error Callback CaptchaAI
Dapatkan observabilitas ke dalam pipeline CAPTCHA Anda — mulai dengan API key CaptchaAI dan hubungkan ke Datadog.