Tutorial

Data Time-Series untuk Tren Performa Solve CAPTCHA

Metrik titik waktu memberi tahu Anda apa yang terjadi saat ini. Data rangkaian waktu memberi tahu Anda apa yang berubah, kapan berubah, dan apakah sesuatu cenderung menimbulkan masalah. Lacak tingkat penyelesaian, latensi, dan biaya CAPTCHA dari waktu ke waktu untuk mengetahui degradasi sebelum berdampak pada pipeline Anda.

Apa yang Harus Dilacak

Metrik Ketik Mengapa
Tingkat penyelesaian (%) Pengukur Deteksi perubahan kualitas penyedia
Mengatasi latensi (ms) Histogram Temukan perlambatan, rencanakan timeout
Tingkat kesalahan berdasarkan kode Penghitung Identifikasi pola kesalahan yang muncul
Biaya per penyelesaian ($) Pengukur Pelacakan anggaran, deteksi anomali
Kedalaman antrian Pengukur Perencanaan kapasitas
Token expiry sebelum digunakan Penghitung Sinyal penyetelan TTL
saldo API Pengukur Isi ulang pemicu

Prometheus + Python (Gerbang Dorong)

Instrumen Pemecah Anda

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

Pertanyaan Prometheus

# 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])

MasuknyaDB + Python

Tulis Metrik Penyelesaian

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)

Kueri InfluxDB (Fluks)

// 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")

Implementasi JavaScript (Prometheus)

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

Perbandingan Basis Data

Fitur Prometheus masuknyaDB Skala waktuDB
Terbaik untuk Pemantauan operasional IoT / metrik berkardinalitas tinggi Analisis berbasis SQL
Bahasa kueri PromQL Fluks SQL
Retensi Berbasis konfigurasi Berbasis kebijakan Retensi PostgreSQL
Integrasi Grafana Asli Asli Asli
Kurva belajar Rendah Sedang Rendah (jika Anda tahu SQL)
Dihosting sendiri Ya Ya Ya (ekstensi PostgreSQL)

Pemecahan masalah

Masalah Sebab Perbaiki
Kesenjangan metrik di dashboard Gerbang dorong tidak menerima data Periksa jaringan antara solver dan push gateway
Histogram latensi menunjukkan persentil yang salah Batasan keranjang tidak sesuai dengan beban kerja Sesuaikan keranjang: [5, 10, 15, 20, 30, 45, 60, 90, 120] untuk penyelesaian CAPTCHA
Metrik biaya tidak sesuai dengan pembelanjaan sebenarnya Harga berbeda untuk setiap jenis CAPTCHA Tandai biaya berdasarkan jenis; gunakan harga per jenis yang sebenarnya
Terlalu banyak kardinalitas Terlalu banyak nilai label Batasi label pada type, status, error_code

Pertanyaan Umum

Basis data deret waktu manakah yang harus saya gunakan?

Prometheus jika Anda sudah memilikinya untuk pemantauan infrastruktur - cukup tambahkan metrik CAPTCHA. InfluxDB jika Anda menginginkan penyimpanan metrik mandiri. TimescaleDB jika Anda ingin kueri SQL pada data deret waktu.

Berapa lama saya harus mempertahankan metrik CAPTCHA?

Simpan data resolusi tinggi (per detik) selama 7 hari, data gabungan (per jam) selama 90 hari, dan ringkasan harian tanpa timeout. Hal ini menyeimbangkan biaya penyimpanan dengan visibilitas tren.

Bisakah saya mendeteksi penurunan tingkat penyelesaian secara otomatis?

Ya. Tetapkan peringatan pada rata-rata perputaran – misalnya, peringatan ketika tingkat keberhasilan 1 jam turun di bawah 90% atau ketika latensi P95 melebihi 45 detik. Peringatan Prometheus Alertmanager dan InfluxDB mendukung hal ini.

Langkah Selanjutnya

Lacak kinerja penyelesaian CAPTCHA Anda dari waktu ke waktu —dapatkan kunci API CaptchaAI Andadan mulai mengumpulkan metrik.

Panduan terkait:

Komentar dinonaktifkan untuk artikel ini.