Monitoring as Code
Monitoring as Code te permite definir tu configuración de monitoreo de LoadFocus como archivos versionados y aplicarla desde la línea de comandos o CI, igual que gestionas la infraestructura con Terraform o Pulumi. Describes los monitores, grupos, alertas, ventanas de mantenimiento, paneles y páginas de estado que quieres; la CLI @loadfocus/monitoring calcula la diferencia con lo que está en producción y la reconcilia (crear, actualizar, eliminar).
Es declarativa e idempotente: ejecutar deploy dos veces no cambia nada la segunda vez. Tus archivos son la fuente de verdad, así que los cambios pasan por pull requests y el historial de tu monitoreo vive en git.
Todo se ejecuta dentro de tu cuenta y tu equipo activo, con los límites de tu plan aplicados por el backend de LoadFocus exactamente igual que en el panel. La CLI solo hace lo que tú mismo podrías hacer en la interfaz.
Cómo funciona
Sección titulada «Cómo funciona»Mantienes una carpeta de archivos YAML (o JavaScript) pequeños (un recurso por archivo) más un loadfocus.config.yaml que apunta a ellos. La CLI envía esas definiciones a LoadFocus, que las mapea a recursos en producción, las compara y devuelve un plan. Revisas el plan y luego lo aplicas.
- Escribe: describe los recursos como archivos (constructos YAML o JS).
- Planifica:
deploy --dry-runmuestra exactamente qué se va a crear, actualizar, adoptar o eliminar. - Aplica:
deployreconcilia tu cuenta para que coincida con los archivos. - Reconcilia la identidad: cada recurso lleva un
logicalIdestable que tú eliges. Así es como la CLI rastrea un recurso a través de los cambios de nombre, de modo que cambiar el nombre visible de una comprobación nunca la recrea.
Instalación
Sección titulada «Instalación»La CLI es un paquete de Node (Node 18+). Ejecútala bajo demanda con npx:
npx @loadfocus/monitoring --help…o instálala globalmente para obtener el comando loadfocus-monitoring:
npm install -g @loadfocus/monitoringloadfocus-monitoring --helpAutenticación
Sección titulada «Autenticación»La CLI se autentica con una clave de API de LoadFocus y un id de equipo. Encontrarás ambos en la página de desarrolladores, que muestra tu clave de API y tu id de equipo juntos, junto con la configuración de MCP.
Inicia sesión una vez y las credenciales se guardan en ~/.loadfocus/config.json:
loadfocus-monitoring login --apikey <your-api-key> --teamid <your-team-id>loadfocus-monitoring whoami # confirm who you are and which team you're targetingPara CI, prefiere las variables de entorno (anulan la configuración guardada y nunca tocan el disco):
export LOADFOCUS_API_KEY="apikey_xxxxxxxx"export LOADFOCUS_TEAM_ID="team_xxxxxxxx"# optional: export LOADFOCUS_API_URL="https://apimonitor.loadfocus.com"Para cambiar más tarde un valor guardado, usa config set con --apikey, --teamid o --api-url. config show muestra las credenciales que la CLI usa realmente, incluidas las variables de entorno, con la clave de API enmascarada salvo sus cuatro últimos caracteres. logout elimina de ~/.loadfocus/config.json la clave de API y el id de equipo guardados.
loadfocus-monitoring config set --teamid <your-team-id> # change one saved valueloadfocus-monitoring config show # credentials in use, API key maskedloadfocus-monitoring logout # remove the saved API key and team idCrear un proyecto
Sección titulada «Crear un proyecto»Genera un archivo de configuración y un monitor de ejemplo en tu repositorio:
loadfocus-monitoring initEsto escribe loadfocus.config.yaml:
project: my-project # a namespace for this set of resourcescheckMatch: - "monitors/**/*.{check,group,alertRule,maintenanceWindow,dashboard,statusPage,alertChannel,variable}.{yaml,yml,js}"defaults: schedule: "300" # applied to checks that omit a schedule locations: [us-east-1]projectdelimita todo lo que la CLI gestiona. Los recursos de un proyecto se reconcilian juntos; cualquier cosa del proyecto que ya no esté en tus archivos se elimina endeploy. Usa proyectos separados para gestionar conjuntos independientes de monitores.checkMatches el glob (o los globs) de tus archivos de autoría.defaultsrellenanschedule,locationsyalertChannelspara las comprobaciones que los omiten.
init omite los archivos que ya existen. Añade --force para sobrescribirlos.
El flujo de trabajo
Sección titulada «El flujo de trabajo»loadfocus-monitoring validate # compile locally + server-side dry-run; great as a PR gateloadfocus-monitoring deploy --dry-run # show the plan (created / updated / adopted / deleted)loadfocus-monitoring deploy # apply itloadfocus-monitoring list # inventory of what's deployed in the projectloadfocus-monitoring list --status # …with each check's latest up/down/degraded statusloadfocus-monitoring get <logicalId> # show one deployed resourceloadfocus-monitoring trigger --id <logicalId> # run a check now (no --id runs every deployed check)loadfocus-monitoring destroy # delete everything managed in the projectdeploy es seguro por defecto: muestra el plan y, cuando se ejecuta de forma interactiva, pregunta antes de eliminar nada. En CI (no interactivo), se niega a eliminar sin --yes y termina con un código claro en lugar de quedarse colgado en un prompt. Añade --json a los comandos de lectura/resultado para una salida legible por máquina.
validate --no-server solo compila tus archivos en local: no necesita credenciales y omite la simulación en el servidor, así que sirve como hook de pre-commit. Además, deploy se niega a aplicar un proyecto cuyo checkMatch no carga ningún archivo, porque ese plan eliminaría todos los recursos que gestiona el proyecto; casi siempre se debe a una carpeta equivocada o a una errata en checkMatch. deploy --dry-run sigue mostrando ese plan. Para eliminarlo todo a propósito, ejecuta destroy o pasa --allow-empty a deploy.
Probar las comprobaciones sin desplegar
Sección titulada «Probar las comprobaciones sin desplegar»loadfocus-monitoring testloadfocus-monitoring test --json # machine-readable resultstest ejecuta una vez cada comprobación de tus archivos, directamente desde ellos, e indica si cada una pasa o falla. No se guarda nada: no se crea ni se modifica ninguna comprobación en tu cuenta. Termina con el código 1 cuando alguna comprobación falla o da error, de modo que un job de CI puede bloquear un pull request hasta que las comprobaciones pasen contra los endpoints reales; un resultado degradado no hace fallar la ejecución. Los proyectos con muchas comprobaciones se envían en lotes de 20.
Adoptar monitores existentes
Sección titulada «Adoptar monitores existentes»¿Ya tienes monitores en el panel? Impórtalos a archivos en lugar de recrearlos:
loadfocus-monitoring import --project my-project --out monitorsEsto escribe un archivo por recurso y un loadfocus.config.yaml. Revisa, haz commit y luego ejecuta deploy --dry-run: los recursos coincidentes se adoptan en su lugar (quedan bajo gestión) en vez de duplicarse.
import omite los archivos que ya existen en la carpeta de salida. Añade --force para sobrescribirlos con la versión del servidor.
Recursos
Sección titulada «Recursos»Cada recurso es un archivo con un kind, un logicalId (tu identificador estable) y los campos de ese kind. Las referencias entre recursos usan logicalIds (o nombres para los canales de alerta); el servidor las resuelve y el orden de despliegue se gestiona por ti.
Comprobaciones
Sección titulada «Comprobaciones»Un único kind check cubre todos los tipos de comprobación mediante type: api, browser, multistep, tcp, heartbeat (en JavaScript, el constructo Monitor hace lo mismo).
kind: checktype: apilogicalId: homename: Home APIschedule: "300" # seconds between runslocations: [us-east-1, eu-west-1]tags: [production, payments] # optional labelsrequest: url: "https://example.com/health" method: GETassertions: - { type: statusCode, comparison: equals, value: 200 } - { type: responseTime, comparison: less-than, value: 1000 }- api: petición HTTP con aserciones sobre código de estado, tiempo de respuesta y cuerpo. Las comparaciones son
equals,not-equals,greater-than,less-than,equals-or-greater-than,equals-or-less-than,containsynot-contains. - browser: un script de flujo de usuario de Playwright con capturas de pantalla y tiempos por paso (de pago).
- multistep: una secuencia ordenada de peticiones de API que pasan datos entre pasos (de pago).
- tcp: una comprobación de puerto/alcanzabilidad desde varias regiones (de pago).
- heartbeat: un interruptor de hombre muerto: un trabajo externo hace ping a una URL según una programación, y LoadFocus alerta si falta un ping.
Una comprobación también puede llevar tags, las mismas etiquetas que pones junto al nombre de la verificación en la aplicación (consulta etiquetas de las verificaciones). Si despliegas un archivo de comprobación sin tags, esa comprobación pierde sus etiquetas. En JavaScript, el constructo Monitor conserva tags desde la versión 1.0.2 de la CLI; las versiones anteriores las descartaban.
Comparte ubicaciones, canales de alerta, frecuencia y activación entre muchas comprobaciones. Una comprobación se une a un grupo con group: <logicalId>.
kind: grouplogicalId: webname: Web serviceslocations: [us-east-1, eu-west-1]Reglas de alerta
Sección titulada «Reglas de alerta»Alerta cuando la métrica de una comprobación cruza un umbral.
kind: alertRulelogicalId: home-latencyname: Home API latencycheck: home # reference a check by logicalIdmetric: responseTime # responseTime | statusCode | durationcondition: aboveconditionValue: 1500 # millisecondsCanales de alerta
Sección titulada «Canales de alerta»Gestiona los canales de notificación como código y referéncialos por nombre desde una comprobación, grupo o regla de alerta. Tipos (type) admitidos: email, slack, microsoftteams, webhook, discord, pagerduty, opsgenie. Los canales de email, Slack, Teams y webhook están en todos los planes; Discord, PagerDuty y Opsgenie son solo de pago. Los campos secretos (webhookUrl, routingKey, apiKey) toman una referencia {{secrets.NAME}}: el valor se almacena con env set-secret y se resuelve al enviar una alerta, nunca se incluye en tus archivos.
kind: alertChannellogicalId: oncall # the name checks / groups / alert rules referencetype: pagerdutyroutingKey: "{{secrets.PAGERDUTY_KEY}}"Ventanas de mantenimiento
Sección titulada «Ventanas de mantenimiento»Suprime las alertas durante el trabajo planificado. Las horas son UTC. startsAt / endsAt aceptan una cadena ISO-8601 (por ejemplo, "2026-07-01T00:00:00Z") o milisegundos unix.
kind: maintenanceWindowlogicalId: weekly-deployname: Weekly deploy windowenabled: truestartsAt: "2026-07-01T00:00:00Z" # ISO-8601 or unix msendsAt: "2026-07-01T02:00:00Z"repeat: weekly # none | daily | weekly | monthlyweekdays: [2] # 0=Sun … 6=Sattargets: allChecks: false checkIds: [home] # by logicalIdPaneles
Sección titulada «Paneles»Una vista compartida de comprobaciones seleccionadas, opcionalmente publica mediante un slug.
kind: dashboardlogicalId: status-overviewname: Status overviewvisibility: private # private | publicchecks: [home] # by logicalIdwindow: 24h # 24h | 7d | 30dPáginas de estado
Sección titulada «Páginas de estado»Una página de estado publica en <slug>.loadfoc.us, opcionalmente en tu propio dominio personalizado.
kind: statusPagelogicalId: public-statustitle: Acme Statusslug: acme # -> acme.loadfoc.us (globally unique)enabled: truecustomDomain: status.acme.com # optional, paid; point a CNAME at cname.loadfoc.usgroups: - { id: core, name: Core Services, order: 0 }components: - id: api name: API groupId: core monitors: [home] # checks shown on this component, by logicalIdbranding: brandColor: "#5353a4" colorTheme: darkUn dominio personalizado entra en funcionamiento una vez que creas el CNAME y se emite el certificado: deploy lo declara; la verificación ocurre fuera de banda.
Variables
Sección titulada «Variables»Valores no secretos (URLs base, IDs) que las verificaciones de API referencian en tiempo de ejecución como ${{NAME}} en la URL, los encabezados, los parámetros de consulta y el cuerpo, con el mismo marcador que los secretos. El logicalId es la clave de la variable. (Para los secretos, usa env set-secret: nunca los pongas en archivos.)
kind: variablelogicalId: BASE_URLvalue: "https://api.example.com"Autoría en JavaScript o TypeScript
Sección titulada «Autoría en JavaScript o TypeScript»Si prefieres código en lugar de YAML, construye las mismas definiciones de forma programática y expórtalas: los constructos producen recursos idénticos:
const { Monitor, Group, AlertRule, Maintenance, Dashboard, StatusPage, AlertChannel, Variable } = require('@loadfocus/monitoring');
module.exports = [ new Monitor({ type: 'api', logicalId: 'home', name: 'Home API', schedule: '300', locations: ['us-east-1'], request: { url: 'https://example.com/health', method: 'GET' }, assertions: [{ type: 'statusCode', comparison: 'equals', value: 200 }], }), new Group({ logicalId: 'web', name: 'Web services', locations: ['us-east-1'] }),];Exporta los constructos desde el archivo (un array, como arriba) y nómbralo de modo que checkMatch lo recoja, por ejemplo monitors/home.check.js. La CLI lo carga como cualquier otro recurso.
Secretos y variables
Sección titulada «Secretos y variables»Referencia valores desde tus comprobaciones sin incluirlos en el repositorio. Los secretos (tokens, contraseñas) se gestionan únicamente de forma imperativa y se referencian como ${{NAME}} en los campos de las comprobaciones (URL, encabezados, cuerpo) y como {{secrets.NAME}} en los campos secretos de los canales de alerta. Las variables (no secretas) pueden declararse como archivos (kind: variable, arriba) o establecerse de forma imperativa, y se referencian igual en los campos de una verificación de API, como ${{NAME}}; en esos campos, un marcador sin el signo de dólar, como {{NAME}}, se envía como texto literal. Una verificación multipaso pasa los valores entre pasos de otra forma: su script de configuración lee la variable como ${{NAME}} y la guarda en ctx.vars, y los pasos la usan como {{name}} (consulta Scripts de configuración y limpieza).
loadfocus-monitoring env set-secret API_TOKEN "s3cr3t"loadfocus-monitoring env set-var BASE_URL "https://example.com"loadfocus-monitoring env ls # list secret + variable keys (values never shown)loadfocus-monitoring env rm-secret API_TOKEN # delete a secretloadfocus-monitoring env rm-var BASE_URL # delete a variableEjecutarla en CI
Sección titulada «Ejecutarla en CI»Un pipeline típico valida en cada pull request y despliega al hacer merge a la rama principal.
name: monitoringon: pull_request: push: branches: [main]jobs: monitoring: runs-on: ubuntu-latest env: LOADFOCUS_API_KEY: ${{ secrets.LOADFOCUS_API_KEY }} LOADFOCUS_TEAM_ID: ${{ secrets.LOADFOCUS_TEAM_ID }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20 } - run: npx @loadfocus/monitoring validate - if: github.ref == 'refs/heads/main' run: npx @loadfocus/monitoring deploy --yesCosas que conviene saber
Sección titulada «Cosas que conviene saber»logicalIdes la identidad. Mantenlo estable. Puedes renombrar libremente elnameo eltitlede una comprobación; cambiar sulogicalIdse trata como eliminar un recurso y crear otro.- Las eliminaciones se limitan al proyecto.
deploysolo retira recursos delprojectactual que ya no están en tus archivos, nunca nada de otro proyecto ni creado fuera de Monitoring as Code (hasta que lo adoptes). - Los slugs de las páginas de estado son globales. El
slugse convierte en un subdominio, así que debe ser único entre todos los clientes de LoadFocus. - Las funciones de pago necesitan un plan de pago. Un equipo gratuito que declare un dominio personalizado en una página de estado recibe un error claro en
deploy. Quitar la insignia "Powered by" no se aplica en un plan gratuito: el campo sigue desactivado. - Se aplican los límites del plan. Crear recursos mediante la CLI está sujeto a las mismas cuotas de plan que el panel. Un recurso que superaría una cuota se informa como rechazado y el resto del deploy continúa.