Modo de aserciones: referencia completa de validación
El modo de aserciones sustituye los campos fijos de aprobado/fallido de un monitor por una lista de reglas que escribes tú mismo, cada una nombrando exactamente qué tiene que ser cierto sobre la respuesta. La mayoría de los monitores de disponibilidad juzgan una comprobación con un puñado de campos fijos: un código de estado que cuenta como "caído", una lista de estados que ignorar, quizás una palabra clave que tiene que aparecer en algún punto del cuerpo. Esos campos no pueden expresar una API que legítimamente responde 404 para un recurso que falta, una página que devuelve 200 con una cáscara vacía porque la base de datos agotó el tiempo de espera, o una cadena de redirecciones que empieza a pasar por el dominio de otro.
El modo de aserciones de HostTracker sustituye esos campos fijos por un pequeño lenguaje de reglas que escribes tú mismo, regla a regla, dentro del editor de monitores. Cada regla dice exactamente qué tiene que ser cierto sobre la respuesta: el estado, un fragmento del cuerpo, una cabecera, cuánto tardó, dónde terminó una redirección. Una comprobación falla solo cuando una de tus reglas falla. Es el mismo lenguaje para un sitio web, una API REST, una consulta a base de datos, un puerto TCP, un objetivo de Ping, un contador SNMP o una comprobación de tipo Counter genérica: un único conjunto de sujetos, un único conjunto de predicados, reutilizados en todos los sitios donde aparece el modo. Esta guía cubre todos los sujetos, operadores, reductores, atajos de azúcar sintáctico y formas de sintaxis que implementa el motor.
Qué sustituye el modo de aserciones
Los campos clásicos de Validación de respuesta siguen ahí cuando el modo de aserciones está apagado: un rango de estado esperado, una lista de estados que ignorar, una palabra clave que debe (o no debe) aparecer. El modo es un interruptor que cambia ese conjunto fijo por una lista de reglas que construyes tú mismo, y volver a apagarlo antes de guardar restaura directamente los campos clásicos. Ningún monitor queda atado a un solo modo de forma permanente.
Un solo lenguaje en lugar de un montón de mecanismos por tipo se compone entre sí. Una comprobación de "debe ser JSON y contener un campo", una comprobación de "todavía debe decir Añadir al carrito" y una comprobación de "no debe haberse vuelto más lento" son tres reglas en la misma sintaxis, en la misma lista, cada una aprobando o fallando por su cuenta.
Cómo activarlo
El modo de aserciones vive dentro de la sección de Validación de respuesta del editor de monitores, para monitores HTTP (sitio web) y API. Activa el interruptor, y los campos clásicos se sustituyen por una lista numerada de reglas con un botón "Añadir regla" y un contador en vivo que muestra cuántas reglas has usado frente al límite de tu plan.

Cada regla se valida a medida que la construyes: una regla que todavía no está terminada lleva un estado diferenciado de "sin terminar", y una regla que el editor puede evaluar se marca como completa. Cada regla tiene además un pequeño botón </> que abre su forma de origen en texto plano, para que puedas leer o copiar la expresión exacta en lugar de solo la vista campo a campo.
El modelo mental: sujeto, predicado, valor
Toda regla tiene la misma forma: un sujeto (el código de estado, el cuerpo, una cabecera, el tiempo de respuesta), un predicado (igual a, contiene, existe, es menor que) y, para la mayoría de los predicados, un valor con el que comparar. status eq 200 es sujeto, predicado y valor; body.json exists es un sujeto y un predicado sin valor, porque "exists" no necesita nada más.
Construir una regla en el editor empieza eligiendo qué comprobar, luego la condición y luego el valor:

Las reglas de la lista se combinan con AND: una comprobación falla cuando cualquier regla individual falla y aprueba solo cuando todas las reglas aprueban. Todavía no existe OR, así que para aceptar uno de varios estados o cadenas de texto, exprésalo dentro de una sola regla (status in [200, 301, 302], body containsAny ["In stock", "Pre-order"]). Una regla que falla se nombra a sí misma en la alerta, así que ponle a cada una una etiqueta corta donde puedas y la alerta dirá qué expectativa se rompió.
Qué puedes comprobar
El selector agrupa los sujetos en el propio documento de la respuesta (el cuerpo, las cabeceras) y su transporte (estado, tiempos, redirecciones, TLS). Algunos de los sujetos más importantes, con la lista completa en la referencia que sigue:
| Sujeto | Qué es | Ejemplo |
|---|---|---|
status | El código de estado HTTP de la respuesta final, tras seguir las redirecciones | status isOk |
body | El cuerpo de la respuesta como texto plano | body contains "Add to cart" |
body.json / body.xml / body.html / body.yaml | El cuerpo, pero solo cuando de verdad se interpreta como ese formato; si no, el sujeto simplemente no está presente | body.json exists |
body.json.path("$.a") | Una consulta JSONPath sobre un cuerpo JSON (el mismo lenguaje de consulta también funciona sobre YAML, ya que YAML se interpreta en el mismo modelo de objetos) | body.json.path("$.status") eq "ok" |
body.size / body.hash | El tamaño de la respuesta en bytes, y una huella del contenido del cuerpo | body.size gt 1kb |
header("Name") | Una cabecera de la respuesta, buscada por nombre | header("Content-Type") isJson |
time y time.connect / time.tls / time.dns / time.head | Tiempo total de respuesta, y sus fases de red, negociación TLS, DNS y tiempo de procesamiento del servidor | time lt 2s |
redirects / requests | Los saltos que siguió una comprobación, y la cadena completa (incluida la respuesta final) | redirects.count eq 0 |
url y sus partes (.host, .scheme, .path...) | La URL final a la que llegó la comprobación | url.scheme eq "https" |
cert.days.left | Días que faltan para que caduque el certificado TLS | cert.days.left gt 14 |
Los números aceptan sufijos de unidad para que nunca tengas que convertir a mano: 2s significa 2000 milisegundos, 1kb significa 1024 bytes. Las comparaciones de texto distinguen mayúsculas de minúsculas a menos que añadas nocase a la regla.
La referencia completa
Lo que sigue es cada sujeto, operador, reductor, atajo de azúcar sintáctico, filtro y forma de sintaxis que el motor de aserciones registra para comprobaciones HTTP y API, tomado del propio registro del motor (los mismos datos que alimentan los selectores del editor de reglas y su documentación). Las entradas que todavía no están disponibles con carácter general llevan una nota entre paréntesis: campos reservados que el motor todavía no ha empezado a rellenar, candidatos que todavía se están desplegando a los agentes, y la familia con estado que necesita un plan concreto. Cualquier cosa sin esa nota está disponible hoy en todos los planes que tienen modo de aserciones.
La referencia sigue la propia agrupación del motor: campos de la respuesta, luego las formas de acceder a un cuerpo, luego tiempos, red y TLS, luego los operadores, reductores y atajos que funcionan sobre todos ellos, y por último los tipos de comprobación más allá de HTTP que hablan el mismo lenguaje.
Respuesta
Los sujetos que describen la propia respuesta: su estado, su cuerpo en bruto, sus cabeceras, la URL desde la que realmente respondió y la cadena de peticiones que llevó hasta ahí.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
body | El cuerpo de la respuesta como texto decodificado. | texto | body contains "Welcome" |
header | Una cabecera de la respuesta final, por nombre. | texto | header("Content-Type") isJson |
redirects | Los saltos de redirección que se siguieron: la cadena de peticiones sin su elemento final. | colección | redirects.count eq 0 |
status | El código de estado HTTP de la respuesta final, tras seguir las redirecciones. | número | status isOk |
body.size | El tamaño del cuerpo descargado, en bytes. | número | body.size lt 500000 |
url | La URL que realmente respondió, después de todas las redirecciones. Una url: compárala como texto, o lee sus partes (url.host, .port, .path, .query, .scheme). | url | url.host eq "www.example.com" |
requests | Cada petición que hizo esta comprobación, en orden: los saltos de redirección y luego la petición final. | colección | requests.count le 2 |
url.host | La parte de host de la URL. | texto | url.host eq "example.com" |
url.path | La parte de ruta de la URL. | texto | url.path startsWith "/api" |
url.port | La parte de puerto de la URL. | número | url.port eq 443 |
url.query | La cadena de consulta de la URL. | texto | url.query contains "token" |
url.scheme | El esquema de la URL (http o https). | texto | url.scheme eq "https" |
body.hash | Una huella del cuerpo de la respuesta: compárala con previous.body.hash para detectar cambios de contenido. | texto | body.hash eq previous.body.hash |
httpVersion (reservado, todavía no se rellena) | La versión de HTTP negociada. | texto | httpVersion eq "HTTP/2" |
setCookie | Los valores de Set-Cookie de la respuesta final, uno por cookie: compara uno con contains o matches, cuéntalos con .count. | colección | setCookie exists |
steps (no disponible todavía) | Los pasos de una comprobación de varios pasos. Todavía no disponible. | colección | steps.count le 1 |
url.original | La URL con la que se configuró la comprobación, antes de cualquier redirección. Una url como la propia url: tiene las mismas partes (url.original.host, .port, .path, .query, .scheme). | url | url.original.scheme eq "http" |
url.original.host | La parte de host de la URL. | texto | url.original.host eq "example.com" |
url.original.path | La parte de ruta de la URL. | texto | url.original.path startsWith "/start" |
url.original.port | La parte de puerto de la URL. | número | url.original.port eq 80 |
url.original.query | La cadena de consulta de la URL. | texto | url.original.query contains "utm_" |
url.original.scheme | El esquema de la URL (http o https). | texto | url.original.scheme eq "http" |
Dos alias: redirectCount es la forma corta de redirects.count; redirectCount eq 0 se lee de forma algo más natural que la forma larga equivalente cuando quieres decir "la comprobación respondió directamente, sin redirecciones". Y setCookie en el nivel superior es la lista de cookies de la respuesta final; el mismo nombre reaparece por cada salto dentro de requests/redirects (ver los sujetos de salto más abajo), con solo las cookies de esa petición concreta.
Extraer valores del cuerpo
Estos sujetos solo se resuelven cuando el cuerpo es del formato que nombran: un espacio de nombres JSON sobre una página HTML simplemente no está presente, no es un error tipado. Eso hace de exists la forma estándar de comprobar el formato, y body.json exists pregunta si el cuerpo se interpretó como JSON. Los cuatro espacios de nombres de formato llevan cada uno su propia función .path(...) de consulta a juego (JSONPath para json/yaml, XPath para xml, selectores CSS para html) y un .regex(...) a juego, más un body.regex(...) independiente del formato que lee el texto en bruto sin importar el formato. body.html.a, body.html.script y body.html.link son colecciones ya preparadas con cada enlace, script y elemento <link> de la página; ver los alcances de elemento más abajo para los campos disponibles en cada uno.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
body.json | El cuerpo de la respuesta, pero solo cuando de verdad es JSON. | texto | body.json exists |
body.json.path | Consulta el cuerpo JSON con una expresión JSONPath. | json | body.json.path("$.status") eq "ok" |
body.html | El cuerpo de la respuesta, pero solo cuando de verdad es HTML. | texto | body.html exists |
body.html.path | Selecciona elementos de la página con un selector CSS. | colección | body.html.path("h1").first contains "Welcome" |
body.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
body.xml | El cuerpo de la respuesta, pero solo cuando de verdad es XML. | texto | body.xml exists |
body.xml.path | Consulta el cuerpo XML con una expresión XPath. | texto | body.xml.path("//item/@id") exists |
body.html.a | Cada enlace de la página. | colección | body.html.a.count gt 0 |
body.html.link | Cada <link> que declara la página. Una mención simple significa los destinos del enlace. | colección | body.html.link.count gt 0 |
body.html.script | Cada script que carga la página. Una mención simple significa las fuentes del script. | colección | body.html.script.count gt 0 |
body.yaml | El cuerpo de la respuesta, pero solo cuando de verdad es YAML. | texto | body.yaml exists |
body.yaml.path | Consulta el cuerpo YAML con una expresión JSONPath. | json | body.yaml.path("$.services.web.image") contains ":1." |
body.html.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
body.json.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
body.xml.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
body.yaml.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
Un detalle de la familia regex que merece mención: los grupos de captura con nombre ((?<id>...)) dentro de una regla .regex(...) escriben en un espacio de nombres de enlaces con alcance de comprobación que una regla posterior puede leer con bind("id") o bind[0] por posición; ver Valores capturados más abajo.
Valores capturados
Un sujeto vive en su propio grupo del registro porque no lee la respuesta directamente, sino lo que capturó una regla anterior a partir de ella.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
bind | Un valor capturado por una regla regex anterior, por nombre de captura o por posición. | texto | bind("id") gt 1000 |
Combínalo con una regla regex anterior en la lista: una regla como body.regex("order-(?<id>\d+)") exists captura el id del pedido con el nombre id, y una regla posterior puede comprobarlo con bind("id") gt 1000 o, para una captura posicional (sin nombre), bind[0].
Tiempos
Un total más un desglose por fase, para que una alerta de "se ha vuelto más lento" también pueda decir qué parte se ha vuelto más lenta.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
time | Tiempo total de respuesta: conexión + TLS + espera + descarga. La resolución DNS no se incluye. | número | time lt 2000 |
ttfb (reservado, todavía no se rellena) | Tiempo hasta el primer byte. | número | ttfb lt 200 |
time.connect | Tiempo empleado en establecer la conexión TCP. | número | time.connect lt 500 |
time.data | Tiempo empleado en descargar el cuerpo de la respuesta. | número | time.data lt 1000 |
time.dns | Tiempo empleado en resolver el nombre de dominio. No se incluye en el sujeto time simple. | número | time.dns lt 200 |
time.head | Tiempo esperado por las cabeceras de la respuesta. | número | time.head lt 500 |
time.tls | Tiempo empleado en la negociación TLS. | número | time.tls lt 300 |
El sujeto time simple es conexión + TLS + espera de cabeceras + descarga del cuerpo. La resolución DNS queda excluida y vive solo en el sujeto hermano time.dns, porque el DNS suele estar en caché y de lo contrario haría que el mismo endpoint pareciera de forma inconsistente rápido o lento entre comprobaciones.
Red: DNS y conexión
dns y conn son espacios de nombres puros en el registro, un grupo sin valor propio, así que una regla nunca puede terminar en el nombre simple (tanto el editor como el motor rechazan una cadena que termine en dns o conn solos, y te señalan los campos reales de abajo).
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
conn | La conexión de red que hizo la comprobación: la dirección que sirvió la respuesta y cualquier fallo de conexión. | texto | - |
conn.failed | Cuántas de las direcciones resueltas fallaron al conectar. | número | conn.failed eq 0 |
conn.failedIps (candidato, desplegándose a los agentes) | Las direcciones resueltas que fallaron al conectar. | colección | conn.failedIps.count eq 0 |
conn.ip | La dirección IP que realmente sirvió la respuesta. | texto | conn.ip eq "203.0.113.10" |
conn.ip.family (candidato, desplegándose a los agentes) | Si la respuesta se sirvió por IPv4 o IPv6. | texto | conn.ip.family eq "IPv4" |
dns | Resolución DNS del nombre monitorizado: a qué direcciones resolvió y qué servidor respondió. | texto | - |
dns.ips | Todas las direcciones IP a las que resolvió el nombre de dominio durante esta comprobación. | colección | dns.ips contains "1.2.3.4" |
dns.server | El servidor DNS que respondió a la resolución. | texto | dns.server eq "8.8.8.8" |
TLS y certificado
Igual que dns y conn, tls y cert son espacios de nombres puros; los datos del certificado y del saludo viven un nivel más abajo.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
cert.days.left | Días que faltan hasta que caduque el certificado del sitio. | número | cert.days.left gt 14 |
cert | El certificado que presentó el servidor: días para caducar, emisor y campos de identidad. | texto | - |
cert.days | Días desde que se emitió el certificado. | número | cert.days gt 0 |
cert.issuer | La autoridad de certificación que emitió el certificado del sitio. | texto | cert.issuer contains "Let's Encrypt" |
cert.san | Los nombres de dominio para los que es válido el certificado. | colección | cert.san contains "www.example.com" |
cert.serial | El número de serie del certificado. | texto | cert.serial exists |
cert.subject (reservado, todavía no se rellena) | El titular del certificado. Todavía no se captura; llegará con una futura versión del agente. | texto | cert.subject contains "example.com" |
tls | La negociación TLS de la conexión segura: versión de protocolo y cifrado negociados. | texto | - |
tls.cipher | El conjunto de cifrado negociado. | texto | tls.cipher contains "AES" |
tls.protocol | La versión de TLS negociada. | texto | tls.protocol eq "Tls13" |
cert.subject se lista aquí para completar, pero todavía no está rellenado; ver la sección de Transparencia más abajo para lo que significa "reservado" en la práctica. La regla de certificado del día a día es cert.days.left gt 14, cubierta en la sección de reglas resueltas.
Sujetos de salto: campos dentro de requests y redirects
requests y redirects son colecciones, y cada elemento es un registro completo de petición/respuesta con su propio conjunto reducido de campos. No todos los sujetos de nivel superior tienen sentido por salto (un salto no tiene certificado propio), y un campo existe solo por salto: hstsHeader, la cabecera Strict-Transport-Security de esa petición en la cadena.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
status | El código de estado de esta petición en la cadena. | número | status eq 200 |
url | La URL a la que se hizo esta petición. | url | url startsWith "https://" |
header | Una cabecera de respuesta de esta petición. Un salto guarda un registro de cabecera reducido, de un solo valor: los predicados de lista (containsAny, containsAll, unique) solo se aplican sobre la cabecera de la respuesta final. | texto | header("Content-Type") contains "json" |
hstsHeader | La cabecera Strict-Transport-Security de esta petición. | texto | requests[0].hstsHeader exists |
setCookie | Los valores de la cabecera Set-Cookie de esta petición. | colección | setCookie exists |
url.original | La URL con la que se configuró la comprobación, antes de cualquier redirección. Una url como la propia url: tiene las mismas partes (url.original.host, .port, .path, .query, .scheme). | url | url.original.scheme eq "http" |
url.host | La parte de host de la URL. | texto | url.host eq "example.com" |
url.port | La parte de puerto de la URL. | número | url.port eq 443 |
url.path | La parte de ruta de la URL. | texto | url.path startsWith "/api" |
url.query | La cadena de consulta de la URL. | texto | url.query contains "token" |
url.scheme | El esquema de la URL (http o https). | texto | url.scheme eq "https" |
url.original.host | La parte de host de la URL. | texto | url.original.host eq "example.com" |
url.original.port | La parte de puerto de la URL. | número | url.original.port eq 80 |
url.original.path | La parte de ruta de la URL. | texto | url.original.path startsWith "/start" |
url.original.query | La cadena de consulta de la URL. | texto | url.original.query contains "utm_" |
url.original.scheme | El esquema de la URL (http o https). | texto | url.original.scheme eq "http" |
El header(...) por salto guarda un registro reducido de un solo valor: los predicados con forma de lista como containsAny o unique solo tienen sentido sobre el mapa completo de cabeceras de la respuesta final, así que se aplican ahí y no por salto. Las dos colecciones significan cosas distintas. requests es toda la cadena incluida la respuesta final que contestó, así que nunca está vacía ni siquiera para un 200 directo, mientras que redirects son solo los saltos seguidos por el camino, vacío cuando no hubo ninguna redirección.
Alcances de elemento: campos dentro de un elemento de colección
Un alcance de elemento es el conjunto de campos disponible en UN elemento de una colección, tras indexar sobre él (requests[0]) o al filtrarlo con where(current. ...) (ver la siguiente sección). Seis colecciones tienen su propio alcance de elemento: las cuatro colecciones de elementos HTML comparten una misma forma, y requests/redirects comparten la forma de los sujetos de salto documentada justo arriba.
| Alcance de elemento | Cómo es un elemento |
|---|---|
body.html.path | Un elemento que coincide con una consulta CSS body.html.path("selector"). |
body.html.a | Un elemento <a> de enlace de body.html.a. |
body.html.script | Un elemento <script> de body.html.script. |
body.html.link | Un elemento <link> de body.html.link. |
requests | Una petición en la cadena completa (ver la tabla de sujetos de salto de arriba). |
redirects | Un salto de redirección seguido (los mismos campos que requests, ver arriba). |
La forma compartida de body.html.path(...), body.html.a, body.html.script y body.html.link, una fila por enlace, etiqueta script o elemento <link>:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
url | El destino del enlace exactamente como lo escribe el marcado. | texto | body.html.a.url contains "/checkout" |
text | El texto visible del elemento. | texto | body.html.a.text contains "Sign in" |
absolute | El destino del enlace resuelto contra la URL de la página como dirección absoluta: una lista de urls, con las partes de la url disponibles por elemento (.host, .path, .port, .query, .scheme). | url | body.html.a.absolute.scheme in ["https"] |
rel | El atributo rel del elemento. | texto | body.html.a.where(current.rel eq "nofollow").count eq 0 |
absolute.host | La parte de host de la URL. | texto | body.html.a.absolute.host.unique.count le 3 |
absolute.port | La parte de puerto de la URL. | número | body.html.a.absolute.port in [443] |
absolute.path | La parte de ruta de la URL. | texto | body.html.a.absolute.path startsWith "/" |
absolute.query | La cadena de consulta de la URL. | texto | body.html.a.absolute.query not contains "session" |
absolute.scheme | El esquema de la URL (http o https). | texto | body.html.a.absolute.scheme in ["https"] |
Se aplican dos valores por defecto antes de escribir una regla contra estas colecciones. Una mención simple de body.html.a (o .script/.link) significa su proyección .url, así que body.html.a.count gt 0 cuenta los hrefs, y una regla guardada se vuelve a leer con .url escrito explícitamente, porque una regla guardada siempre dice exactamente qué evalúa. Y .url es el atributo href en bruto exactamente como lo escribió el marcado, así que un enlace relativo se queda relativo; .absolute es ese mismo enlace resuelto contra la propia URL de la página, que es lo que quieres al comprobar el esquema o el host de enlaces salientes (body.html.a.absolute.scheme in ["https"]).
Operadores
La mitad de predicado de cada regla: qué prueba ejecutar contra el sujeto. Los 15 se comparten en todos los tipos de comprobación, y cuáles encajan con un sujeto dado depende de su tipo (un código de estado admite lt/gt, un cuerpo admite contains, una colección admite exists/unique/in).
| Nombre | Qué es | Se aplica a | Ejemplo |
|---|---|---|---|
eq | Igual a. Contra un literal json("…") / xml("…") / yaml("…") es una coincidencia estructural EXACTA: mismas claves (en cualquier orden), arrays en el mismo orden, mismos valores. | cualquier tipo | body.json eq json("{\"ok\": true}") |
lt | Menor que. | números | time lt 2000 |
le | Menor o igual que. | números | cert.days.left le 30 |
gt | Mayor que. | números | body.size gt 0 |
ge | Mayor o igual que. | números | status ge 500 |
contains | Contiene el texto; sobre una lista, aprueba cuando el valor ES uno de los elementos (coincidencia exacta; usa matches para buscar dentro de los elementos). Contra un literal json("…") / xml("…") / yaml("…") es contención ESTRUCTURAL: todo lo que declara el literal tiene que estar presente y coincidir; la respuesta puede tener más. | texto o lista | body.json contains json("{\"status\": \"ok\"}") |
startsWith | Empieza por el texto; sobre una lista, cuando CUALQUIER elemento lo hace. | texto | url.path startsWith "/api" |
endsWith | Termina en el texto; sobre una lista, cuando CUALQUIER elemento lo hace. | texto | url.path endsWith ".json" |
matches | Coincide con la expresión regular en cualquier punto del texto; sobre una lista, cuando CUALQUIER elemento lo hace. | texto | body matches "order-\\d+" |
containsAny | Contiene al menos uno de los valores listados (sobre una lista: algún elemento ES IGUAL a uno de ellos). | lista | body containsAny ["In stock", "Pre-order"] |
containsAll | Contiene todos y cada uno de los valores listados (sobre una lista: cada valor es igual a algún elemento; los elementos que lo cumplen pueden variar). | lista | body.html.a.text containsAll ["Home", "Contact"] |
in | Es uno de los valores o rangos listados; sobre una lista, cada elemento lo es. | valor(es) o rango | status in [200, 301, 302] |
exists | El sujeto está presente. | cualquier sujeto | header("ETag") exists |
isNumber | El valor se lee como un número. | texto o cualquier valor | bind("id") isNumber |
unique | La lista no tiene duplicados. | lista | dns.ips unique |
Dos operadores significan algo más estrecho de lo que parece. contains sobre una lista es pertenencia exacta: el valor tiene que ser igual a un elemento completo, no aparecer como subcadena dentro de uno, así que recurre a matches cuando quieras un comportamiento de subcadena sobre los elementos de una colección. Y eq contra un literal json(...)/xml(...)/yaml(...) es una coincidencia estructural completa (mismas claves, arrays en el mismo orden, mismos valores), mientras que contains contra el mismo tipo de literal es contención estructural: todo lo que declara el literal tiene que estar presente, pero la respuesta real puede llevar más.
Reductores
Un reductor colapsa una colección a un solo valor y solo puede aparecer al final de una cadena. Los ejemplos de abajo usan requests.status, la colección naturalmente numérica que forman los sujetos HTTP, como ilustración; los mismos ocho reductores funcionan sobre cualquier colección numérica en cualquier tipo de comprobación (los tiempos de ida y vuelta de una comprobación Ping, un conjunto filtrado de filas de base de datos).
| Nombre | Qué colapsa | Se aplica a | Ejemplo |
|---|---|---|---|
count | Cuántos elementos tiene la lista. | cualquier colección | requests.count le 2 |
min | El número más pequeño de la lista. | colección numérica | requests.status.min ge 200 |
max | El número más grande de la lista. | colección numérica | requests.status.max lt 500 |
sum | La suma de los números de la lista. | colección numérica | requests.status.sum gt 0 |
avg | El promedio de los números de la lista. | colección numérica | requests.status.avg lt 300 |
first | El primer elemento de la lista. | cualquier colección | redirects.status.first eq 301 |
last | El último elemento de la lista. | cualquier colección | requests.status.last eq status |
unique | La lista sin duplicados. | cualquier colección | dns.ips.unique.count le 3 |
unique está sobrecargado, y la forma de escribirlo distingue los dos significados. Escrito como operador sin punto (x unique) es un predicado, "esta colección no tiene duplicados", y falla nombrando la repetición. Escrito como reductor con punto (x.unique) es una transformación, la propia colección deduplicada, que todavía necesita algo después (x.unique.count eq 1). Un x.unique suelto sin nada después es un error de sintaxis, porque el motor no puede adivinar cuál de los dos significados querías.
Azúcar sintáctico
Los predicados de azúcar sintáctico son atajos que el motor expande en predicados básicos ordinarios antes de que la regla se envíe nunca a un agente; un predicado de azúcar no cuesta nada extra añadir (sin paquete de agente, sin versión mínima) porque cuando llega a la red ya parece una regla ordinaria. Prefiere el azúcar siempre que exista: se lee mejor, y es exactamente equivalente a escribir la forma larga a mano.
| Nombre | Qué significa | Se aplica a | Ejemplo |
|---|---|---|---|
isOk | El estado es un código de éxito (200-299). | status | - |
isRedirect | El estado es un código de redirección (300-399). | status | status isRedirect |
isClientError | El estado es un error de cliente (400-499). | status | status isClientError |
isServerError | El estado es un error de servidor (500-599). | status | status isServerError |
isJson | El contenido de verdad es JSON. | documento o texto de tipo de medio | header("Content-Type") isJson |
isXml | El contenido de verdad es XML: el cuerpo se interpreta como XML, o una cabecera nombra un tipo de medio XML. | documento o texto de tipo de medio | body isXml |
isHtml | El contenido de verdad es HTML: el cuerpo se interpreta como HTML, o una cabecera nombra un tipo de medio HTML. | documento o texto de tipo de medio | body isHtml |
isForm | Un tipo de medio nombra una codificación de formulario: application/x-www-form-urlencoded o multipart/form-data. A diferencia de isJson/isXml/isHtml no hay un espacio de nombres de cuerpo a juego, así que solo se aplica a un valor de tipo de medio como una cabecera Content-Type. | solo texto de tipo de medio | header("Content-Type") isForm |
isEmpty | No hay nada ahí: un texto vacío, un tamaño cero o una lista vacía. | texto, tamaño o lista | body isEmpty |
isNull | El valor es nulo. | cualquier valor | body.json.path("$.deletedAt") isNull |
absent | El sujeto no está presente en absoluto. | cualquier sujeto | header("X-Debug") absent |
between | Un número dentro de un rango inclusivo. | números (2 operandos) | body.size between 50 and 500kb |
isJson/isXml/isHtml son sensibles al contexto a propósito, y lo que escribas sobre ellos decide qué significado se aplica. Escritos sobre el propio documento (body isJson) significan "¿esto se interpreta como ese formato?", igual que body.json exists. Escritos sobre un valor de texto que nombra un tipo de medio, como una cabecera (header("Content-Type") isJson), significan "¿esto nombra la familia MIME de ese formato?"; ver las familias MIME más abajo para qué tipos de medio cumplen. isForm solo tiene el segundo significado, ya que no hay un espacio de nombres body.form en el que interpretarlo, así que body isForm es un error estático en lugar de una regla que nunca podría ser cierta.
El filtro where(...)
Conserva solo los elementos que coinciden, y sigue a partir de ahí. Es la única construcción de filtrado del lenguaje, y tiene exactamente una forma: where(current.<campo> <condición> <valor>).
Filtrar es distinto de proyectar: requests.url contains "cart" pregunta si existe un salto así en cualquier punto de la cadena, mientras que requests.where(current.url contains "cart").status pregunta qué devolvió ese salto. Filtrar no colapsa la lista, así que termina con .first, una comprobación in [...], o .count. Va solo un nivel, y toma exactamente una condición.
| Parte | Qué nombra | Notas |
|---|---|---|
current.<campo> | Un campo de cada elemento que se filtra, escrito tras current. | Esta es la mitad que la gente se equivoca: current.url es la URL del salto individual, no la de la respuesta final. Solo los campos propios del elemento pueden ir tras current.. |
| la condición | Cualquier predicado ordinario, incluidos not y nocase | Cualquier condición que funcione en el nivel superior de una regla también funciona aquí. |
| el valor | Contra qué se compara el campo de cada elemento | Normalmente un valor simple. Un sujeto escrito aquí se lee de la respuesta EXTERNA, no del elemento: where(current.url eq url.original) compara cada salto contra la URL con la que se configuró la comprobación, por lo que el lado del elemento tiene que decir current. explícitamente. |
Ejemplo: requests.where(current.url contains "cart").status.first eq 301: conserva solo los saltos cuya URL contenga "cart", y mira luego el estado del primero que coincidió.
Dos límites más, ambos impuestos por el analizador con su propio mensaje: where no se puede anidar dentro de otro where, y su argumento es exactamente una condición, sin and/or dentro. Solo se aplica a una colección cuyos elementos llevan campos con nombre (requests, body.html.a), no a una lista proyectada simple como dns.ips, donde no hay nada que current. pueda nombrar.
Referencia de sintaxis
Todo lo demás que define la gramática: cómo nombrar una regla, cómo escribir rangos y listas, qué significa un sujeto simple, y las pequeñas formas de puntuación que aparecen en muchas reglas.
| Forma | Qué hace | Tipo | Ejemplo |
|---|---|---|---|
where | Conserva solo los elementos que coinciden, y sigue a partir de ahí. | filtro de colección | requests.where(current.url contains "cart").status.first eq 301 |
not | Invierte la condición que sigue. | indicador | body not contains "error" |
nocase | Compara texto sin distinguir mayúsculas de minúsculas. | indicador | body contains "welcome" nocase |
current | Dentro de where(…), nombra el elemento que se está filtrando. | referencia de elemento (dentro de where) | requests.where(current.status eq 301) |
range | Un rango de números, con AMBOS extremos incluidos. | rango de números | status in [200..299] |
list | Una lista de valores con la que comparar. | lista de valores | status in [200, 301, 302] |
docLiteral | Un valor de documento tipado para comparación estructural: el texto entre comillas se interpreta como JSON, XML o YAML al guardar la regla. | texto json/xml/yaml | body.json contains json("{\"user\": {\"active\": true}}") |
implicitExists | Una regla que solo nombra un sujeto comprueba que está presente: escribir solo body.json se guarda como body.json exists. | línea de sujeto simple | body.json |
index | Elige UN elemento de una lista por posición, contando desde 0. | entero base 0 | requests[0].status |
label | Un nombre opcional para la regla, escrito antes de dos puntos. | nombre antes de dos puntos | "json ok": body.json exists |
comment | Todo lo que va después de # es una nota para ti mismo; no afecta a la comprobación. | texto tras # al final | status isOk # the happy path |
Algunos merecen una explicación en lenguaje llano. label le da a una regla un nombre que aparece en la alerta en lugar de la expresión renderizada; escríbelo antes de dos puntos, como en "json ok": body.json exists. implicitExists significa que una línea que solo nombra un sujeto y ningún predicado es una forma corta de exists: escribir body.json se guarda como body.json exists, y al reabrir la regla se muestra la forma completa. range y list son las dos formas que puede tomar un valor después de in: un rango ([200..299], ambos extremos incluidos) o una lista explícita ([200, 301, 302]), y un valor puede quedar abierto por cualquiera de los dos lados ([400..]). docLiteral es el envoltorio json(...)/xml(...)/yaml(...) usado para la comparación estructural contra el cuerpo (cubierto en Operadores más arriba y en las reglas resueltas más abajo). index elige un elemento de una colección por posición, base 0, del mismo modo que bind[0] lee una captura posicional. current solo tiene sentido dentro de un filtro where(...), cubierto en su propia sección más arriba.
Envoltorios: previous, delta y delta2
Tres formas que miran hacia atrás en lugar de solo a la respuesta actual; cada una está restringida a planes con aserciones con estado, y cada una se explica por completo en "Comparar contra la comprobación anterior" más abajo.
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
delta (requiere un plan con aserciones con estado) | Cuánto cambió un valor numérico desde la comprobación anterior, opcionalmente como una tasa por ms/s/m/h. | número | delta(body.size, h) lt 1mb |
delta2 (requiere un plan con aserciones con estado) | El cambio del cambio: ¿se está acelerando un valor? | número | delta2(time) gt 0 |
previous (requiere un plan con aserciones con estado) | El valor que tenía este sujeto en la comprobación anterior. | cualquier valor | status eq previous.status |
Indicadores: not y nocase
Dos modificadores que se adjuntan a una regla en lugar de ser sujetos o predicados propios.
| Indicador | Qué hace | Tipo | Ejemplo |
|---|---|---|---|
not | Invierte la condición que sigue. | indicador (se adjunta a una regla) | body not contains "error" |
nocase | Compara texto sin distinguir mayúsculas de minúsculas. | indicador (se adjunta a una regla) | body contains "welcome" nocase |
not se combina con el predicado que sigue en lugar de negar toda la regla como una unidad: x not != y se lee como x eq y, no como una doble negación. Cuando un sujeto puede estar completamente ausente, prefiere el azúcar absent antes que not exists: los dos significan exactamente lo mismo, pero absent lo dice de forma directa. nocase solo cambia algo en una comparación genuinamente textual; el editor (y esta referencia) te dejan escribirlo en cualquier sitio, pero no tiene ningún efecto en una prueba numérica como status eq 200 nocase.
Familias MIME
Las tablas de referencia detrás de isJson, isXml, isHtml e isForm cuando se aplican a un valor de tipo de medio como una cabecera. Cada familia coincide con el tipo de medio de nivel superior obvio más, para JSON y XML, cualquier tipo que termine en el sufijo de sintaxis estructurada correspondiente, que es lo que hace que header("Content-Type") isJson apruebe correctamente sobre application/problem+json o application/vnd.api+json y no solo sobre el simple application/json.
| Familia | Coincide con | Azúcar asociado | Ejemplo |
|---|---|---|---|
json | application/json, text/json, o cualquier tipo de medio que termine en +json (application/problem+json, application/vnd.api+json, application/ld+json, ...). | azúcar: isJson | header("Content-Type") isJson |
xml | application/xml, text/xml, o cualquier tipo de medio que termine en +xml (image/svg+xml, application/atom+xml, ...). | azúcar: isXml | header("Content-Type") isXml |
html | text/html o application/xhtml+xml. | azúcar: isHtml | header("Content-Type") isHtml |
form | application/x-www-form-urlencoded o multipart/form-data. | azúcar: isForm | header("Content-Type") isForm |
La coincidencia ignora todo desde el primer ; en adelante (así que application/json; charset=utf-8 sigue coincidiendo) y no distingue mayúsculas de minúsculas.
Sujetos para comprobaciones de base de datos, contador, SNMP, puerto y ping
Todos los operadores, reductores, atajos de azúcar sintáctico y formas de sintaxis de arriba son idénticos para estos cinco tipos de comprobación: el motor registra los mismos 15 operadores, 8 reductores, 12 predicados de azúcar y 11 formas de sintaxis para los seis tipos sin excepción. Lo que cambia según el tipo es la lista de sujetos. Cada tipo expone un pequeño conjunto de sujetos propios de lo que mide, más un subconjunto de los sujetos de red/tiempos/TLS ya documentados arriba, con el significado adaptándose al tipo (el time de una comprobación de base de datos es conexión-más-consulta en lugar de conexión-más-TLS-más-descarga, ya que no hay una respuesta HTTP que descargar).
Comprobaciones de base de datos
Comparte time, time.connect y time.dns con los sujetos documentados arriba (reajustados a una conexión de base de datos: conexión-más-consulta, resolución DNS del host de la base de datos). Propios de las comprobaciones de base de datos:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
scalar | El único valor que devolvió la consulta (modo Scalar). | cualquier valor | - |
rows | Las filas que afectó o devolvió la consulta (modo NonQuery). | colección | - |
time.query | Tiempo que tardó la propia consulta. | número | - |
Hay un ejemplo resuelto en la siguiente sección: usa rows.count para hacer una aserción sobre cuántas filas afectó o devolvió una consulta, y scalar para comprobar directamente un único valor devuelto.
Comprobaciones Counter
Comparte time con los sujetos documentados arriba, como campo en estado candidato específicamente para las comprobaciones Counter (tiempo de ida y vuelta de la petición del contador; ver la sección de Transparencia para lo que significa "candidato"). Propio de las comprobaciones Counter:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
value | El valor medido del contador. | número | - |
Comprobaciones SNMP
Comparte time y time.dns con los sujetos documentados arriba (resolución del nombre de host más la propia petición SNMP). Propios de las comprobaciones SNMP:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
time.request | Tiempo que tardó la petición SNMP. | número | - |
value | El valor que devolvió el OID. | cualquier valor | - |
value.type (candidato, desplegándose a los agentes) | El nombre del tipo de dato SNMP del valor devuelto. | texto | - |
value.type está en estado candidato; ver la sección de Transparencia. Nota sobre disponibilidad: el interruptor de Validación de respuesta en modo de aserciones todavía no ha llegado al editor de monitores SNMP. Muestra un panel de "Próximamente" que nombra estos dos sujetos en lugar de una lista de reglas funcional. Los sujetos y el evaluador que hay debajo ya están registrados; solo falta la interfaz del editor SNMP.
Comprobaciones de puerto
La lista compartida más grande de cualquier tipo que no sea HTTP. Una comprobación de puerto TCP lleva esencialmente los mismos sujetos de conexión, DNS, TLS y certificado que una comprobación HTTP, ya que una comprobación de puerto también puede negociar TLS: bind, cert y sus seis subcampos, conn y sus cuatro subcampos, dns y sus dos subcampos, time/time.connect/time.dns/time.tls, y tls/tls.cipher/tls.protocol, todos documentados en las secciones de arriba, con el mismo significado. Propios de las comprobaciones de puerto:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
banner | Los datos leídos del socket tras conectar. | texto | - |
banner.hash (candidato, desplegándose a los agentes) | Una huella del banner: compárala con previous.banner.hash para detectar cambios de servicio. | texto | - |
banner.regex | Compara el texto con una expresión regular y toma lo que capturó. | texto | body.regex("order-(?<id>\\d+)") exists |
banner.size (candidato, desplegándose a los agentes) | El tamaño del banner, en bytes. | número | - |
banner.hash y banner.size están en estado candidato; ver la sección de Transparencia. banner.regex está disponible hoy y funciona exactamente igual que body.regex(...) en una comprobación HTTP: las capturas con nombre alimentan el mismo espacio de nombres bind(...).
Comprobaciones Ping
Comparte los sujetos de conexión y DNS con las secciones de arriba: conn, conn.failed, conn.failedIps, conn.ip, conn.ip.family, dns, dns.ips, dns.server, time (aquí, el tiempo medio de ida y vuelta de las respuestas correctas) y time.dns. Propios de las comprobaciones Ping:
| Nombre | Qué es | Tipo/valores | Ejemplo |
|---|---|---|---|
loss | El porcentaje de peticiones echo que no obtuvieron respuesta. | número | loss eq 0 |
reply | Las respuestas echo correctas. | colección | - |
sentCount (candidato, desplegándose a los agentes) | Cuántas peticiones echo se enviaron. | número | - |
time.max | El tiempo de ida y vuelta de la respuesta más lenta. | número | - |
time.min | El tiempo de ida y vuelta de la respuesta más rápida. | número | - |
ttl | El TTL de la primera respuesta correcta: compáralo con previous.ttl para detectar cambios de ruta. | número | - |
sentCount está en estado candidato; ver la sección de Transparencia. ttl merece conocerse incluso fuera de una regla estricta de aprobado/fallido: combinarlo con previous.ttl (ver Envoltorios más arriba) señala un cambio de ruta entre comprobaciones, ya que el tiempo de vida de un paquete al llegar refleja cuántos saltos cruzó.
Reglas que la gente de verdad quiere escribir
La página está activa y de verdad dice lo correcto
Un código de estado por sí solo no puede decirte si una página se renderizó correctamente; una respuesta 200 con una cáscara vacía es el clásico fallo silencioso que se le escapa a una comprobación que solo mira el estado.
status isOk
body contains "Add to cart"
Una API responde con JSON y con el campo que esperas
Comprueba que el endpoint todavía habla JSON, y luego entra en él. La primera línea detecta una página de error HTML servida donde debería haber JSON, una forma de caída habitual detrás de un proxy; la segunda comprueba el propio estado de salud reportado por la API, no solo su estado de transporte.
body isJson
body.json.path("$.status") eq "ok"
La respuesta se volvió más lenta de lo que debería
Desglósalo cuando necesites saber qué arreglar en lugar de solo que algo va lento: time.connect, time.tls, time.dns y time.head separan el tiempo de red, del saludo, del resolutor y de la aplicación.
time lt 2s
Una redirección envió a los visitantes fuera de tu propio dominio
Compara dónde terminó la comprobación contra la URL que configuraste: falla en el momento en que una cadena de redirecciones, secuestrada, mal configurada o simplemente cambiada por un despliegue, acaba en algún sitio que no pretendías.
url.host eq url.original.host
La página cambió desde la última comprobación
Útil en contenido que debería ser estable entre comprobaciones (precios, condiciones, una política publicada) y también sirve como señal básica de desfiguración del sitio.
previous.body.hash eq body.hash
Un número dentro de un rango, escrito de forma corta
Detecta tanto una página recortada como una desbocada en una sola regla, sin escribir un rango explícito.
body.size between 50 and 500kb
Un certificado a punto de caducar
La comprobación TLS más habitual con diferencia, y una que un monitor simple de activo/caído no puede expresar en absoluto: un certificado que todavía valida hoy pero que caduca la semana que viene no da ninguna otra señal de aviso. Combínala con cert.issuer si también quieres detectar un certificado emitido en silencio por la autoridad equivocada.
cert.days.left gt 14
Una consulta a base de datos que devuelve un número de filas incorrecto
En una comprobación de base de datos, rows es la colección que una consulta afectó o devolvió: contarla detecta que una consulta que debería devolver exactamente un registro de cuenta empieza en silencio a devolver cero (eliminado, o una unión rota) o más de uno (un duplicado que no debería existir).
rows.count eq 1
Un valor SNMP que se sale del rango
Un dispositivo SNMP que responde en absoluto no es lo mismo que uno que está sano: un OID monitorizado (uso de disco, profundidad de cola, temperatura) puede subir bastante por encima de un umbral seguro mientras el dispositivo en sí sigue siendo perfectamente accesible. Comparar el value consultado contra un rango detecta lo que una simple comprobación de accesibilidad no puede.
value lt 90
Un servicio TCP que responde con el banner equivocado
Un puerto que acepta conexiones no es lo mismo que el servicio correcto escuchando en él: un proceso colgado, un proxy mal configurado o un servicio degradado o sustituido pueden todos completar igualmente el saludo TCP. Leer el mensaje de bienvenida que envía un servicio justo tras conectar (un banner de SMTP, FTP o similar) detecta lo que una simple comprobación de puerto abierto no puede.
banner contains "220"
Comparar contra la comprobación anterior
Un puñado de sujetos miran hacia atrás en lugar de solo a la respuesta actual: pon previous. delante de un sujeto para leer cuál era su valor en la última comprobación, o envuélvelo en delta(...) para obtener la diferencia entre entonces y ahora, o en delta2(...) para obtener el cambio de ese cambio, útil para detectar un valor que se está acelerando en lugar de solo desviándose (un tiempo de respuesta que sube cada vez más rápido en cada comprobación). previous.body.hash eq body.hash de arriba es exactamente esto: "¿coincide la huella del cuerpo con la que tenía la última vez?". delta(body.size, h) lee el cambio como una tasa por hora en lugar de una diferencia en bruto, para valores que esperas que crezcan de forma constante en lugar de dar saltos.
La primera vez que se ejecuta una regla así no tiene nada con qué comparar, así que se omite en lugar de fallar: la comprobación se marca como "calentando", no como rota, y añadir la regla no genera ninguna alerta falsa. El calentamiento solo se aplica cuando la lectura actual es correcta y falta la base de referencia. Si la propia lectura actual falla (por ejemplo, el cuerpo no es JSON válido esta vez), la regla falla exactamente como lo haría su versión simple, sin previous.. Una regla así también necesita que el valor cambie entre comprobaciones, lo que la hace inútil en un método de comprobación que nunca hace avanzar el estado, una petición HEAD por ejemplo.
Comparar contra la comprobación anterior necesita un plan de nivel superior; sin él, esos sujetos aparecen en gris en el editor con una explicación.
Límites, y qué falta deliberadamente
Cuántas reglas puedes añadir depende de tu plan, mostrado como un contador en vivo junto a "Añadir regla". El motor también impone un tope absoluto en cada comprobación sin importar el plan, una salvaguarda contra el abuso más que un límite para el uso normal: una comprobación con un número de reglas cercano a ese tope ya sería inusualmente grande.
No hay forma de escribir JavaScript personalizado para una regla, y nunca la habrá. Cada regla se construye a partir de un vocabulario fijo y con nombre de sujetos y predicados en lugar de un entorno de scripting abierto, lo que mantiene una regla legible de un vistazo y segura de ejecutar en todos los agentes de monitorización del mundo.
No todas las reglas funcionan en todas partes en el momento en que se escriben: algunas condiciones más nuevas necesitan una versión reciente del agente de monitorización que ejecuta tu comprobación, así que una nueva capacidad tarda un tiempo en llegar a todas las comprobaciones de tu cuenta a medida que los agentes se actualizan en segundo plano. Las reglas construidas sobre el núcleo estable del lenguaje no se ven afectadas.
Un puñado de entradas de esta referencia todavía no están del todo disponibles, y cada una lleva su etiqueta en la tabla correspondiente de arriba:
- Reservado (declarado, todavía sin rellenar por ningún agente):
ttfb,httpVersion,cert.subject. - Candidato (ya desplegándose, todavía no en todos los agentes):
conn.ip.familyyconn.failedIpsen comprobaciones HTTP, de puerto y Ping,value.typeen comprobaciones SNMP,banner.hashybanner.sizeen comprobaciones de puerto,sentCounten comprobaciones Ping, y el propiotimede la comprobación Counter. - Todavía no disponible:
steps, reservado para un futuro tipo de comprobación de varios pasos. - Requiere un plan con aserciones con estado: toda la familia de envoltorios
previous/delta/delta2, en todos los tipos de comprobación.
Todo lo demás en esta referencia está disponible hoy en todos los planes que tienen modo de aserciones.
Dónde funciona hoy el modo de aserciones
El interruptor de Validación de respuesta para el modo de aserciones aparece en monitores HTTP (sitio web) y API, que comparten el mismo editor y sintaxis de reglas. El mismo lenguaje y evaluador ya funcionan por debajo en comprobaciones de base de datos, Counter, puerto, Ping y SNMP a nivel de protocolo: el registro de arriba sirve a los seis tipos de comprobación, y una regla guardada para uno se lee igual si el modo llega más adelante al editor de otro tipo.
SNMP muestra la vista previa más clara: su editor ya tiene un panel de reglas de aserciones que nombra value y value.type, etiquetado como "Próximamente", sin ninguna lista de reglas funcional detrás todavía. Las comprobaciones de base de datos, Counter y Ping no muestran ningún panel de modo de aserciones en absoluto, aunque sus sujetos están igualmente disponibles en el motor que hay debajo.
Configurar una comprobación real
Si estás validando una API REST en lugar de una página web simple, empieza por validación de respuesta de API, que cubre juntos la disponibilidad, el tiempo de respuesta y el cuerpo de tu propia API. Para una página o sitio que necesita seguir activo y responder correctamente desde todos los sitios donde están tus usuarios, la monitorización de disponibilidad global desde más de 300 ubicaciones es el panorama más amplio en el que encaja el modo de aserciones. Para configurar reglas por código en lugar de por el panel, la API v2 propia de HostTracker crea y actualiza las reglas de aserciones de un monitor de la misma forma que lo hace el editor. Para la regla de caducidad de certificado de arriba y todo lo demás sobre TLS, la monitorización de dominio y certificado TLS cubre el tipo de comprobación en el que viven cert.days.left y los demás sujetos TLS. Para ver evaluarse una regla contra una URL real ahora mismo, sin cuenta, usa la herramienta gratuita de comprobación HTTP. Para los códigos de estado contra los que compara el sujeto status, empieza por 200 OK, y las guías de monitorización cubren cómo configurar cada tipo de comprobación bajo el que funciona este lenguaje.
Preguntas frecuentes
¿Qué pasa con mi configuración antigua de código de estado y palabra clave si activo el modo de aserciones?
Se sustituyen por la lista de reglas mientras el modo está activo. Volver a desactivarlo antes de guardar restaura los campos clásicos exactamente como estaban: no se borra nada, los dos modos simplemente no pueden estar activos a la vez.
¿Puedo combinar varias condiciones en un mismo monitor?
Sí: todas las reglas de la lista tienen que aprobar. Todavía no hay un "OR" entre reglas independientes, así que para aceptar uno de varios valores usa una sola regla con in [...] o containsAny [...].
¿El modo de aserciones algún día me dejará escribir mi propio script?
No. Cada regla se compone a partir del conjunto fijo de sujetos y predicados del lenguaje. No hay JavaScript personalizado, por diseño.
¿Qué pasa la primera vez que añado una regla que compara con la comprobación anterior?
Todavía no tiene nada con qué comparar, así que se marca como calentando y se omite en lugar de fallar. Añadir una regla de "esto cambió" nunca genera por sí sola una alerta falsa.
¿Necesito un plan específico para usar el modo de aserciones?
El modo en sí y las reglas del día a día (estado, cuerpo, cabeceras, tiempos, redirecciones) están ampliamente disponibles; cuántas reglas puedes añadir a la vez depende de tu plan y se muestra en vivo en el editor. Las reglas que comparan contra una comprobación anterior (previous, delta, delta2) necesitan un plan de nivel superior y aparecen en gris con una explicación.
¿El modo de aserciones funciona en monitores API igual que en monitores de sitio web?
Sí. Los monitores HTTP y API comparten el mismo editor de reglas, sujetos y predicados, y una regla escrita para uno se lee de forma idéntica en el otro.
¿Qué hace realmente where(...), y cuándo lo necesito?
Filtra una colección hasta los elementos que cumplen una condición antes de que leas un campo del resultado. Úsalo cuando una proyección simple como requests.status no sea lo bastante específica y necesites un salto, enlace o elemento concreto en lugar de toda la colección (ver la sección de arriba).
¿Puedo escribir hoy una regla contra una consulta de base de datos, un valor SNMP, un banner de puerto o un resultado de ping?
El lenguaje y el evaluador los admiten todos, y las tablas de sujetos de arriba cubren cada uno. El editor de reglas no: hoy solo los monitores HTTP y API muestran el interruptor de Validación de respuesta. SNMP muestra una vista previa de "Próximamente" con sus dos sujetos, y las comprobaciones de base de datos, Counter y Ping no muestran ningún panel de modo de aserciones en absoluto.
¿Por qué algunos sujetos de esta referencia dicen "reservado" o "candidato" en lugar de listarse con normalidad?
"Reservado" significa que el campo está declarado en el registro pero ningún agente lo rellena todavía; "candidato" significa que se está desplegando a los agentes pero todavía no ha llegado a todos. Ambos se señalan allí donde aparecen en esta referencia y en la lista resumen de la sección de Límites de arriba.