DevOps & Scaling

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

CaptchaAI ardışık düzeniniz kesintiye uğradığında bunu önce siz mi fark ediyorsunuz, yoksa bir destek talebiyle mi öğreniyorsunuz? Datadog'a bağladığınız yedi metrikle çözüm oranını, gecikmeyi ve API bakiyesini gerçek zamanlı izler, sorun büyümeden önce uyarı alırsınız. Aşağıda DogStatsD entegrasyonundan hazır panel şablonuna ve kritik uyarı eşiklerine kadar üretime hazır bir kurulum var — kod örneklerini olduğu gibi kopyalayıp kendi ortam değişkenlerinizle çalıştırabilirsiniz.

Datadog'da Hangi CaptchaAI Metriklerini İzlemelisiniz?

Üretimde en az yedi metrik toplayın; bu set çözüm hattındaki çoğu arızayı büyümeden önce yakalamak için yeterlidir. İkiye ayırarak bakmak faydalı: birikimli sayaçlar/histogram ve o anki durumu gösteren ölçerler.

Sayaç ve Histogram Metrikleri

Metrik Tür Neden Önemli?
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

Ölçer (Gauge) Metrikleri

Metrik Tür Neden Önemli?
captcha.queue.depth Ölçer Kuyrukta bekleyen görevler
captcha.balance Ölçer Kalan API bakiyesi
captcha.worker.active Ölçer Aktif worker süreçleri

Yerel bağlam: İstanbul merkezli bir ajans için checkout QA botu ya da veri kazıma hattı işletiyorsanız, ortam etiketini env:tr-prod gibi sabit tutup saat dilimini Europe/Istanbul olarak ayarlamak, gece yarısı tetiklenen uyarıların hangi vardiyaya düştüğünü netleştirir. KVKK kapsamında etiketlere veya loglara kullanıcıya ait kişisel veri (ad, telefon, kimlik bilgisi vb.) eklemeyin — yalnızca teknik metrik ve durum bilgisi taşıyın.

Python ile Datadog Metrik Entegrasyonu

Aşağıdaki dekoratör her solve_recaptcha() çağrısını otomatik olarak sayar, süresini ölçer ve hata tipine göre etiketler:

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)

Node.js ile Datadog Metrik Entegrasyonu

Node.js tarafında hot-shots paketi aynı DogStatsD protokolünü konuşur; aşağıdaki örnek çözüm isteğini sarmalar ve bakiyeyi her dakika ayrı bir zamanlayıcıyla raporlar:

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

Hazır Datadog Kontrol Paneli Şablonu

Aşağıdaki JSON şablonunu Datadog'un panel oluşturucusuna içe aktararak dört widget'lı bir CaptchaAI izleme panosunu dakikalar içinde ayağa kaldırabilirsiniz:

{
  "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ı Eşiklerini Nasıl Belirlersiniz?

Aşağıdaki değerler, thread bazlı bir CaptchaAI planında tipik bir üretim iş yükü için başlangıç noktasıdır — trafik hacminize göre ayarlayın.

Eşik Tablosu

Uyarı Koşul Şiddet
Düşük bakiye captcha.balance < 10 Uyarı
Kritik bakiye captcha.balance < 2 Kritik
Yüksek hata oranı 5 dakika içinde hata oranı %10'u aşıyor Uyarı
Gecikme artışı p95 gecikmesi 10 dakika boyunca 120 saniyeyi aşıyor Uyarı
Kuyruk yedekleme Kuyruk derinliği 100'ün üzerinde ve 5 dakikadır artıyor Uyarı
Worker devre dışı captcha.worker.active == 0 Kritik

YAML ile Otomatik Tanım

Aşağıdaki YAML, düşük bakiye uyarısını Datadog Monitors API ile tanımlar:

# 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

  • Metrikler görünmüyor — Neden: DogStatsD ajanı çalışmıyor. Çözüm: DD_AGENT_HOST değerini doğrulayın; ajan konteyneri için docker ps komutunu kontrol edin.
  • Gecikme histogramı boş — Neden: Başarılı çözüm izlenmemiş. Çözüm: Başarı yolunda statsd.histogram() çağrısının yapıldığını kontrol edin.
  • Etiketler eksik — Neden: Yanlış etiket biçimi. Çözüm: key:value biçimini kullanın; etiketlerde boşluk olmasın.
  • Yinelenen metrikler — Neden: Birden fazla raporlama süreci aynı anda çalışıyor. Çözüm: Dağıtım başına yalnızca bir bakiye raporlayıcısı çalıştığından emin olun.

SSS

CaptchaAI bakiyesi için hangi uyarı eşiğini kullanmalıyım?

Çoğu ekip düşük bakiye eşiğini yaklaşık bir haftalık ortalama tüketime, kritik eşiği ise bir güne denk gelecek şekilde ayarlar. Yukarıdaki sabit < 10 / < 2 değerleri başlangıç için yeterlidir; asıl doğru eşik günlük çözüm hacminize bağlıdır.

Her worker için ayrı bir Datadog ajanı gerekir mi?

Hayır. Ana bilgisayar başına tek bir DogStatsD ajanı çalıştırmanız yeterlidir; o ana bilgisayardaki tüm worker süreçleri metrikleri aynı yerel ajana gönderir, ajan da bunları Datadog'un alım katmanına iletir.

Datadog özel metrik maliyeti ne kadar tutar?

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

Alarm yorgunluğunu (alert fatigue) nasıl önlerim?

Önce eşikleri gerçek trafiğinize göre kalibre edin, ardından yalnızca Kritik seviyedeki uyarıları anlık bildirime, Uyarı seviyesindekileri ise günlük özet kanalına yönlendirin. Bu ayrım, gece yarısı gelen düşük öncelikli bildirimleri azaltır.

Prometheus yerine Datadog'u ne zaman tercih etmeliyim?

Kendi izleme altyapınızı yönetmek istemiyorsanız ve hazır panel/uyarı arayüzüne öncelik veriyorsanız Datadog daha hızlı kurulur. Metrikleri kendi barındırdığınız bir yığında tutmak isterseniz makalenin sonundaki ilgili kılavuza bakın.

İlgili Makaleler

Konu Bağlantı
İnceleme izleme sistemi kurma CaptchaAI ile inceleme izleme sistemi kurma
İçerik değişikliği izleyen bot CaptchaAI ile içerik değişikliği izleyen bot kurma
Kullanım kontrol paneli CaptchaAI kullanım kontrol paneli kurma

Sonraki Adımlar

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

İlgili Kılavuzlar

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