Quando sua organização resolve milhares de CAPTCHAs diariamente, você precisa de um registro de cada solicitação. Os registros de auditoria respondem a perguntas como: Quem desencadeou esta solução? Para qual site era? Quanto custou? Quando isso aconteceu? Este guia mostra como implementar registros de auditoria abrangentes paraCaptchaAIoperações.
O que registrar
Cada solução CAPTCHA deve registrar:
| Campo | Objetivo | Exemplo |
|---|---|---|
timestamp |
Quando o pedido foi feito | 2026-04-04T14:30:00Z |
request_id |
Identificador exclusivo para esta solução | uuid4() |
captcha_type |
Método CAPTCHA usado | userrecaptcha |
target_site |
URL da página sendo resolvido | https://staging.example.com/qa-login |
task_id |
ID da tarefa CaptchaAI | 73829451 |
status |
Resultado | solved, failed, timeout |
solve_time_ms |
Tempo desde o envio até o resultado | 18432 |
error_code |
Erro se falhar | ERROR_CAPTCHA_UNSOLVABLE |
initiator |
Quem ou o que desencadeou a solução | scraper-job-42 |
cost |
Custo estimado | 0.003 |
Não registre: chaves de API, tokens CAPTCHA (eles são temporários) ou informações de identificação pessoal de sites de destino.
Implementação Python
# audit_solver.py
import os
import uuid
import time
import json
import logging
from datetime import datetime, timezone
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Configure audit logger — separate from application logs
audit_logger = logging.getLogger("captcha_audit")
audit_logger.setLevel(logging.INFO)
# File handler with rotation
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
"captcha_audit.jsonl",
maxBytes=50_000_000, # 50 MB per file
backupCount=10,
)
handler.setFormatter(logging.Formatter("%(message)s"))
audit_logger.addHandler(handler)
def log_audit(record):
"""Write a structured audit record."""
audit_logger.info(json.dumps(record, default=str))
def solve_with_audit(sitekey, pageurl, captcha_type="userrecaptcha",
initiator="unknown"):
"""Solve a CAPTCHA with full audit logging."""
request_id = str(uuid.uuid4())
start = time.time()
audit_record = {
"request_id": request_id,
"timestamp": datetime.now(timezone.utc).isoformat(),
"captcha_type": captcha_type,
"target_site": pageurl,
"initiator": initiator,
"status": "submitted",
}
session = requests.Session()
try:
# Submit
resp = session.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": captcha_type,
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
audit_record.update({
"status": "submit_failed",
"error_code": result.get("request"),
"solve_time_ms": int((time.time() - start) * 1000),
})
log_audit(audit_record)
return None
task_id = result["request"]
audit_record["task_id"] = task_id
# Poll
time.sleep(15)
for _ in range(25):
poll = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
solve_time = int((time.time() - start) * 1000)
audit_record.update({
"status": "solved",
"solve_time_ms": solve_time,
"cost_estimate": 0.003, # Adjust per your rate
})
log_audit(audit_record)
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
audit_record.update({
"status": "failed",
"error_code": poll_result.get("request"),
"solve_time_ms": int((time.time() - start) * 1000),
})
log_audit(audit_record)
return None
time.sleep(5)
audit_record.update({
"status": "timeout",
"solve_time_ms": int((time.time() - start) * 1000),
})
log_audit(audit_record)
return None
except Exception as e:
audit_record.update({
"status": "error",
"error_code": str(e)[:200],
"solve_time_ms": int((time.time() - start) * 1000),
})
log_audit(audit_record)
raise
# Usage
token = solve_with_audit(
sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
pageurl="https://www.google.com/recaptcha/api2/demo",
initiator="price-scraper-v2",
)
Saída do log de auditoria (formato JSONL)
{"request_id":"a1b2c3d4-...","timestamp":"2026-04-04T14:30:00+00:00","captcha_type":"userrecaptcha","target_site":"https://www.google.com/recaptcha/api2/demo","initiator":"price-scraper-v2","status":"solved","task_id":"73829451","solve_time_ms":18432,"cost_estimate":0.003}
Implementação de JavaScript
// audit_solver.js
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const axios = require('axios');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
const AUDIT_FILE = 'captcha_audit.jsonl';
function logAudit(record) {
fs.appendFileSync(AUDIT_FILE, JSON.stringify(record) + '\n');
}
async function solveWithAudit(sitekey, pageurl, initiator = 'unknown') {
const requestId = uuidv4();
const start = Date.now();
const record = {
request_id: requestId,
timestamp: new Date().toISOString(),
captcha_type: 'userrecaptcha',
target_site: pageurl,
initiator,
status: 'submitted',
};
try {
const submit = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) {
record.status = 'submit_failed';
record.error_code = submit.data.request;
record.solve_time_ms = Date.now() - start;
logAudit(record);
return null;
}
record.task_id = submit.data.request;
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: submit.data.request, json: '1' },
});
if (poll.data.status === 1) {
record.status = 'solved';
record.solve_time_ms = Date.now() - start;
record.cost_estimate = 0.003;
logAudit(record);
return poll.data.request;
}
if (poll.data.request !== 'CAPCHA_NOT_READY') {
record.status = 'failed';
record.error_code = poll.data.request;
record.solve_time_ms = Date.now() - start;
logAudit(record);
return null;
}
await new Promise(r => setTimeout(r, 5000));
}
record.status = 'timeout';
record.solve_time_ms = Date.now() - start;
logAudit(record);
return null;
} catch (e) {
record.status = 'error';
record.error_code = e.message.slice(0, 200);
record.solve_time_ms = Date.now() - start;
logAudit(record);
throw e;
}
}
Consultando registros de auditoria
Resumo Diário
import json
from collections import Counter
from datetime import date
def daily_summary(log_file, target_date=None):
"""Generate a daily summary from audit logs."""
target = target_date or date.today().isoformat()
statuses = Counter()
total_cost = 0
solve_times = []
with open(log_file) as f:
for line in f:
record = json.loads(line)
if record["timestamp"].startswith(target):
statuses[record["status"]] += 1
total_cost += record.get("cost_estimate", 0)
if record.get("solve_time_ms"):
solve_times.append(record["solve_time_ms"])
print(f"Date: {target}")
print(f"Total requests: {sum(statuses.values())}")
print(f"Statuses: {dict(statuses)}")
print(f"Estimated cost: ${total_cost:.2f}")
if solve_times:
print(f"Median solve time: {sorted(solve_times)[len(solve_times)//2]}ms")
daily_summary("captcha_audit.jsonl")
Retenção e armazenamento
| Volume | Tamanho do registro diário | Armazenamento mensal | Recomendação |
|---|---|---|---|
| 100 resolve/day | ~30KB | ~1MB | Arquivo local |
| 1.000 soluções/day | ~300KB | ~10 MB | Arquivo local + rotação |
| 10.000 soluções/day | ~3MB | ~100 MB | Enviar para agregador de log |
| 100.000 soluções/day | ~30 MB | ~1GB | Registro centralizado (ELK, Datadog) |
Solução de problemas
| Problema | Causa | Correção |
|---|---|---|
| Arquivo de log ficando muito grande | Nenhuma rotação configurada | Use RotatingFileHandler ou logrotate |
| Registros de auditoria ausentes | Exceção antes do log | Faça login no bloco finally |
| Gravações lentas em alto volume | Arquivo síncrono I/O | Use gravações de arquivo assíncronas ou buffer |
| Carimbos de data e hora inconsistentes | Desvio do relógio do sistema | Usar NTP; faça login em UTC |
Perguntas frequentes
Devo registrar o token CAPTCHA na trilha de auditoria?
Não. Os tokens são temporários (expiram em 60 a 300 segundos) e não têm valor de auditoria. Registra-los aumenta o armazenamento sem benefício.
Posso usar registros de auditoria para reconciliação de faturamento?
Sim. Compare os totais do seu registro de auditoria com o painel de uso do CaptchaAI para verificar a precisão do faturamento.
Que período de retenção devo definir?
90 dias é o padrão para logs de auditoria operacional. Para registros orientados à conformidade, verifique os requisitos do seu setor (SOC 2, GDPR, HIPAA).
Artigos relacionados
- Rastreamento de solução de captcha sem servidor Dynamodb
Próximas etapas
Adicione responsabilidade a cada solução CAPTCHA -obtenha sua chave API CaptchaAI.
Guias relacionados:
- Monitoramento do painel de uso
- Registro estruturado
- Verificação de saldo e recarga automática