Estado de Checks — LeadFlowAI
Monitoreo desde us-east-1, eu-west-1, ap-southeast-1 · Actualizado hace 47s
● Passing
187ms
Latencia P95
99.98%
Uptime 30d
us-east-1eu-west-1ap-se-1
● Passing
234ms
Latencia P95
100%
Uptime 30d
us-east-1eu-west-1ap-se-1
● Passing
312ms
Latencia P95
99.91%
Uptime 30d
us-east-1eu-west-1
⚠ Degraded
3.1s
Duración P95
99.6%
Uptime 30d
us-east-1eu-west-1ap-se-1
● Passing
4.8s
Duración P95
100%
Uptime 30d
us-east-1eu-west-1
● Deploy exitoso
✓ Build: 2m 34s
✓ Deploy Railway: 48s
✓ Deploy Vercel: 31s
✓ checkly test --record: 5/5 pass
commit 3fa8c12 · hace 2h · @maria.dev
Definición de Checks — monitoring-as-code
__checks__/ — versionado en git junto al código de aplicación
Código — Monitoring as Code
checkly.config.ts + checks TypeScript · versionados en el repo de LeadFlowAI
⚙️ checkly.config.ts
⚡ health.check.ts
📋 leads.check.ts
🖥️ login-flow.check.ts
🔄 deploy.yml
checkly.config.ts
✓ deployado
import { defineConfig } from "checkly"; import { EmailAlertChannel, SlackAlertChannel, PagerDutyAlertChannel } from "checkly/constructs"; // ── Canales de alerta ────────────────────────────────────────────────────── const slackAlert = new SlackAlertChannel("slack-alerts-prod", { webhookUrl: process.env.SLACK_WEBHOOK_URL!, channel: "#alerts-produccion", sendFailure: true, sendRecovery: true, sendDegraded: true, }); const emailAlert = new EmailAlertChannel("email-ops", { address: "ops@leadflowai.io", sendFailure: true, sendRecovery: true, sendDegraded: false, // Solo criticos por email }); const pagerAlert = new PagerDutyAlertChannel("pagerduty-critical", { serviceKey: process.env.PAGERDUTY_KEY!, sendFailure: true, // Solo fallos reales, no degraded sendRecovery: true, }); // ── Configuración global ──────────────────────────────────────────────────── export default defineConfig({ projectName: "LeadFlowAI Production", logicalId: "leadflowai-monitoring", repoUrl: "https://github.com/leadflowai/app", checks: { locations: ["us-east-1", "eu-west-1", "ap-southeast-1"], tags: ["production", "leadflowai"], runtimeId: "2024.02", alertChannels: [slackAlert, emailAlert, pagerAlert], apiChecks: { frequency: 1, // cada 1 minuto testMatch: "**/__checks__/api/**/*.check.ts", }, browserChecks: { frequency: 10, // cada 10 minutos testMatch: "**/__checks__/browser/**/*.check.ts", }, }, });
__checks__/api/leads.check.ts
setup + teardown scripts
import { ApiCheck, AssertionBuilder } from "checkly/constructs"; new ApiCheck("leads-create-cleanup", { name: "Leads API — Create + Cleanup", request: { method: "POST", url: "https://api.leadflowai.io/v2/leads", headers: [ { key: "Authorization", value: "Bearer {{MONITORING_API_KEY}}" }, { key: "Content-Type", value: "application/json" }, { key: "X-Test-Mode", value: "true" }, // no dispara workflows reales ], body: JSON.stringify({ email: "monitoring-test@leadflowai.io", name: "Checkly Monitor", source: "synthetic-check", }), assertions: [ AssertionBuilder.statusCode().equals(201), AssertionBuilder.jsonBody("$.id").isNotEmpty(), AssertionBuilder.jsonBody("$.status").equals("active"), AssertionBuilder.responseTime().lessThan(2000), ], }, degradedResponseTime: 1000, maxResponseTime: 4000, teardownScript: { content: ` // Limpiar el lead de prueba después de crearlo if (response.statusCode === 201) { const leadId = JSON.parse(response.body).id; await fetch(\`https://api.leadflowai.io/v2/leads/\${leadId}\`, { method: 'DELETE', headers: { 'Authorization': 'Bearer ' + process.env.MONITORING_API_KEY }, }); } `, }, });
__checks__/browser/login-flow.check.ts
⚠ Degraded — latencia 3.1s
import { test, expect } from "@playwright/test"; test("Flujo login LeadFlowAI", async ({ page }) => { // 1. Navegar a login await page.goto("https://app.leadflowai.io/login"); await expect(page.getByRole("heading", { name: "Accede a tu cuenta" })).toBeVisible(); // 2. Introducir credenciales de monitoreo await page.getByLabel("Email").fill(process.env.TEST_USER_EMAIL!); await page.getByLabel("Contraseña").fill(process.env.TEST_USER_PASSWORD!); await page.getByRole("button", { name: "Entrar" }).click(); // 3. Verificar dashboard cargado await expect(page).toHaveURL(/.*dashboard/, { timeout: 8000 }); await expect(page.getByRole("heading", { name: "Mis Campañas" })).toBeVisible(); // 4. Verificar widget de leads cargado (sin data real) await expect(page.getByTestId("leads-counter")).toBeVisible({ timeout: 5000 }); }); // ⚠ NOTA: Step 3 (dashboard heading) tardando 3.1s — umbral degraded: 2.5s // Investigar: posible N+1 query en /api/dashboard al cargar campañas // Ticket: https://github.com/leadflowai/app/issues/847
Pipeline CI/CD — GitHub Actions
Los checks se ejecutan como gate tras cada deploy a producción
git push
main
Build
npm run build
Deploy API
Railway
Deploy Web
Vercel
checkly test
--record
Notify
Slack + Email
Canales de Alerta Configurados
Escalado inteligente: degraded → Slack · fallos → Slack + Email + PagerDuty
Slack
#alerts-produccion
failure
recovery
degraded
Email
ops@leadflowai.io
failure
recovery
PagerDuty
Service: leadflowai-prod · escalado tras 3 fallos
failure
recovery
Eventos Recientes — Últimas 24h
API Checks
hace 2 min · us-east-1
API Health ✓ 187ms
hace 2 min · eu-west-1
Auth Login ✓ 234ms
hace 5 min · us-east-1
Leads Create ✓ 312ms
hace 6h · ap-southeast-1
Leads Create ✗ timeout 4.2s
hace 6h 3min · ap-southeast-1
Leads Create ✓ recovered 298ms
Browser Checks
hace 10 min · eu-west-1
Login Flow ⚠ degraded 3.1s
hace 20 min · us-east-1
Login Flow ⚠ degraded 2.9s
hace 10 min · eu-west-1
Crear Campaña ✓ 4.8s
hace 2h · todas las regiones
Deploy post-check ✓ 5/5 pass
Deploy Events
hace 2h · main@3fa8c12
checkly test 5/5 ✓ deploy ok
hace 1d · main@b2e91a4
checkly test 5/5 ✓ deploy ok
hace 2d · main@a1c88f0
checkly test 4/5 ✗ deploy bloqueado
hace 2d fix · main@c9f22a1
checkly test 5/5 ✓ deploy ok