DevOps ve Ölçeklendirme

Datadog ile CaptchaAI İzleme: Ölçümler ve Uyarılar

Göremediğiniz şeyi düzeltemezsiniz. Datadog size CAPTCHA çözüm ardışık düzeninize ilişkin gerçek zamanlı görünürlük sağlar; çözüm oranları, gecikme yüzdelikleri, hata dökümleri ve ardışık düzeniniz kesilmeden önce tetiklenen anormallik uyarıları.

İzlenecek Temel Metrikler

Metrik Tür Neden Önemlidir?
captcha.solve.count Sayaç Gönderilen toplam görevler
captcha.solve.success Sayaç Başarılı çözümler
captcha.solve.error Sayaç Başarısız çözümler (hata türüne göre)
captcha.solve.latency Histogram Gönderimden çözüme kadar geçen süre
captcha.queue.depth Ölçer Kuyrukta bekleyen görevler
captcha.balance Ölçer Kalan API bakiyesi
captcha.worker.active Ölçer Aktif çalışan süreçleri

Python – DogStatsD Entegrasyonu

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 – Datadog Entegrasyonu

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 };

Datadog Kontrol Paneli JSON

CAPTCHA izleme panosu oluşturmak için bu JSON şablonunu Datadog'a aktarın:

{
  "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{*}"}]
      }
    }
  ]
}

Uyarı Tanımları

uyarı Durum Şiddet
Düşük bakiye captcha.balance < 10 Uyarı
Kritik denge captcha.balance < 2 Kritik
Yüksek hata oranı 5 dakika içinde hata oranı > %10 Uyarı
Gecikme artışı p95 gecikmesi > 10 dakika boyunca 120 saniye Uyarı
Kuyruk yedekleme Kuyruk derinliği > 100, 5 dakika boyunca artıyor Uyarı
İşçi aşağı captcha.worker.active == 0 Kritik
# 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

Sorun giderme

Sorun Sebep Düzeltme
Metrikler görünmüyor DogStatsD aracısı çalışmıyor DD_AGENT_HOST'yi doğrulayın; ajan konteyneri için docker ps'yi kontrol edin
Gecikme histogramı boş Takip edilen başarılı çözüm yok Başarı yolunda statsd.histogram()'nin çağrıldığını kontrol edin
Etiketler eksik Yanlış etiket biçimi key:value biçimini kullanın; etiketlerde boşluk yok
Yinelenen metrikler Çok sayıda muhabir çalışıyor Dağıtım başına yalnızca bir denge raporlayıcısının olmasını sağlayın

SSS

Her çalışan için bir Datadog temsilcisine ihtiyacım var mı?

Ana bilgisayar başına bir DogStatsD aracısı çalıştırın. Bu ana bilgisayardaki tüm çalışanlar, Datadog'un alımına ileten yerel temsilciye metrikler gönderir.

Datadog özel metriklerinin maliyeti ne kadardır?

Datadog, özel metrik zaman serisi başına ücretlendirme yapar. Birkaç etiket kombinasyonuyla birlikte yukarıdaki 7 metrik genellikle ücretsiz katman sınırları dahilinde kalır. Kesin maliyetler için Datadog'un fiyatlandırmasını kontrol edin.

Özel ölçümler yerine Datadog APM izlemelerini kullanabilir miyim?

Evet. Otomatik izleme elde etmek için çözme işlevinizi ddtrace ile sarın. Ancak özel ölçümler, toplama ve uyarı verme konusunda size daha fazla kontrol sağlar.

İlgili Makaleler

Sonraki Adımlar

CAPTCHA ardışık düzeninize gözlemlenebilirlik kazandırın —CaptchaAI API anahtarıyla başlayınve Datadog'a bağlanın.

İlgili kılavuzlar:

Bu makale için yorumlar devre dışı bırakılmıştır.