DevOps & Mise à l'Échelle

Surveillance CaptchaAI avec New Relic : intégration APM

New Relic APM vous offre une visibilité de bout en bout sur la résolution de CAPTCHA, de la soumission d'API à la livraison de solutions. Suivez la latence des transactions, les pannes d'erreurs et les événements personnalisés qui correspondent directement à l'état de votre pipeline de résolution.

Que surveiller

[Submit Task] → [Wait for Solution] → [Apply Token]
     ↓                  ↓                   ↓
  Submit latency    Poll duration       Token usage
  API errors        Timeout rate        Success rate

Python – Nouvelle instrumentation personnalisée Relic

import os
import time
import requests
import newrelic.agent

API_KEY = os.environ["CAPTCHAAI_API_KEY"]
session = requests.Session()


@newrelic.agent.background_task(name="captcha_solve", group="CaptchaAI")
def solve_captcha(sitekey, pageurl, captcha_type="recaptcha_v2"):
    """Solve a CAPTCHA with full New Relic instrumentation."""
    # Add custom attributes for filtering
    newrelic.agent.add_custom_attributes([
        ("captcha_type", captcha_type),
        ("target_url", pageurl),
    ])

    # Submit phase
    submit_result = _submit_task(sitekey, pageurl, captcha_type)
    if "error" in submit_result:
        newrelic.agent.record_custom_event("CaptchaSolveError", {
            "error": submit_result["error"],
            "phase": "submit",
            "captcha_type": captcha_type,
        })
        return submit_result

    # Poll phase
    captcha_id = submit_result["captcha_id"]
    poll_result = _poll_result(captcha_id, captcha_type)

    # Record solve event
    event_data = {
        "captcha_type": captcha_type,
        "captcha_id": captcha_id,
        "success": "solution" in poll_result,
    }
    if "solution" in poll_result:
        event_data["solve_time"] = poll_result.get("elapsed", 0)
        newrelic.agent.record_custom_event("CaptchaSolveSuccess", event_data)
    else:
        event_data["error"] = poll_result.get("error", "unknown")
        newrelic.agent.record_custom_event("CaptchaSolveError", event_data)

    return poll_result


@newrelic.agent.function_trace(name="captcha_submit")
def _submit_task(sitekey, pageurl, captcha_type):
    payload = {
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": pageurl,
        "json": 1
    }
    resp = session.post("https://ocr.captchaai.com/in.php", data=payload)
    data = resp.json()

    newrelic.agent.add_custom_attributes([
        ("submit_status", data.get("status")),
    ])

    if data.get("status") != 1:
        return {"error": data.get("request")}
    return {"captcha_id": data["request"]}


@newrelic.agent.function_trace(name="captcha_poll")
def _poll_result(captcha_id, captcha_type):
    start = time.time()
    poll_count = 0

    for _ in range(60):
        time.sleep(5)
        poll_count += 1
        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:
            elapsed = time.time() - start
            newrelic.agent.add_custom_attributes([
                ("poll_count", poll_count),
                ("solve_time_seconds", round(elapsed, 2)),
            ])
            return {"solution": result["request"], "elapsed": elapsed}

        if result.get("request") != "CAPCHA_NOT_READY":
            return {"error": result.get("request")}

    return {"error": "TIMEOUT"}


def report_balance():
    """Record balance as a custom event."""
    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"])
        newrelic.agent.record_custom_event("CaptchaBalance", {
            "balance": balance,
            "low": balance < 10,
        })
        return balance
    return None

Nouvelle configuration de l'agent Relic

# newrelic.ini
[newrelic]
app_name = CaptchaAI Pipeline
license_key = YOUR_NEW_RELIC_LICENSE_KEY
monitor_mode = true
log_level = info
transaction_tracer.enabled = true
transaction_tracer.transaction_threshold = 5.0
custom_insights_events.enabled = true
custom_insights_events.max_samples_stored = 5000

JavaScript – Intégration de New Relic

const newrelic = require("newrelic");
const axios = require("axios");

const API_KEY = process.env.CAPTCHAAI_API_KEY;

async function solveCaptchaWithNewRelic(sitekey, pageurl, captchaType = "recaptcha_v2") {
  return newrelic.startBackgroundTransaction(
    "CaptchaSolve",
    "CaptchaAI",
    async () => {
      const transaction = newrelic.getTransaction();
      newrelic.addCustomAttributes({
        captchaType,
        targetUrl: pageurl,
      });

      const startTime = Date.now();

      try {
        // Submit
        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) {
          newrelic.recordCustomEvent("CaptchaSolveError", {
            error: submitResp.data.request,
            phase: "submit",
            captchaType,
          });
          transaction.end();
          return { error: submitResp.data.request };
        }

        const captchaId = submitResp.data.request;
        newrelic.addCustomAttributes({ captchaId });

        // Poll
        let pollCount = 0;
        for (let i = 0; i < 60; i++) {
          await new Promise((r) => setTimeout(r, 5000));
          pollCount++;

          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) {
            const elapsed = (Date.now() - startTime) / 1000;
            newrelic.recordCustomEvent("CaptchaSolveSuccess", {
              captchaType,
              solveTime: elapsed,
              pollCount,
            });
            newrelic.addCustomAttributes({
              solveTime: elapsed,
              pollCount,
            });
            transaction.end();
            return { solution: pollResp.data.request, elapsed };
          }

          if (pollResp.data.request !== "CAPCHA_NOT_READY") {
            newrelic.recordCustomEvent("CaptchaSolveError", {
              error: pollResp.data.request,
              phase: "poll",
              captchaType,
            });
            transaction.end();
            return { error: pollResp.data.request };
          }
        }

        newrelic.recordCustomEvent("CaptchaSolveError", {
          error: "TIMEOUT",
          phase: "poll",
          captchaType,
          pollCount,
        });
        transaction.end();
        return { error: "TIMEOUT" };
      } catch (err) {
        newrelic.noticeError(err);
        transaction.end();
        throw err;
      }
    }
  );
}

// Balance monitoring
async function monitorBalance() {
  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);
      newrelic.recordCustomEvent("CaptchaBalance", { balance });
    }
  } catch (err) {
    newrelic.noticeError(err);
  }
}

setInterval(monitorBalance, 60000);

module.exports = { solveCaptchaWithNewRelic };

Requêtes du tableau de bord NRQL

Créez un tableau de bord New Relic avec ces requêtes NRQL :

-- Solve success rate (last hour)
SELECT percentage(count(*), WHERE success = true)
FROM CaptchaSolveSuccess, CaptchaSolveError
SINCE 1 hour ago

-- Average solve time by CAPTCHA type
SELECT average(solveTime)
FROM CaptchaSolveSuccess
FACET captchaType
SINCE 1 hour ago TIMESERIES

-- Error breakdown
SELECT count(*)
FROM CaptchaSolveError
FACET error
SINCE 1 hour ago

-- P95 solve latency
SELECT percentile(solveTime, 95)
FROM CaptchaSolveSuccess
SINCE 1 hour ago TIMESERIES

-- Balance over time
SELECT latest(balance)
FROM CaptchaBalance
SINCE 24 hours ago TIMESERIES 5 minutes

-- Tasks per minute
SELECT rate(count(*), 1 minute)
FROM CaptchaSolveSuccess, CaptchaSolveError
SINCE 1 hour ago TIMESERIES

Politiques d'alerte

Alerte Condition NRQL Seuil
Faible taux de résolution SELECT percentage(count(*), WHERE success = true) < 85 % pendant 5 min
Latence élevée SELECT percentile(solveTime, 95) FROM CaptchaSolveSuccess > 120 s pendant 10 min
Solde faible SELECT latest(balance) FROM CaptchaBalance < 10 $
Pic d'erreur SELECT count(*) FROM CaptchaSolveError > 50 en 5 minutes

Dépannage

Problème Parce que Corriger
Les événements personnalisés n'apparaissent pas custom_insights_events.enabled est faux Activer dans newrelic.ini
Traces de transaction manquantes Seuil trop élevé Abaissez transaction_threshold à 1,0 s
Attributs tronqués Valeur trop longue Conserver les valeurs d'attribut sous 255 caractères
Aucune donnée après le déploiement Clé de licence incorrecte ou agent ne démarre pas Vérifiez newrelic-admin validate-config newrelic.ini

FAQ

New Relic APM vs événements personnalisés : quand les utiliser ?

APM auto-instrumente les appels HTTP et les requêtes de base de données. Les événements personnalisés vous fournissent des données spécifiques au CAPTCHA (temps de résolution, type de CAPTCHA, codes d'erreur). Utilisez les deux : APM pour la santé de l’infrastructure, événements personnalisés pour les mesures commerciales.

Comment puis-je corréler les résolutions CAPTCHA avec les transactions Web ?

Ajoutez le captcha_id en tant qu'attribut personnalisé à la tâche en arrière-plan CAPTCHA et à la transaction Web qui l'a déclenchée. Liez-les dans NRQL avec WHERE captchaId = '...'.

New Relic APM ajoute-t-il de la latence à la résolution de CAPTCHA ?

Négligeable. L'agent ajoute des microsecondes de surcharge par appel instrumenté. Les temps de résolution du CAPTCHA (5 à 120 secondes) rendent cela impossible à mesurer.

Articles connexes

Prochaines étapes

Obtenez une visibilité complète sur votre pipeline CAPTCHA –commencez avec une clé API CaptchaAIet connectez-vous à New Relic.

Guides associés :

  • Surveillance Datadog
  • Prométhée et Grafana
  • Tableau de bord d'utilisation
Les commentaires sont désactivés pour cet article.