Tutorials

CAPTCHA Çözme Performans Trendleri için Zaman Serisi Verileri

Diyelim ki çözüm oranınız bu sabah %98'den %90'a indi. Peki bu düşüş ne zaman başladı — dün gece mi, yoksa on gün önce mi? Anlık bir panel bu soruyu yanıtlayamaz; yalnızca zaman serisi verisi yanıtlar. Çözüm oranını, gecikmeyi ve maliyeti zaman içinde kaydettiğinizde, bir bozulmayı üretim akışınıza yansımadan önce fark edersiniz. Bu rehber, bu geçmişi Prometheus, InfluxDB ve TimescaleDB ile nasıl toplayacağınızı çalışan örneklerle gösteriyor.

Hangi metrikleri izlemelisiniz?

İzlemeye değer metrikler ikiye ayrılır: sağlayıcı kalitesini yansıtanlar (çözüm oranı, gecikme) ve bütçeyi yansıtanlar (maliyet, bakiye). Aşağıdaki tablo her birini hangi metrik tipiyle toplayacağınızı özetler.

Metrik Tip Neden izlenir
Çözüm oranı (%) Gauge Sağlayıcı kalitesindeki değişiklikleri yakalar
Çözüm gecikmesi (ms) Histogram Yavaşlamaları görür, zaman aşımı eşiği belirler
Hata koduna göre hata oranı Counter Yeni beliren hata desenlerini ortaya çıkarır
Çözüm başına maliyet ($) Gauge Bütçe takibi, anormallik tespiti
Kuyruk derinliği Gauge Kapasite planlaması
Kullanılmadan süresi dolan token'lar Counter TTL ayarı için sinyal
API bakiyesi Gauge Yeniden yükleme tetiği

Hangi zaman serisi veritabanını seçmelisiniz?

Kod yazmadan önce nereye yazacağınıza karar verin. Üç seçenek de Grafana ile sorunsuz çalışır; fark sorgu diline ve altyapınızda zaten ne bulunduğuna iner. Operasyonel izleme için Prometheus, bağımsız bir metrik deposu için InfluxDB, tanıdık SQL için TimescaleDB mantıklı bir başlangıçtır.

Özellik Prometheus InfluxDB TimescaleDB
En uygun olduğu senaryo Operasyonel izleme IoT / yüksek kardinaliteli metrikler SQL tabanlı analiz
Sorgu dili PromQL Flux SQL
Saklama Yapılandırma tabanlı Politika tabanlı PostgreSQL saklama
Grafana entegrasyonu Yerleşik Yerleşik Yerleşik
Öğrenme eğrisi Düşük Orta Düşük (SQL biliyorsanız)
Kendi sunucunuzda barındırma Evet Evet Evet (PostgreSQL uzantısı)

Prometheus + Python ile metrik toplama (Push Gateway)

Kısa ömürlü çözüm işleri için Push Gateway en pratik yaklaşımdır: çözücünüz metriği bir aracıya iter, Prometheus oradan çeker. Böylece worker durduğunda metrik akışı kesilmez.

Çözücünüze ölçüm ekleyin

import os
import time
import requests
from prometheus_client import CollectorRegistry, Counter, Histogram, Gauge, push_to_gateway

registry = CollectorRegistry()

SOLVE_TOTAL = Counter(
    "captcha_solve_total", "Total CAPTCHA solve attempts",
    ["type", "status"], registry=registry
)
SOLVE_LATENCY = Histogram(
    "captcha_solve_latency_seconds", "CAPTCHA solve latency",
    ["type"], buckets=[5, 10, 15, 20, 30, 45, 60, 90, 120],
    registry=registry
)
SOLVE_COST = Counter(
    "captcha_solve_cost_dollars", "Total cost of CAPTCHA solves",
    ["type"], registry=registry
)
API_BALANCE = Gauge(
    "captcha_api_balance_dollars", "CaptchaAI account balance",
    registry=registry
)

API_KEY = os.environ["CAPTCHAAI_API_KEY"]
PUSHGATEWAY = os.environ.get("PUSHGATEWAY_URL", "localhost:9091")


def solve_with_metrics(sitekey, pageurl, captcha_type="recaptcha_v2"):
    start = time.time()

    resp = requests.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:
        SOLVE_TOTAL.labels(type=captcha_type, status="submit_error").inc()
        push_metrics()
        return {"error": data.get("request")}

    captcha_id = data["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get",
            "id": captcha_id, "json": 1
        }).json()

        if result.get("status") == 1:
            elapsed = time.time() - start
            SOLVE_TOTAL.labels(type=captcha_type, status="solved").inc()
            SOLVE_LATENCY.labels(type=captcha_type).observe(elapsed)
            SOLVE_COST.labels(type=captcha_type).inc(0.00299)
            push_metrics()
            return {"solution": result["request"]}

        if result.get("request") != "CAPCHA_NOT_READY":
            SOLVE_TOTAL.labels(type=captcha_type, status="error").inc()
            push_metrics()
            return {"error": result.get("request")}

    SOLVE_TOTAL.labels(type=captcha_type, status="timeout").inc()
    push_metrics()
    return {"error": "TIMEOUT"}


def push_metrics():
    try:
        push_to_gateway(PUSHGATEWAY, job="captcha_solver", registry=registry)
    except Exception:
        pass  # Don't fail solving because metrics push failed


def update_balance():
    resp = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "getbalance"
    })
    try:
        balance = float(resp.text)
        API_BALANCE.set(balance)
        push_metrics()
    except ValueError:
        pass

Prometheus sorguları

Trend görünürlüğünü sağlayan dört sorgu: saatlik başarı oranı, P95 gecikme, tipe göre hata oranı ve saatlik maliyet.

# Success rate over last hour
rate(captcha_solve_total{status="solved"}[1h])
/ rate(captcha_solve_total[1h]) * 100

# P95 solve latency
histogram_quantile(0.95, rate(captcha_solve_latency_seconds_bucket[1h]))

# Error rate by type
rate(captcha_solve_total{status="error"}[1h])

# Hourly cost
increase(captcha_solve_cost_dollars_total[1h])

InfluxDB + Python ile metrik yazma

Metrikleri bağımsız bir depoda tutmak isterseniz InfluxDB doğal seçenektir. Her çözümü ölçüm noktası olarak yazarsınız; etiketler filtrelemeyi, alanlar toplamayı kolaylaştırır.

Çözüm metriklerini yazın

from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS

INFLUX_URL = os.environ.get("INFLUX_URL", "http://localhost:8086")
INFLUX_TOKEN = os.environ.get("INFLUX_TOKEN", "")
INFLUX_ORG = os.environ.get("INFLUX_ORG", "captcha")
INFLUX_BUCKET = os.environ.get("INFLUX_BUCKET", "captcha_metrics")

influx_client = InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
write_api = influx_client.write_api(write_options=SYNCHRONOUS)


def record_solve_metric(captcha_type, status, elapsed_ms, cost=0.0, error=None):
    point = (
        Point("captcha_solve")
        .tag("type", captcha_type)
        .tag("status", status)
        .field("elapsed_ms", elapsed_ms)
        .field("cost", cost)
        .field("success", 1 if status == "solved" else 0)
    )
    if error:
        point = point.tag("error_code", error)
    write_api.write(bucket=INFLUX_BUCKET, record=point)


def record_balance(balance):
    point = Point("captcha_balance").field("balance", balance)
    write_api.write(bucket=INFLUX_BUCKET, record=point)

InfluxDB (Flux) sorguları

Aynı üç trendi Flux ile alırsınız: saatlik pencerelerde başarı oranı, tipe göre ortalama çözüm süresi ve kümülatif maliyet.

// Success rate over last 24 hours (1-hour windows)
from(bucket: "captcha_metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "captcha_solve" and r._field == "success")
  |> aggregateWindow(every: 1h, fn: mean)
  |> map(fn: (r) => ({r with _value: r._value * 100.0}))
  |> yield(name: "success_rate")

// Average solve time by type
from(bucket: "captcha_metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "captcha_solve" and r._field == "elapsed_ms" and r.status == "solved")
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1h, fn: mean)
  |> yield(name: "avg_latency")

// Cumulative cost
from(bucket: "captcha_metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "captcha_solve" and r._field == "cost")
  |> cumulativeSum()
  |> yield(name: "cumulative_cost")

JavaScript ile Prometheus entegrasyonu

Çözüm mantığınız Node.js tarafındaysa prom-client ile aynı sayaç ve histogramları tutar, /metrics uç noktasını açıp Prometheus'un çekmesine izin verirsiniz.

const client = require("prom-client");
const axios = require("axios");

const register = new client.Registry();
const API_KEY = process.env.CAPTCHAAI_API_KEY;

const solveTotal = new client.Counter({
  name: "captcha_solve_total",
  help: "Total CAPTCHA solve attempts",
  labelNames: ["type", "status"],
  registers: [register],
});

const solveLatency = new client.Histogram({
  name: "captcha_solve_latency_seconds",
  help: "CAPTCHA solve latency",
  labelNames: ["type"],
  buckets: [5, 10, 15, 20, 30, 45, 60, 90, 120],
  registers: [register],
});

async function solveWithMetrics(sitekey, pageurl, type = "recaptcha_v2") {
  const start = Date.now();

  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: { key: API_KEY, method: "userrecaptcha", googlekey: sitekey, pageurl, json: 1 },
  });

  if (submit.data.status !== 1) {
    solveTotal.inc({ type, status: "submit_error" });
    return { error: submit.data.request };
  }

  const captchaId = submit.data.request;

  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const poll = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: captchaId, json: 1 },
    });

    if (poll.data.status === 1) {
      const elapsed = (Date.now() - start) / 1000;
      solveTotal.inc({ type, status: "solved" });
      solveLatency.observe({ type }, elapsed);
      return { solution: poll.data.request };
    }

    if (poll.data.request !== "CAPCHA_NOT_READY") {
      solveTotal.inc({ type, status: "error" });
      return { error: poll.data.request };
    }
  }

  solveTotal.inc({ type, status: "timeout" });
  return { error: "TIMEOUT" };
}

// Expose metrics endpoint
const express = require("express");
const app = express();
app.get("/metrics", async (req, res) => {
  res.set("Content-Type", register.contentType);
  res.end(await register.metrics());
});
app.listen(9090);

Maliyet takibi ve thread bütçesi

Zaman serisi verisinin en somut faydası maliyet görünürlüğüdür. CaptchaAI thread tabanlı çalışır: ücreti çözüm başına değil, eş zamanlı thread sayısına göre ödersiniz ve her thread sınırsız çözüm içerir. BASIC planla ($15/ay, 5 thread) sabit bir bütçeyle çalışırsınız — Türk geliştiriciler için USD'nin öngörülebilir aylık maliyeti, kur dalgalanmasına karşı gerçek bir avantajdır. captcha_solve_cost_dollars ve captcha_api_balance_dollars metriklerini izleyerek harcamanın planınızla uyumlu gittiğini ve bakiyenin ne zaman yükleme gerektireceğini erkenden görürsünüz.

Sorun giderme

Sorun Sebep Düzeltme
Panelde metrik boşlukları Push Gateway veri almıyor Çözücü ile Push Gateway arasındaki ağ bağlantısını kontrol edin
Gecikme histogramı yanlış yüzdelik dilimler gösteriyor Kova sınırları iş yüküyle örtüşmüyor Kovaları CAPTCHA çözümü için [5, 10, 15, 20, 30, 45, 60, 90, 120] olarak ayarlayın
Maliyet metrikleri gerçek harcamayla tutmuyor CAPTCHA tipine göre fiyat farkı Maliyeti tipe göre etiketleyin; tip başına gerçek fiyatı kullanın
Kardinalite çok yüksek Fazla etiket değeri Etiketleri type, status, error_code ile sınırlayın

Sık sorulan sorular

Anlık metriklerle zaman serisi verisi arasındaki fark nedir?

Anlık metrik size şu andaki durumu söyler: çözüm oranı şu an %90. Zaman serisi verisi ise bu değerin nasıl bir eğri izlediğini gösterir — düşüş üç gün önce mi başladı, yoksa ani bir sıçrama mı? Trend olmadan bir tek ölçümün normal mi anormal mi olduğunu bilemezsiniz.

Push Gateway olmadan Prometheus kullanabilir miyim?

Evet. Uzun ömürlü bir servis çalıştırıyorsanız /metrics uç noktasını doğrudan açıp Prometheus'un çekmesine izin verebilirsiniz — JavaScript örneğindeki yaklaşım budur. Push Gateway asıl olarak, hızlıca başlayıp biten kısa ömürlü çözüm işleri için gerekir.

Çözüm oranı düştüğünde otomatik uyarı nasıl kurarım?

Sabit eşikler yerine hareketli ortalamalara uyarı bağlayın; örneğin 1 saatlik başarı oranı %90'ın altına indiğinde ya da P95 gecikmesi 45 saniyeyi aştığında tetiklenen bir kural yazın. Hem Prometheus Alertmanager hem de InfluxDB uyarıları bunu destekler.

Çözüm başına maliyeti metriklerde nasıl doğru tutarım?

Maliyeti tek bir sabit değere gömmeyin; her metriği CAPTCHA type etiketiyle işaretleyin ve tip başına gerçek fiyatı kullanın. Böylece bir tipteki hacim artışının toplam maliyeti nasıl kaydırdığını ayrıştırabilirsiniz.

Sonraki adımlar

Çözüm performansınızın zaman içindeki eğrisini görmek istiyorsanız, ilk adım metrikleri toplamaya başlamaktır — CaptchaAI API anahtarınızı alın ve çözücünüzü yukarıdaki örneklerle donatın.

İlgili rehberler:

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