DevOps và Mở Rộng

Giám sát CaptchaAI với Datadog: Số liệu và Cảnh báo

Bạn không thể sửa chữa những gì bạn không thể nhìn thấy. Datadog cung cấp cho bạn khả năng hiển thị theo thời gian thực về quy trình giải CAPTCHA của bạn — tỷ lệ giải quyết, phần trăm độ trễ, phân tích lỗi và cảnh báo bất thường phát ra trước khi quy trình của bạn bị hỏng.

Các số liệu chính cần theo dõi

Số liệu loại Tại sao nó quan trọng
captcha.solve.count quầy Tổng số nhiệm vụ đã gửi
captcha.solve.success quầy Giải quyết thành công
captcha.solve.error quầy Giải quyết không thành công (theo loại lỗi)
captcha.solve.latency biểu đồ Thời gian từ khi gửi đến khi giải quyết
captcha.queue.depth Máy đo Nhiệm vụ đang chờ xử lý trong hàng đợi
captcha.balance Máy đo Số dư API còn lại
captcha.worker.active Máy đo Quy trình công nhân tích cực

Python – Tích hợp 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 – Tích hợp 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 };

Bảng điều khiển dữ liệu JSON

Nhập mẫu JSON này vào Datadog để tạo bảng thông tin giám sát 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{*}"}]
      }
    }
  ]
}

Định nghĩa cảnh báo

Cảnh báo tình trạng Mức độ nghiêm trọng
Số dư thấp captcha.balance < 10 Cảnh báo
Cân bằng quan trọng captcha.balance < 2 Quan trọng
Tỷ lệ lỗi cao Tỷ lệ lỗi > 10% trong 5 phút Cảnh báo
Độ trễ tăng đột biến độ trễ p95 > 120 giây trong 10 phút Cảnh báo
Sao lưu hàng đợi Độ sâu hàng đợi > 100 tăng dần trong 5 phút Cảnh báo
Công nhân xuống captcha.worker.active == 0 Quan trọng
# 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

Khắc phục sự cố

Vấn đề Nguyên nhân Cách xử lý
Số liệu không xuất hiện Tác nhân DogStatsD không chạy Xác minh DD_AGENT_HOST; kiểm tra docker ps để tìm thùng chứa đại lý
Biểu đồ độ trễ trống Không có giải pháp thành công nào được theo dõi Kiểm tra xem statsd.histogram() có được gọi trên đường dẫn thành công không
Thiếu thẻ Định dạng thẻ sai Sử dụng định dạng key:value; không có dấu cách trong thẻ
Số liệu trùng lặp Nhiều phóng viên chạy Đảm bảo chỉ có một báo cáo số dư cho mỗi lần triển khai

Câu hỏi thường gặp

Tôi có cần tác nhân Datadog cho mỗi công nhân không?

Chạy một tác nhân DogStatsD trên mỗi máy chủ. Tất cả nhân viên trên máy chủ đó gửi số liệu đến đại lý địa phương, đại lý này sẽ chuyển tiếp dữ liệu tiếp nhận của Datadog.

Số liệu tùy chỉnh của Datadog có giá bao nhiêu?

Tính phí Datadog cho mỗi chuỗi thời gian số liệu tùy chỉnh. 7 chỉ số ở trên cùng với một số kết hợp thẻ thường nằm trong giới hạn cấp miễn phí. Kiểm tra giá của Datadog để biết chi phí chính xác.

Tôi có thể sử dụng dấu vết APM của Datadog thay vì số liệu tùy chỉnh không?

Vâng. Kết hợp chức năng giải của bạn với ddtrace để tự động theo dõi. Tuy nhiên, số liệu tùy chỉnh cung cấp cho bạn nhiều quyền kiểm soát hơn đối với việc tổng hợp và cảnh báo.

bài viết liên quan

Các bước tiếp theo

Đưa khả năng quan sát vào quy trình CAPTCHA của bạn —bắt đầu với khóa API CaptchaAIvà kết nối với Datadog.

Hướng dẫn liên quan:

Os comentários estão desativados para este artigo.