Skip to main content

Runbook: Incidentes de Session Replay

Serviço afetado: webanalytics/ (SDK), events/ (ingest), backend/ (analytics), Cloudflare R2 (blob), ClickHouse (atlas.tbt_sdk_replay_events + atlas.mv_replay_sessions + atlas.audit_replay_views). Provider observability: New Relic — dashboard “Atlas — M8 Session Replay” + policy “Atlas — M8 Session Replay” (8 condições). Owner primário: SRE on-call. Escalation: Tech Lead Atlas → CTO.

Mapa de alertas → ação


1. DLQ rate alta

Sintoma: atlas.sdk-replay-snapshot-items.dlq recebendo > 10 mensagens/min. Significa que o Kafka producer no events/ está falhando para publicar metadata (R2 PutObject já passou — chunk está em R2, mas Gold MV não vai populá-lo). Diagnóstico:
Causas prováveis:
  • MSK broker queue cheio → revisar atlas_msk_kafka_data_logs_disk_used.
  • Schema drift entre producer e consumer (CH Kafka Engine columns mismatch).
  • Tópico não existe (atlas.sdk-replay-snapshot-items foi deletado).
Resolver:
  1. events/ logs: kubectl logs deploy/atlas-events -n stg --tail=200 | grep replay.
  2. Recriar tópico se ausente: make kafka-topics (em events/).
  3. Reconciliação manual de chunks órfãos (R2 sem CH): rodar scripts/reconcile_orphan_replay_chunks.sh (TODO Phase 2.5).
  4. Se persistir > 30min: rollback do producer commit + páginar Tech Lead.

2. R2 latência p99 alta

Sintoma: atlas_sdk_replay_r2_put_duration_seconds p99 > 5s. Diagnóstico:
Causas prováveis:
  • Incident Cloudflare (regional).
  • Rate-limit R2 (busy bucket — improvável).
  • ECS task events/ em CPU throttling → menos goroutines disponíveis para retry.
Resolver:
  1. Verificar https://www.cloudflarestatus.com.
  2. Se Cloudflare OK, escalar tasks events/ (CPU/memory) via Terraform.
  3. Se latência persistir mesmo após escalar: abrir ticket Cloudflare Support.
  4. Não há fallback automático para S3. SDK continua tentando — eventualmente o sender exponential backoff vai falhar e o chunk é perdido. Em incidente longo, considerar desabilitar replay temporariamente via env flag em events/ (CONFIG R2_BUCKET="" quebra o init e habilita o disabledReplayService que retorna 502 imediato — SDK descarta sem retry).

3. Tenant mismatch surge

Sintoma: > 5 ocorrências de replay_chunk_not_found com flag de tenant mismatch em 5 minutos. Indica possível tentativa de cross-org leakage. Diagnóstico:
Causas prováveis:
  • Bug benigno (frontend cachando old replay_id de outra brand).
  • Bot/scraper tentando IDs random.
  • Insider threat (compliance/CRM testando IDs de outras orgs).
Resolver:
  1. Cruzar actor_user_id com users table em Postgres — usuário legítimo?
  2. Se padrão suspeito (IDs sequenciais, alta taxa): suspender token via Auth0.
  3. Documentar incidente em Security/Incidents (PRP obrigatório).
  4. Se confirmado access scan, NÃO apenas suspender — preservar audit log por 365d (TTL atual) + extrair CSV para evidência.

4. Active sessions acima do baseline

Sintoma: atlas_sdk_replay_active_sessions > 10k em 5min. Não é incidente — é capacity planning. Resolver:
  1. Verificar custo R2 projetado: total_size_bytes / 86400 * 30 * 0.015 USD/mês.
  2. Se ultrapassar budget: reduzir sampleRate para 0.05 nos brands mais pesados via remote-config (Phase 2.5) ou patch SDK por brand.
  3. Considerar habilitar trigger.urlMatchRegex no SDK init para grandes brands (/(deposito|saque) reduz 60-90% storage).

5. Audit log failure rate

Sintoma: atlas_replay_audit_records_failed_total > 5/min. Diagnóstico:
Causas prováveis:
  • CH em backpressure (memory/CPU).
  • audit_replay_views table com TTL travado.
  • Network entre backend/ ECS e ClickHouse Cloud.
Resolver:
  1. INSERT falha é best-effort — não bloqueia o 200 do GET manifest. Impacto imediato = audit gap. Compliance não consegue auditar viewers.
  2. CH overload → escalar service em clickhouse-cloud-dashboard provisioning.
  3. Se persistir > 1h, escalar Tech Lead.

6. Marketing quota batida

Sintoma: ator marketing chegou em ≥ 50 views/dia (limite hardcoded Phase 2). Não é incidente — é signal de uso. Resolver:
  • Comportamento esperado: ator recebe 429 nos próximos GETs.
  • Se padrão recorrente, abrir ticket Product para considerar quota maior.
  • NÃO aumentar quota ad-hoc — Phase 2.5 vai mover para backoffice config.

7. Ingest 429 spike

Sintoma: outcome="rejected_ratelimit" rate > 20/min. SDK está sendo throttled pelo rate-limit per replay_id (12 chunks/min default). Causas prováveis:
  • SDK bug — sender entrou em retry loop sem backoff.
  • Cliente final em rede flaky → retries normais
  • Operador customizando intervalo de chunk para muito agressivo.
Resolver:
  1. Inspecionar SDK no browser de teste (DevTools Network → ver intervalo entre POSTs):
  2. Se intervalo < 5s: bug do SDK (REPLAY_BATCH_FLUSH_MS = 10s default).
  3. Se intervalo > 5s mas spike de 429: muitos replays simultâneos no mesmo replay_id — improvável; investigar collision de IDs.

8. Bundle gzip acima do gate

Sintoma: atlas_sdk_replay_bundle_size_bytes_gzipped > 65 KB. Informativo — CI já bloqueia merges via npm run size:replay. Resolver:
  1. Verificar último commit no webanalytics/ que ultrapassou.
  2. Reverter ou otimizar:
    • Remove dependências não-tree-shakeable.
    • Tightening terser passes.
    • Switch para CompressionStream se ainda usando pako (já default em Wp-37).

Operações manuais

Purge LGPD (direito ao esquecimento)

Reconciliação chunks órfãos (R2 sem CH)

Acontece quando R2 PutObject sucede mas Kafka publish falha (e o DLQ também não recupera). Result: blob em R2 sem metadata no Gold MV.
Em Phase 2 não há reconciliation automática. Phase 2.5 vai shippar: scripts/reconcile_orphan_replay_chunks.go que lê os arquivos e injeta metadata reconstruída em CH.

Rollback emergencial (vazamento PII)