Ir para o conteúdo principal

Guias / Guias de monitoramento: cada tipo de verificação, passo a passo

Modo de asserções: referência completa de validação

O modo de asserções substitui os campos fixos de aprovado/reprovado de um monitor por uma lista de regras que você mesmo escreve, cada regra nomeando exatamente o que precisa ser verdade sobre a resposta. A maioria dos monitores de uptime julga uma verificação com um punhado de campos fixos: um código de status que conta como "fora do ar", uma lista de status a ignorar, talvez uma palavra-chave que precisa aparecer em algum lugar no corpo. Esses campos não conseguem expressar uma API que legitimamente responde 404 para um recurso ausente, uma página que devolve 200 com uma casca vazia porque o banco de dados deu timeout, ou uma cadeia de redirecionamento que começa a passar pelo domínio de outra pessoa.

O modo de asserções da HostTracker substitui esses campos fixos por uma pequena linguagem de regras que você escreve, regra por regra, dentro do editor do monitor. Cada regra diz exatamente o que precisa ser verdade sobre a resposta: o status, um trecho do corpo, um cabeçalho, quanto tempo levou, para onde um redirecionamento foi parar. Uma verificação falha apenas quando uma das suas regras falha. É a mesma linguagem para um site, uma API REST, uma consulta de banco de dados, uma porta TCP, um alvo de Ping, um contador SNMP ou uma verificação de Counter genérica: um único conjunto de sujeitos, um único conjunto de predicados, reutilizados em todo lugar onde o modo aparece. Este guia cobre todo sujeito, operador, redutor, atalho de açúcar sintático e forma de sintaxe que o motor implementa.

O que o modo de asserções substitui

Os campos clássicos de Validação de Resposta continuam lá quando o modo de asserções está desligado: um intervalo de status esperado, uma lista de status a ignorar, uma palavra-chave que precisa (ou não pode) aparecer. O modo é um interruptor que troca esse conjunto fixo por uma lista de regras que você mesmo constrói, e desligá-lo de novo antes de salvar traz os campos clássicos de volta imediatamente. Nenhum monitor fica preso a um modo permanentemente.

Uma única linguagem em vez de uma pilha de mecanismos específicos por tipo se compõe. Uma verificação "precisa ser JSON e conter um campo", uma verificação "ainda precisa dizer Adicionar ao carrinho" e uma verificação "não pode ter ficado mais lenta" são três regras na mesma sintaxe, na mesma lista, cada uma passando ou falhando por conta própria.

Ativando o modo

O modo de asserções fica dentro da seção Validação de Resposta do editor do monitor, para monitores HTTP (site) e API. Ative o interruptor, e os campos clássicos são substituídos por uma lista numerada de regras com um botão "Adicionar regra" e um contador ao vivo mostrando quantas regras você usou em relação ao limite do seu plano.

Modo de asserções ativado, com a primeira regra construída e validada

Cada regra é validada conforme você a constrói: uma regra ainda não terminada carrega um estado distinto de "inacabada", e uma regra que o editor consegue avaliar é marcada como completa. Toda regra também tem um pequeno botão </> que abre a forma de texto puro da fonte dela, para que você possa ler ou copiar a expressão exata em vez de só a visão caixa por caixa.

O modelo mental: sujeito, predicado, valor

Toda regra tem o mesmo formato: um sujeito (o código de status, o corpo, um cabeçalho, o tempo de resposta), um predicado (igual a, contém, existe, é menor que) e, para a maioria dos predicados, um valor para comparar. status eq 200 é sujeito, predicado e valor; body.json exists é um sujeito e um predicado sem valor, porque "existe" não precisa de mais nada.

Construir uma regra no editor começa escolhendo o que verificar, depois a condição, depois o valor:

Construindo uma segunda regra: o seletor de campo lista cada sujeito com seu tipo e um exemplo

As regras na lista são combinadas com E: uma verificação falha quando qualquer regra individual falha e passa apenas quando todas as regras passam. Ainda não existe OU, então, para aceitar um entre vários status ou textos, expresse isso dentro de uma única regra (status in [200, 301, 302], body containsAny ["In stock", "Pre-order"]). Uma regra que falha se nomeia no alerta, então dê um rótulo curto a cada uma onde puder, e o alerta vai dizer qual expectativa quebrou.

O que você pode verificar

O seletor agrupa os sujeitos entre o próprio documento da resposta (o corpo, os cabeçalhos) e o transporte dela (status, tempo, redirecionamentos, TLS). Alguns dos sujeitos mais importantes, com a lista completa na referência a seguir:

SujeitoO que éExemplo
statusO código de status HTTP da resposta final, depois de os redirecionamentos serem seguidosstatus isOk
bodyO corpo da resposta como texto purobody contains "Add to cart"
body.json / body.xml / body.html / body.yamlO corpo, mas só quando ele realmente é interpretável nesse formato - caso contrário o sujeito simplesmente não está presentebody.json exists
body.json.path("$.a")Uma consulta JSONPath dentro de um corpo JSON (a mesma linguagem de consulta também funciona sobre YAML, já que YAML é interpretado no mesmo modelo de objeto)body.json.path("$.status") eq "ok"
body.size / body.hashO tamanho da resposta em bytes, e uma impressão digital do conteúdo do corpobody.size gt 1kb
header("Name")Um cabeçalho da resposta, buscado pelo nomeheader("Content-Type") isJson
time e time.connect / time.tls / time.dns / time.headTempo total de resposta, e suas fases de rede, handshake TLS, DNS e tempo de processamento do servidortime lt 2s
redirects / requestsOs saltos que uma verificação seguiu, e a cadeia completa (incluindo a resposta final)redirects.count eq 0
url e suas partes (.host, .scheme, .path...)A URL final em que a verificação chegouurl.scheme eq "https"
cert.days.leftDias restantes antes de o certificado TLS vencercert.days.left gt 14

Os números aceitam sufixos de unidade para que você nunca precise converter na mão: 2s significa 2000 milissegundos, 1kb significa 1024 bytes. As comparações de texto diferenciam maiúsculas de minúsculas, a menos que você adicione nocase à regra.

A referência completa

O que vem a seguir é todo sujeito, operador, redutor, atalho de açúcar sintático, filtro e forma de sintaxe que o motor de asserções registra para verificações HTTP e API, tirado diretamente do registro do próprio motor (os mesmos dados que alimentam os seletores do editor de regras e a sua documentação). As entradas que ainda não estão totalmente disponíveis carregam uma nota entre parênteses: campos reservados que o motor ainda não começou a popular, candidatos ainda em fase de lançamento para os agentes, e a família com estado que precisa de um plano específico. Qualquer coisa sem essa nota já está disponível hoje em todo plano que tem o modo de asserções.

A referência segue o agrupamento do próprio motor: campos da resposta, depois as formas de acessar um corpo, depois tempo, rede e TLS, depois os operadores, redutores e atalhos que funcionam sobre todos eles, depois os tipos de verificação além de HTTP que falam a mesma linguagem.

Resposta

Os sujeitos que descrevem a própria resposta: seu status, seu corpo bruto, seus cabeçalhos, a URL de onde ela de fato respondeu, e a cadeia de requisições que chegou até ali.

NomeO que éTipo/valoresExemplo
bodyO corpo da resposta como texto decodificado.textobody contains "Welcome"
headerUm cabeçalho da resposta final, pelo nome.textoheader("Content-Type") isJson
redirectsOs saltos de redirecionamento seguidos - a cadeia de requisições sem o último elemento.coleçãoredirects.count eq 0
statusO código de status HTTP da resposta final, depois de os redirecionamentos serem seguidos.númerostatus isOk
body.sizeO tamanho do corpo baixado, em bytes.númerobody.size lt 500000
urlA URL que efetivamente respondeu, depois de todos os redirecionamentos. Uma url: compare-a como texto, ou leia suas partes (url.host, .port, .path, .query, .scheme).urlurl.host eq "www.example.com"
requestsToda requisição que essa verificação fez, em ordem - os saltos de redirecionamento e depois a requisição final.coleçãorequests.count le 2
url.hostA parte de host da URL.textourl.host eq "example.com"
url.pathA parte de caminho da URL.textourl.path startsWith "/api"
url.portA parte de porta da URL.númerourl.port eq 443
url.queryA string de consulta da URL.textourl.query contains "token"
url.schemeO esquema da URL (http ou https).textourl.scheme eq "https"
body.hashUm resumo (digest) do corpo da resposta - compare com previous.body.hash para detectar mudanças de conteúdo.textobody.hash eq previous.body.hash
httpVersion (reservado - ainda não populado)A versão de HTTP negociada.textohttpVersion eq "HTTP/2"
setCookieOs valores de Set-Cookie da resposta final, um item por cookie - combine um com contains ou matches, conte-os com .count.coleçãosetCookie exists
steps (ainda não disponível)As etapas de uma verificação em várias etapas. Ainda não disponível.coleçãosteps.count le 1
url.originalA URL com que a verificação foi configurada, antes de qualquer redirecionamento. Uma url como a própria url: tem as mesmas partes (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.original.hostA parte de host da URL.textourl.original.host eq "example.com"
url.original.pathA parte de caminho da URL.textourl.original.path startsWith "/start"
url.original.portA parte de porta da URL.númerourl.original.port eq 80
url.original.queryA string de consulta da URL.textourl.original.query contains "utm_"
url.original.schemeO esquema da URL (http ou https).textourl.original.scheme eq "http"

Dois apelidos: redirectCount é um atalho para redirects.count - redirectCount eq 0 lê um pouco mais naturalmente do que a forma longa equivalente quando você quer dizer "a verificação respondeu diretamente, sem redirecionamentos". E setCookie no nível superior é a lista de cookies da resposta final; o mesmo nome reaparece por salto dentro de requests/redirects (veja Sujeitos de salto abaixo), guardando apenas os cookies daquela requisição.

Extraindo valores do corpo

Esses sujeitos só se resolvem quando o corpo é o formato que eles nomeiam: um namespace JSON em uma página HTML simplesmente não está presente, não é um erro tipado. Isso faz de exists a forma padrão de sondar o formato, e body.json exists pergunta se o corpo foi interpretado como JSON. Os quatro namespaces de formato carregam cada um uma função .path(...) correspondente (JSONPath para json/yaml, XPath para xml, seletores CSS para html) e um .regex(...) correspondente, além de um body.regex(...) agnóstico de formato que lê o texto bruto independentemente do formato. body.html.a, body.html.script e body.html.link são coleções prontas de todo link, script e elemento <link> da página; veja Escopos de elemento abaixo para os campos disponíveis em cada um.

NomeO que éTipo/valoresExemplo
body.jsonO corpo da resposta, mas só quando realmente é JSON.textobody.json exists
body.json.pathConsulta o corpo JSON com uma expressão JSONPath.jsonbody.json.path("$.status") eq "ok"
body.htmlO corpo da resposta, mas só quando realmente é HTML.textobody.html exists
body.html.pathSeleciona elementos da página com um seletor CSS.coleçãobody.html.path("h1").first contains "Welcome"
body.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists
body.xmlO corpo da resposta, mas só quando realmente é XML.textobody.xml exists
body.xml.pathConsulta o corpo XML com uma expressão XPath.textobody.xml.path("//item/@id") exists
body.html.aTodo link da página.coleçãobody.html.a.count gt 0
body.html.linkTodo <link> que a página declara. Uma menção simples se refere aos alvos do link.coleçãobody.html.link.count gt 0
body.html.scriptTodo script que a página carrega. Uma menção simples se refere às fontes dos scripts.coleçãobody.html.script.count gt 0
body.yamlO corpo da resposta, mas só quando realmente é YAML.textobody.yaml exists
body.yaml.pathConsulta o corpo YAML com uma expressão JSONPath.jsonbody.yaml.path("$.services.web.image") contains ":1."
body.html.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists
body.json.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists
body.xml.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists
body.yaml.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists

Um detalhe da família de regex que vale destacar: grupos de captura nomeados ((?<id>...)) dentro de uma regra .regex(...) gravam em um namespace de vínculos com escopo de verificação que uma regra posterior pode ler de volta com bind("id") ou bind[0] por posição - veja Valores capturados abaixo.

Valores capturados

Um sujeito vive em seu próprio grupo do registro porque não lê a resposta diretamente - ele lê o que uma regra anterior capturou dela.

NomeO que éTipo/valoresExemplo
bindUm valor capturado por uma regra de regex anterior, pelo nome da captura ou pela posição.textobind("id") gt 1000

Combine com uma regra de regex anterior na lista: uma regra como body.regex("order-(?<id>\d+)") exists captura o id do pedido no nome id, e uma regra posterior pode testá-lo com bind("id") gt 1000 ou, para uma captura posicional (sem nome), bind[0].

Tempo

Um total mais uma divisão por fase, para que um alerta de "ficou mais lento" também possa dizer qual parte ficou mais lenta.

NomeO que éTipo/valoresExemplo
timeTempo total de resposta: conexão + TLS + espera + download. A resolução de DNS não está incluída.númerotime lt 2000
ttfb (reservado - ainda não populado)Tempo até o primeiro byte.númerottfb lt 200
time.connectTempo levado para estabelecer a conexão TCP.númerotime.connect lt 500
time.dataTempo levado para baixar o corpo da resposta.númerotime.data lt 1000
time.dnsTempo levado para resolver o nome de domínio. Não incluído no sujeito time simples.númerotime.dns lt 200
time.headTempo de espera pelos cabeçalhos da resposta.númerotime.head lt 500
time.tlsTempo levado pelo handshake TLS.númerotime.tls lt 300

O sujeito time simples é conexão + TLS + espera pelos cabeçalhos + download do corpo. A resolução de DNS fica de fora e só existe no irmão time.dns, porque o DNS costuma ficar em cache e faria o mesmo endpoint parecer inconsistentemente rápido ou lento entre verificações.

Rede: DNS e conexão

dns e conn são namespaces puros no registro - um grupo sem valor próprio, então uma regra nunca pode terminar no nome simples (o editor e o motor recusam uma cadeia que termina em dns ou conn sozinho, apontando para os campos reais abaixo).

NomeO que éTipo/valoresExemplo
connA conexão de rede que a verificação fez - o endereço que serviu a resposta e quaisquer falhas de conexão.texto-
conn.failedQuantos dos endereços resolvidos falharam ao conectar.númeroconn.failed eq 0
conn.failedIps (candidato - em rollout para os agentes)Os endereços resolvidos que falharam ao conectar.coleçãoconn.failedIps.count eq 0
conn.ipO endereço IP que efetivamente serviu a resposta.textoconn.ip eq "203.0.113.10"
conn.ip.family (candidato - em rollout para os agentes)Se a resposta foi servida sobre IPv4 ou IPv6.textoconn.ip.family eq "IPv4"
dnsResolução DNS do nome monitorado - para quais endereços ele resolveu e qual servidor respondeu.texto-
dns.ipsTodos os endereços IP para os quais o nome de domínio resolveu durante essa verificação.coleçãodns.ips contains "1.2.3.4"
dns.serverO servidor DNS que respondeu a resolução.textodns.server eq "8.8.8.8"

TLS e certificado

Assim como dns e conn, tls e cert são namespaces puros - os fatos do certificado/handshake ficam um nível abaixo.

NomeO que éTipo/valoresExemplo
cert.days.leftDias restantes até o certificado do site vencer.númerocert.days.left gt 14
certO certificado que o servidor apresentou - dias até o vencimento, emissor e campos de identidade.texto-
cert.daysDias desde que o certificado foi emitido.númerocert.days gt 0
cert.issuerA autoridade certificadora que emitiu o certificado do site.textocert.issuer contains "Let's Encrypt"
cert.sanOs nomes de domínio para os quais o certificado é válido.coleçãocert.san contains "www.example.com"
cert.serialO número de série do certificado.textocert.serial exists
cert.subject (reservado - ainda não populado)O assunto (subject) do certificado. Ainda não capturado - virá em uma versão futura do agente.textocert.subject contains "example.com"
tlsO handshake TLS da conexão segura - versão de protocolo e cifra negociadas.texto-
tls.cipherA suíte de cifra negociada.textotls.cipher contains "AES"
tls.protocolA versão de TLS negociada.textotls.protocol eq "Tls13"

cert.subject está listado aqui por completude mas ainda não está populado - veja a seção Honestidade abaixo para o que "reservado" significa na prática. A regra de certificado do dia a dia é cert.days.left gt 14, coberta na seção de regras prontas.

Sujeitos de salto: campos dentro de requests e redirects

requests e redirects são coleções, e cada item é um registro completo de requisição/resposta com o próprio conjunto reduzido de campos. Nem todo sujeito de nível superior faz sentido por salto (um salto não tem certificado próprio), e um campo existe só por salto: hstsHeader, o cabeçalho Strict-Transport-Security daquela requisição na cadeia.

NomeO que éTipo/valoresExemplo
statusO código de status dessa requisição na cadeia.númerostatus eq 200
urlA URL para a qual essa requisição foi feita.urlurl startsWith "https://"
headerUm cabeçalho de resposta dessa requisição. Um salto mantém um registro de cabeçalho reduzido, de valor único - predicados de lista (containsAny, containsAll, unique) se aplicam só ao cabeçalho da resposta final.textoheader("Content-Type") contains "json"
hstsHeaderO cabeçalho Strict-Transport-Security dessa requisição.textorequests[0].hstsHeader exists
setCookieOs valores do cabeçalho Set-Cookie dessa requisição.coleçãosetCookie exists
url.originalA URL com que a verificação foi configurada, antes de qualquer redirecionamento. Uma url como a própria url: tem as mesmas partes (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.hostA parte de host da URL.textourl.host eq "example.com"
url.portA parte de porta da URL.númerourl.port eq 443
url.pathA parte de caminho da URL.textourl.path startsWith "/api"
url.queryA string de consulta da URL.textourl.query contains "token"
url.schemeO esquema da URL (http ou https).textourl.scheme eq "https"
url.original.hostA parte de host da URL.textourl.original.host eq "example.com"
url.original.portA parte de porta da URL.númerourl.original.port eq 80
url.original.pathA parte de caminho da URL.textourl.original.path startsWith "/start"
url.original.queryA string de consulta da URL.textourl.original.query contains "utm_"
url.original.schemeO esquema da URL (http ou https).textourl.original.scheme eq "http"

O header(...) por salto mantém um registro reduzido, de valor único: predicados no formato de lista como containsAny ou unique só fazem sentido no mapa completo de cabeçalhos da resposta final, então se aplicam lá e não por salto. As duas coleções significam coisas diferentes. requests é a cadeia inteira incluindo a resposta final que respondeu, então nunca fica vazia mesmo para um 200 direto, enquanto redirects é só os saltos seguidos no caminho até lá, vazia quando nada redirecionou.

Escopos de elemento: campos dentro de um item de coleção

Um escopo de elemento é o conjunto de campos disponível em UM item de uma coleção - depois de indexar nele (requests[0]) ou enquanto o filtra com where(current. ...) (veja a próxima seção). Seis coleções carregam o próprio escopo de elemento: as quatro coleções de elementos HTML compartilham um formato, e requests/redirects compartilham o formato de sujeitos de salto documentado logo acima.

Escopo de elementoComo é um item
body.html.pathUm elemento encontrado por uma consulta CSS body.html.path("selector").
body.html.aUm elemento <a> de body.html.a.
body.html.scriptUm elemento <script> de body.html.script.
body.html.linkUm elemento <link> de body.html.link.
requestsUma requisição na cadeia completa (veja a tabela de sujeitos de salto acima).
redirectsUm salto de redirecionamento seguido (os mesmos campos de requests, veja acima).

O formato compartilhado para body.html.path(...), body.html.a, body.html.script e body.html.link - uma linha por link, tag de script ou elemento <link>:

NomeO que éTipo/valoresExemplo
urlO alvo do link exatamente como o HTML escreve.textobody.html.a.url contains "/checkout"
textO texto visível do elemento.textobody.html.a.text contains "Sign in"
absoluteO alvo do link resolvido contra a URL da página em um endereço absoluto - uma lista de urls, com as partes da url disponíveis por elemento (.host, .path, .port, .query, .scheme).urlbody.html.a.absolute.scheme in ["https"]
relO atributo rel do elemento.textobody.html.a.where(current.rel eq "nofollow").count eq 0
absolute.hostA parte de host da URL.textobody.html.a.absolute.host.unique.count le 3
absolute.portA parte de porta da URL.númerobody.html.a.absolute.port in [443]
absolute.pathA parte de caminho da URL.textobody.html.a.absolute.path startsWith "/"
absolute.queryA string de consulta da URL.textobody.html.a.absolute.query not contains "session"
absolute.schemeO esquema da URL (http ou https).textobody.html.a.absolute.scheme in ["https"]

Dois padrões se aplicam antes de você escrever uma regra sobre essas coleções. Uma menção simples de body.html.a (ou .script/.link) significa a projeção .url dela, então body.html.a.count gt 0 conta hrefs, e uma regra salva é lida de volta com .url escrito por extenso, porque uma regra salva sempre diz exatamente o que avalia. E .url é o atributo href bruto exatamente como o HTML o escreveu, então um link relativo continua relativo; .absolute é o mesmo link resolvido contra a própria URL da página, o que é o que você quer ao verificar o esquema ou o host de links de saída (body.html.a.absolute.scheme in ["https"]).

Operadores

A metade de predicado de toda regra: qual teste rodar contra o sujeito. Os 15 são compartilhados por todo tipo de verificação, e quais deles se encaixam em um dado sujeito depende do tipo dele (um código de status aceita lt/gt, um corpo aceita contains, uma coleção aceita exists/unique/in).

NomeO que éSe aplica aExemplo
eqIgual a. Contra um literal json("…") / xml("…") / yaml("…") é uma correspondência estrutural EXATA: mesmas chaves (em qualquer ordem), arrays na mesma ordem, mesmos valores.qualquer tipobody.json eq json("{\"ok\": true}")
ltMenor que.númerostime lt 2000
leMenor ou igual a.númeroscert.days.left le 30
gtMaior que.númerosbody.size gt 0
geMaior ou igual a.númerosstatus ge 500
containsContém o texto - sobre uma lista, passa quando o valor É um dos itens (correspondência exata; use matches para buscar dentro dos itens). Contra um literal json("…") / xml("…") / yaml("…") é uma CONTENÇÃO estrutural: tudo o que o literal declara precisa estar presente e bater; a resposta pode ter mais.texto ou listabody.json contains json("{\"status\": \"ok\"}")
startsWithComeça com o texto - sobre uma lista, quando QUALQUER item começa.textourl.path startsWith "/api"
endsWithTermina com o texto - sobre uma lista, quando QUALQUER item termina.textourl.path endsWith ".json"
matchesBate com a expressão regular em algum ponto do texto - sobre uma lista, quando QUALQUER item bate.textobody matches "order-\\d+"
containsAnyContém pelo menos um dos valores listados (sobre uma lista: algum item É IGUAL a um deles).listabody containsAny ["In stock", "Pre-order"]
containsAllContém todos os valores listados (sobre uma lista: cada valor é igual a algum item - as testemunhas podem ser diferentes).listabody.html.a.text containsAll ["Home", "Contact"]
inÉ um dos valores ou intervalos listados - sobre uma lista, todo item é.valor(es) ou intervalostatus in [200, 301, 302]
existsO sujeito está presente.qualquer sujeitoheader("ETag") exists
isNumberO valor pode ser lido como número.texto ou qualquerbind("id") isNumber
uniqueA lista não tem duplicatas.listadns.ips unique

Dois operadores significam algo mais restrito do que parecem. contains sobre uma lista é associação exata: o valor precisa ser igual a um item inteiro, não aparecer como substring dentro de um, então recorra a matches quando quiser comportamento de substring pelos elementos de uma coleção. E eq contra um literal json(...)/xml(...)/yaml(...) é uma correspondência estrutural completa (mesmas chaves, arrays na mesma ordem, mesmos valores), enquanto contains contra o mesmo tipo de literal é contenção estrutural: tudo o que o literal declara precisa estar presente, mas a resposta real pode carregar mais.

Redutores

Um redutor reduz uma coleção a um único valor e só pode aparecer no fim de uma cadeia. Os exemplos abaixo usam requests.status, a coleção naturalmente numérica que os sujeitos HTTP formam, como ilustração; os mesmos oito redutores funcionam sobre qualquer coleção numérica em qualquer tipo de verificação (os tempos de ida e volta de uma verificação Ping, um conjunto filtrado de linhas de banco de dados).

NomeO que reduzSe aplica aExemplo
countQuantos itens a lista tem.qualquer coleçãorequests.count le 2
minO menor número da lista.coleção numéricarequests.status.min ge 200
maxO maior número da lista.coleção numéricarequests.status.max lt 500
sumA soma dos números da lista.coleção numéricarequests.status.sum gt 0
avgA média dos números da lista.coleção numéricarequests.status.avg lt 300
firstO primeiro item da lista.qualquer coleçãoredirects.status.first eq 301
lastO último item da lista.qualquer coleçãorequests.status.last eq status
uniqueA lista sem duplicatas.qualquer coleçãodns.ips.unique.count le 3

unique é sobrecarregado, e a grafia distingue os dois sentidos. Escrito como operador sem ponto (x unique) é um predicado, "essa coleção não tem duplicatas", e falha nomeando a repetição. Escrito como redutor com ponto (x.unique) é uma transformação, a própria coleção deduplicada, que ainda precisa de algo depois (x.unique.count eq 1). Um x.unique solto sem nada depois é um erro de sintaxe, porque o motor não consegue adivinhar qual dos dois sentidos você quis.

Açúcar sintático

Os predicados de açúcar sintático são atalhos que o motor expande em predicados centrais comuns antes de a regra ser enviada a um agente - um predicado de açúcar não custa nada a mais para adicionar (nenhum pacote de agente, nenhum piso de versão) porque, quando chega na rede, já parece uma regra comum. Prefira o açúcar sintático sempre que existir: ele se lê melhor, e é exatamente equivalente a escrever a forma longa na mão.

NomeO que significaSe aplica aExemplo
isOkO status é um código de sucesso (200-299).status-
isRedirectO status é um código de redirecionamento (300-399).statusstatus isRedirect
isClientErrorO status é um erro de cliente (400-499).statusstatus isClientError
isServerErrorO status é um erro de servidor (500-599).statusstatus isServerError
isJsonO conteúdo realmente é JSON.documento ou texto de tipo de mídiaheader("Content-Type") isJson
isXmlO conteúdo realmente é XML - o corpo é interpretado como XML, ou um cabeçalho nomeia um tipo de mídia XML.documento ou texto de tipo de mídiabody isXml
isHtmlO conteúdo realmente é HTML - o corpo é interpretado como HTML, ou um cabeçalho nomeia um tipo de mídia HTML.documento ou texto de tipo de mídiabody isHtml
isFormUm tipo de mídia nomeia uma codificação de formulário: application/x-www-form-urlencoded ou multipart/form-data. Diferente de isJson/isXml/isHtml, não há um namespace de corpo correspondente, então isso só se aplica a um valor de tipo de mídia, como um cabeçalho Content-Type.somente texto de tipo de mídiaheader("Content-Type") isForm
isEmptyNada ali: um texto vazio, um tamanho zero ou uma lista vazia.texto, tamanho ou listabody isEmpty
isNullO valor é nulo.qualquer valorbody.json.path("$.deletedAt") isNull
absentO sujeito não está presente de forma alguma.qualquer sujeitoheader("X-Debug") absent
betweenUm número dentro de um intervalo inclusivo.números (2 operandos)body.size between 50 and 500kb

isJson/isXml/isHtml são sensíveis ao contexto de propósito, e o que você escreve determina qual sentido se aplica. Escritos sobre o próprio documento (body isJson) significam "isso é interpretável nesse formato", o mesmo que body.json exists. Escritos sobre um valor de texto que nomeia um tipo de mídia, como um cabeçalho (header("Content-Type") isJson), significam "isso nomeia a família MIME desse formato"; veja Famílias MIME abaixo para quais tipos de mídia se qualificam. isForm só tem o segundo sentido, já que não existe um namespace body.form para interpretar, então body isForm é um erro estático em vez de uma regra que nunca poderia ser verdadeira.

O filtro where(...)

Mantém só os elementos que combinam, e continua a partir daí. É o único mecanismo de filtragem da linguagem, e tem exatamente um formato: where(current.<campo> <condição> <valor>).

Filtrar é diferente de projetar: requests.url contains "cart" pergunta se tal salto existe em algum ponto da cadeia, enquanto requests.where(current.url contains "cart").status pergunta o que aquele salto devolveu. Filtrar não reduz a lista, então termine com .first, uma verificação in [...], ou .count. Vai só um nível, e recebe exatamente uma condição.

ParteO que nomeiaNotas
current.<campo>Um campo de cada elemento sendo filtrado, escrito depois de current.Essa é a metade que as pessoas erram: current.url é a URL do salto individual, não a da resposta final. Só os campos próprios do elemento podem vir depois de current..
a condiçãoQualquer predicado comum, incluindo not e nocaseQualquer condição que funciona no nível superior de uma regra também funciona aqui.
o valorContra o que o campo de cada elemento é comparadoGeralmente um valor simples. Um sujeito escrito aqui é lido da resposta EXTERNA, não do elemento - where(current.url eq url.original) compara cada salto contra a URL com que a verificação foi configurada, e é por isso que o lado do elemento precisa dizer current. explicitamente.

Exemplo: requests.where(current.url contains "cart").status.first eq 301 - mantém só os saltos cuja URL contém "cart", depois olha o status do primeiro que combinou.

Mais dois limites, ambos aplicados pelo analisador com a própria mensagem: where não pode ser aninhado dentro de outro where, e o argumento dele é exatamente uma condição, sem and/or dentro. Só se aplica a uma coleção cujos elementos carregam campos nomeados (requests, body.html.a), não a uma lista projetada simples como dns.ips, onde não há nada para current. nomear.

Referência de sintaxe

Tudo o mais que a gramática define: como nomear uma regra, como escrever intervalos e listas, o que um sujeito solto significa, e as pequenas formas de pontuação que aparecem em várias regras.

FormaO que fazTipoExemplo
whereMantém só os elementos que combinam, e continua a partir daí.filtro de coleçãorequests.where(current.url contains "cart").status.first eq 301
notInverte a condição que segue.sinalizadorbody not contains "error"
nocaseCompara texto sem diferenciar maiúsculas de minúsculas.sinalizadorbody contains "welcome" nocase
currentDentro de where(…), nomeia o único elemento sendo filtrado.referência de elemento (dentro de where)requests.where(current.status eq 301)
rangeUm intervalo de números, com AMBAS as pontas INCLUÍDAS.intervalo numéricostatus in [200..299]
listUma lista de valores para comparar.lista de valoresstatus in [200, 301, 302]
docLiteralUm valor de documento tipado para comparação estrutural: o texto entre aspas é interpretado como JSON, XML ou YAML quando a regra é salva.texto json/xml/yamlbody.json contains json("{\"user\": {\"active\": true}}")
implicitExistsUma regra que nomeia só um sujeito verifica que ele está presente: escrever apenas body.json salva como body.json exists.linha de sujeito soltobody.json
indexEscolhe UM item de uma lista pela posição, contando a partir de 0.inteiro de base 0requests[0].status
labelUm nome opcional para a regra, escrito antes de dois-pontos.nome antes de dois-pontos"json ok": body.json exists
commentTudo depois de # é uma nota para você mesmo; não afeta a verificação.texto # no finalstatus isOk # the happy path

Alguns valem uma passagem em português claro. label dá um nome à regra que aparece no alerta em vez da expressão renderizada; escreva-o antes de dois-pontos, como em "json ok": body.json exists. implicitExists significa que uma linha que nomeia só um sujeito e nenhum predicado é um atalho para exists: escrever body.json salva como body.json exists, e reabrir a regra mostra a forma por extenso. range e list são as duas formas que um valor pode ter depois de in: um intervalo ([200..299], com ambas as pontas incluídas) ou uma lista explícita ([200, 301, 302]), e um valor pode ficar em aberto de qualquer lado ([400..]). docLiteral é o wrapper json(...)/xml(...)/yaml(...) usado para comparação estrutural contra o corpo (coberto em Operadores acima e nas regras prontas abaixo). index escolhe um item de uma coleção pela posição, com base 0, da mesma forma que bind[0] lê uma captura posicional. current só tem sentido dentro de um filtro where(...), coberto na própria seção acima.

Wrappers: previous, delta e delta2

Três formas que olham para trás em vez de só para a resposta atual - cada uma restrita a planos com asserções com estado, e cada uma explicada por completo em "Comparando com a verificação anterior" abaixo.

NomeO que éTipo/valoresExemplo
delta (exige um plano com asserções com estado)Quanto um valor numérico mudou desde a verificação anterior - opcionalmente como uma taxa por ms/s/m/h.númerodelta(body.size, h) lt 1mb
delta2 (exige um plano com asserções com estado)A mudança da mudança - um valor está acelerando?númerodelta2(time) gt 0
previous (exige um plano com asserções com estado)O valor que esse sujeito tinha na verificação anterior.qualquerstatus eq previous.status

Sinalizadores: not e nocase

Dois modificadores que se anexam a uma regra em vez de serem sujeitos ou predicados por conta própria.

SinalizadorO que fazTipoExemplo
notInverte a condição que segue.sinalizador (se anexa a uma regra)body not contains "error"
nocaseCompara texto sem diferenciar maiúsculas de minúsculas.sinalizador (se anexa a uma regra)body contains "welcome" nocase

not se combina com o predicado que segue em vez de negar a regra inteira como unidade - x not != y se lê como x eq y, não como dupla negação. Quando um sujeito pode estar totalmente ausente, prefira o açúcar sintático absent a not exists: os dois significam exatamente a mesma coisa, mas absent diz isso diretamente. nocase só muda alguma coisa em uma comparação genuinamente textual; o editor (e esta referência) ainda deixam você escrevê-lo em qualquer lugar, mas ele é silenciosamente sem efeito em um teste numérico como status eq 200 nocase.

Famílias MIME

As tabelas de consulta por trás de isJson, isXml, isHtml e isForm quando aplicados a um valor de tipo de mídia, como um cabeçalho. Cada família combina com o tipo de mídia de nível superior óbvio mais, para JSON e XML, qualquer tipo que termine no sufixo de sintaxe estruturada correspondente - o que faz header("Content-Type") isJson passar corretamente em application/problem+json ou application/vnd.api+json e não só no simples application/json.

FamíliaCombina comAçúcar correspondenteExemplo
jsonapplication/json, text/json, ou qualquer tipo de mídia terminado em +json (application/problem+json, application/vnd.api+json, application/ld+json, ...).açúcar: isJsonheader("Content-Type") isJson
xmlapplication/xml, text/xml, ou qualquer tipo de mídia terminado em +xml (image/svg+xml, application/atom+xml, ...).açúcar: isXmlheader("Content-Type") isXml
htmltext/html ou application/xhtml+xml.açúcar: isHtmlheader("Content-Type") isHtml
formapplication/x-www-form-urlencoded ou multipart/form-data.açúcar: isFormheader("Content-Type") isForm

A correspondência ignora tudo a partir do primeiro ; em diante (então application/json; charset=utf-8 ainda combina) e não diferencia maiúsculas de minúsculas.

Sujeitos para verificações de banco de dados, counter, SNMP, porta e ping

Todo operador, redutor, atalho de açúcar sintático e forma de sintaxe acima é idêntico para esses cinco tipos de verificação: o motor registra os mesmos 15 operadores, 8 redutores, 12 predicados de açúcar e 11 formas de sintaxe para todos os seis tipos sem exceção. O que muda por tipo é a lista de sujeitos. Cada tipo expõe um pequeno conjunto de sujeitos exclusivos do que mede, mais um subconjunto dos sujeitos de rede/tempo/TLS já documentados acima, com o significado se adaptando ao tipo (o time de uma verificação de Database é conexão-mais-consulta em vez de conexão-mais-TLS-mais-download, já que não há uma resposta HTTP para baixar).

Verificações de banco de dados

Compartilha time, time.connect e time.dns com os sujeitos documentados acima (com o escopo redefinido para uma conexão de banco de dados: conexão-mais-consulta, resolução DNS do host do banco). Exclusivos das verificações de banco de dados:

NomeO que éTipo/valoresExemplo
scalarO valor único que a consulta devolveu (modo Scalar).qualquer-
rowsAs linhas que a consulta afetou ou devolveu (modo NonQuery).coleção-
time.queryTempo que a própria consulta levou.número-

Um exemplo pronto está na próxima seção: use rows.count para verificar quantas linhas uma consulta afetou ou devolveu, e scalar para verificar diretamente um único valor devolvido.

Verificações de counter

Compartilha time com os sujeitos documentados acima - como campo em status candidato especificamente para verificações de Counter (tempo de ida e volta da requisição do counter; veja a seção Honestidade para o que "candidato" significa). Exclusivo das verificações de counter:

NomeO que éTipo/valoresExemplo
valueO valor medido do counter.número-

Verificações SNMP

Compartilha time e time.dns com os sujeitos documentados acima (resolução do nome de host mais a própria requisição SNMP). Exclusivos das verificações SNMP:

NomeO que éTipo/valoresExemplo
time.requestTempo que a requisição SNMP levou.número-
valueO valor que o OID devolveu.qualquer-
value.type (candidato - em rollout para os agentes)O nome do tipo de dado SNMP do valor devolvido.texto-

value.type está em status candidato; veja a seção Honestidade. Nota sobre disponibilidade: o interruptor de Validação de Resposta do modo de asserções ainda não chegou ao editor de monitor SNMP. Ele mostra um painel "Em breve" nomeando esses dois sujeitos em vez de uma lista de regras funcional. Os sujeitos e o avaliador por baixo já estão registrados; só a interface do editor SNMP está pendente.

Verificações de porta

A maior lista compartilhada de qualquer tipo não-HTTP. Uma verificação de porta TCP carrega essencialmente os mesmos sujeitos de conexão, DNS, TLS e certificado que uma verificação HTTP, já que uma verificação de porta também pode negociar TLS: bind, cert e seus seis subcampos, conn e seus quatro subcampos, dns e seus dois subcampos, time/time.connect/time.dns/time.tls, e tls/tls.cipher/tls.protocol - todos documentados nas seções acima, com os mesmos significados. Exclusivos das verificações de porta:

NomeO que éTipo/valoresExemplo
bannerOs dados lidos do socket depois de conectar.texto-
banner.hash (candidato - em rollout para os agentes)Um resumo (digest) do banner - compare com previous.banner.hash para detectar mudanças de serviço.texto-
banner.regexCombina o texto com uma expressão regular e pega o que foi capturado.textobody.regex("order-(?<id>\\d+)") exists
banner.size (candidato - em rollout para os agentes)O tamanho do banner, em bytes.número-

banner.hash e banner.size estão em status candidato - veja a seção Honestidade. banner.regex já está disponível hoje e funciona exatamente como body.regex(...) em uma verificação HTTP: capturas nomeadas alimentam o mesmo namespace bind(...).

Verificações de ping

Compartilha os sujeitos de conexão e DNS com as seções acima: conn, conn.failed, conn.failedIps, conn.ip, conn.ip.family, dns, dns.ips, dns.server, time (aqui, o tempo médio de ida e volta das respostas bem-sucedidas) e time.dns. Exclusivos das verificações de ping:

NomeO que éTipo/valoresExemplo
lossA porcentagem de pedidos de eco que não obtiveram resposta.númeroloss eq 0
replyAs respostas de eco bem-sucedidas.coleção-
sentCount (candidato - em rollout para os agentes)Quantos pedidos de eco foram enviados.número-
time.maxO tempo de ida e volta da resposta mais lenta.número-
time.minO tempo de ida e volta da resposta mais rápida.número-
ttlO TTL da primeira resposta bem-sucedida - compare com previous.ttl para notar mudanças de rota.número-

sentCount está em status candidato - veja a seção Honestidade. ttl vale a pena conhecer mesmo fora de uma regra estrita de aprovado/reprovado: combiná-lo com previous.ttl (veja Wrappers acima) sinaliza uma mudança de rota entre verificações, já que o tempo de vida de um pacote na chegada reflete quantos saltos ele atravessou.

Regras que as pessoas realmente querem escrever

A página está no ar e realmente diz a coisa certa

Um código de status sozinho não consegue dizer se uma página renderizou corretamente - uma resposta 200 com uma casca vazia é a clássica falha silenciosa que uma verificação só de status não pega.

status isOk
body contains "Add to cart"

Uma API responde com JSON e o campo esperado

Verifique se o endpoint ainda fala JSON, depois busque dentro dele. A primeira linha pega uma página de erro em HTML servida onde deveria haver JSON, um formato comum de indisponibilidade atrás de um proxy; a segunda verifica a própria saúde reportada pela API, não só o status de transporte.

body isJson
body.json.path("$.status") eq "ok"

A resposta ficou mais lenta do que deveria

Detalhe quando você precisa saber o que corrigir e não só que algo está lento - time.connect, time.tls, time.dns e time.head separam tempo de rede, de handshake, de resolvedor e de aplicação.

time lt 2s

Um redirecionamento enviou visitantes para fora do seu domínio

Compara onde a verificação terminou contra a URL que você configurou - falha no momento em que uma cadeia de redirecionamento, sequestrada, mal configurada, ou apenas mudada por uma implantação, chega a algum lugar que você não pretendia.

url.host eq url.original.host

A página mudou desde a última verificação

Útil em conteúdo que deveria ficar estável entre verificações - preços, termos, uma política publicada - e também funciona como um sinal básico de desfiguração (defacement).

previous.body.hash eq body.hash

Um número dentro de um intervalo, escrito da forma curta

Pega tanto uma página reduzida demais quanto uma descontrolada em uma única regra, sem escrever um intervalo explícito.

body.size between 50 and 500kb

Um certificado prestes a vencer

A verificação TLS mais comum de todas, e uma que um monitor simples de no-ar/fora-do-ar não consegue expressar de jeito nenhum - um certificado que ainda é válido hoje mas vence semana que vem não dá nenhum outro sinal de aviso. Combine com cert.issuer se você também quiser pegar um certificado emitido silenciosamente pela autoridade errada.

cert.days.left gt 14

Uma consulta de banco de dados devolvendo o número errado de linhas

Em uma verificação de Database, rows é a coleção que uma consulta afetou ou devolveu - contá-la pega uma consulta que deveria devolver exatamente um registro de conta silenciosamente começando a devolver zero (apagado, ou um join quebrado) ou mais de um (uma duplicata que não deveria existir).

rows.count eq 1

Um valor SNMP saindo da faixa

Um dispositivo SNMP que responde não é a mesma coisa que um saudável - um OID monitorado (uso de disco, profundidade de fila, temperatura) pode subir bem além de um limite seguro enquanto o dispositivo em si continua perfeitamente alcançável. Comparar o value consultado contra uma faixa pega o que uma verificação simples de alcançabilidade não consegue.

value lt 90

Um serviço TCP respondendo com o banner errado

Uma porta que aceita conexões não é a mesma coisa que o serviço certo escutando nela - um processo travado, um proxy mal configurado, ou um serviço rebaixado/substituído ainda podem completar um handshake TCP. Ler o texto de saudação que um serviço envia logo após conectar (um banner de SMTP, FTP ou similar) pega o que uma verificação simples de porta aberta não consegue.

banner contains "220"

Comparando com a verificação anterior

Um punhado de sujeitos olha para trás em vez de só para a resposta atual: coloque previous. na frente de um sujeito para ler o que ele era na última verificação, ou envolva-o em delta(...) para obter a diferença entre antes e agora, ou em delta2(...) para obter a mudança dessa mudança - útil para identificar um valor que está acelerando em vez de apenas variando (um tempo de resposta que sobe mais rápido a cada verificação). previous.body.hash eq body.hash acima é exatamente isso - "a impressão digital do corpo bate com o que era da última vez". delta(body.size, h) lê a mudança como uma taxa por hora em vez de uma diferença bruta, para valores que você espera que cresçam de forma constante em vez de saltar.

Na primeira vez que uma regra assim roda, ela não tem nada para comparar, então é pulada em vez de falhar: a verificação é marcada como "aquecendo", não quebrada, e adicionar a regra não gera nenhum alerta falso. O aquecimento só se aplica quando a leitura atual é válida e falta a linha de base. Se a própria leitura atual falhar (digamos, o corpo não é JSON válido dessa vez), a regra falha exatamente como a versão dela sem previous. falharia. Uma regra assim também precisa que o valor mude entre verificações, o que a torna sem sentido em um método de verificação que nunca avança de estado, por exemplo uma requisição HEAD.

Comparar com a verificação anterior exige um plano de nível mais alto; sem ele, esses sujeitos aparecem esmaecidos no editor com uma explicação.

Limites, e o que está deliberadamente faltando

Quantas regras você pode adicionar depende do seu plano, mostrado como um contador ao vivo ao lado de "Adicionar regra". O motor também aplica um teto absoluto em toda verificação independentemente do plano, uma salvaguarda contra abuso e não um limite para o uso normal: uma verificação com um número de regras perto desse teto já seria incomumente grande.

Não há como escrever JavaScript personalizado para uma regra, e nunca haverá. Toda regra é construída a partir de um vocabulário fixo e nomeado de sujeitos e predicados em vez de um sandbox de script aberto, o que mantém uma regra legível à primeira vista e segura para rodar em todo agente de monitoramento do mundo.

Nem toda regra funciona em todo lugar no momento em que é escrita: algumas condições mais novas precisam de uma versão recente do agente de monitoramento que roda sua verificação, então uma capacidade nova leva tempo para chegar a toda verificação da sua conta conforme os agentes se atualizam em segundo plano. Regras construídas sobre o núcleo estável da linguagem não são afetadas.

Um punhado de entradas nesta referência ainda não está totalmente disponível, e cada uma está identificada na tabela correspondente acima:

  • Reservado (declarado, ainda não populado por nenhum agente): ttfb, httpVersion, cert.subject.
  • Candidato (já em rollout, ainda não em todo agente): conn.ip.family e conn.failedIps em verificações HTTP, de porta e ping, value.type em verificações SNMP, banner.hash e banner.size em verificações de porta, sentCount em verificações de ping, e o próprio time da verificação de Counter.
  • Ainda não disponível: steps, reservado para um futuro tipo de verificação em várias etapas.
  • Exige um plano com asserções com estado: toda a família de wrappers previous / delta / delta2, em todo tipo de verificação.

Tudo o mais nesta referência já está disponível hoje em todo plano que tem o modo de asserções.

Onde o modo de asserções funciona hoje

O interruptor de Validação de Resposta para o modo de asserções aparece em monitores HTTP (site) e API, que compartilham o mesmo editor de regras e sintaxe. A mesma linguagem e o mesmo avaliador já rodam por baixo das verificações de Database, Counter, Port, Ping e SNMP no nível de protocolo: o registro acima serve os seis tipos de verificação, e uma regra salva para um deles se lê da mesma forma se o modo chegar ao editor de outro tipo mais tarde.

O SNMP mostra o preview mais claro: o editor dele já tem um painel de regras de asserção nomeando value e value.type, rotulado "Em breve", sem nenhuma lista de regras funcional por trás ainda. As verificações de Database, Counter e Ping não mostram nenhum painel de modo de asserções, mesmo que os sujeitos delas estejam igualmente disponíveis no motor por baixo.

Configurando uma verificação de verdade

Se você está validando uma API REST em vez de uma página web simples, comece pela validação de resposta de API, que cobre o uptime, o tempo de resposta e o corpo da sua própria API juntos. Para uma página ou site que precisa continuar no ar e respondendo corretamente de todo lugar onde seus usuários estão, o monitoramento global de uptime a partir de mais de 300 localidades é o panorama mais amplo em que o modo de asserções se encaixa. Para configurar regras por código em vez de pelo painel, a própria API v2 da HostTracker cria e atualiza as regras de asserção de um monitor da mesma forma que o editor faz. Para a regra de vencimento de certificado acima e todo o resto de TLS, o monitoramento de domínio e certificado TLS cobre o tipo de verificação em que cert.days.left e os outros sujeitos de TLS vivem. Para ver uma regra sendo avaliada agora contra uma URL real, sem conta, use a ferramenta gratuita de verificação HTTP. Para os códigos de status contra os quais o sujeito status compara, comece por 200 OK, e os guias de monitoramento cobrem como configurar cada tipo de verificação sob o qual essa linguagem roda.

Perguntas frequentes

O que acontece com minhas configurações antigas de código de status e palavra-chave se eu ativar o modo de asserções?

Elas são substituídas pela lista de regras enquanto o modo está ativo. Desativá-lo de volta antes de salvar restaura os campos clássicos exatamente como estavam: nada é apagado, os dois modos simplesmente não podem estar ativos ao mesmo tempo.

Posso combinar várias condições em um monitor?

Sim: toda regra na lista precisa passar. Ainda não existe um "OU" entre regras separadas, então, para aceitar um entre vários valores, use uma única regra com in [...] ou containsAny [...].

O modo de asserções algum dia vai deixar eu escrever meu próprio script?

Não. Toda regra é composta a partir do conjunto fixo de sujeitos e predicados da linguagem. Não há JavaScript personalizado, por design.

O que acontece na primeira vez que eu adiciono uma regra que compara com a verificação anterior?

Ainda não há nada para comparar, então ela é marcada como aquecendo e é pulada em vez de falhar. Adicionar uma regra de "isso mudou" nunca gera um alerta falso por conta própria.

Eu preciso de um plano específico para usar o modo de asserções?

O modo em si e as regras do dia a dia (status, corpo, cabeçalhos, tempo, redirecionamentos) estão amplamente disponíveis; quantas regras você pode adicionar de uma vez depende do seu plano e é mostrado ao vivo no editor. Regras que comparam com uma verificação anterior (previous, delta, delta2) exigem um plano de nível mais alto e aparecem esmaecidas com uma explicação.

O modo de asserções funciona em monitores de API da mesma forma que em monitores de site?

Sim. Monitores HTTP e API compartilham o mesmo editor de regras, sujeitos e predicados, e uma regra escrita para um deles se lê de forma idêntica no outro.

O que o where(...) realmente faz, e quando eu preciso dele?

Ele filtra uma coleção até os elementos que combinam com uma condição antes de você ler um campo do resultado. Use quando uma projeção simples como requests.status não é específica o suficiente e você precisa de um salto, link ou elemento em particular, em vez da coleção inteira (veja a seção acima).

Posso escrever uma regra contra uma consulta de banco de dados, um valor SNMP, um banner de porta ou um resultado de ping hoje?

A linguagem e o avaliador suportam todos eles, e as tabelas de sujeitos acima cobrem cada um. O editor de regras não: só monitores HTTP e API mostram o interruptor de Validação de Resposta hoje. O SNMP mostra um preview "Em breve" dos dois sujeitos dele, e Database, Counter e Ping não mostram nenhum painel de modo de asserções.

Por que alguns sujeitos nesta referência dizem "reservado" ou "candidato" em vez de simplesmente serem listados normalmente?

"Reservado" significa que o campo está declarado no registro mas nenhum agente ainda o popula; "candidato" significa que está em rollout para os agentes mas ainda não chegou a todos. Os dois são identificados em todo lugar onde aparecem nesta referência e na lista-resumo na seção Limites acima.

Verificar agora

Faça a verificação gratuita no seu próprio site, sem precisar de conta.

Web api validation

Monitorar permanentemente

Seja avisado no momento em que algo quebrar: o HostTracker verifica de mais de 300 localidades e notifica você por e-mail, SMS, Slack, Telegram e mais.

Recursos do HostTracker

Mais nesta seção: Guias de monitoramento: cada tipo de verificação, passo a passo