Aller au contenu principal

Guides / Guides de surveillance : chaque type de vérification, pas à pas

Mode assertion : la référence complète de validation de réponse

Le mode assertion remplace les champs fixes de réussite/échec d'un moniteur par une liste de règles que vous écrivez vous-même, chaque règle nommant exactement ce qui doit être vrai à propos de la réponse. La plupart des moniteurs d'uptime jugent une vérification avec une poignée de champs fixes : un code de statut qui compte comme « en panne », une liste de statuts à ignorer, peut-être un mot-clé qui doit apparaître quelque part dans le corps. Ces champs ne peuvent pas exprimer une API qui répond légitimement 404 pour une ressource manquante, une page qui renvoie 200 avec une coquille vide parce que la base de données a expiré, ou une chaîne de redirection qui se met à passer par le domaine de quelqu'un d'autre.

Le mode assertion de HostTracker remplace ces champs fixes par un petit langage de règles que vous écrivez vous-même, règle par règle, dans l'éditeur de moniteur. Chaque règle dit exactement ce qui doit être vrai à propos de la réponse : le statut, un morceau du corps, un en-tête, le temps qu'elle a pris, où a atterri une redirection. Une vérification échoue seulement quand l'une de vos règles échoue. C'est le même langage pour un site web, une API REST, une requête de base de données, un port TCP, une cible Ping, un compteur SNMP ou une vérification Counter générique : un seul ensemble de sujets, un seul ensemble de prédicats, réutilisés partout où le mode apparaît. Ce guide couvre chaque sujet, opérateur, réducteur, raccourci sucré et forme de syntaxe que le moteur implémente.

Ce que le mode assertion remplace

Les champs classiques de Validation de la réponse sont toujours là quand le mode assertion est désactivé : une plage de statut attendue, une liste de statuts à ignorer, un mot-clé qui doit (ou ne doit pas) apparaître. Le mode est un interrupteur qui échange cet ensemble fixe contre une liste de règles que vous construisez vous-même, et le désactiver de nouveau avant d'enregistrer remet directement les champs classiques en place. Aucun moniteur n'est enfermé de façon permanente dans un seul mode.

Un seul langage se compose au lieu d'un tas de gadgets propres à chaque type. Une vérification « doit être du JSON et contenir un champ », une vérification « doit toujours dire Ajouter au panier » et une vérification « ne doit pas avoir ralenti » sont trois règles dans la même syntaxe, dans la même liste, chacune réussissant ou échouant de son côté.

L'activer

Le mode assertion vit dans la section Validation de la réponse de l'éditeur de moniteur, pour les moniteurs HTTP (site web) et API. Basculez l'interrupteur, et les champs classiques sont remplacés par une liste de règles numérotées avec un bouton « Ajouter une règle » et un compteur en direct montrant combien de règles vous avez utilisées par rapport à la limite de votre forfait.

Mode assertion activé, avec la première règle construite et validée

Chaque règle est validée au fur et à mesure que vous la construisez : une règle pas encore terminée porte un état « inachevé » distinct, et une règle que l'éditeur peut évaluer est marquée complète. Chaque règle a aussi un petit bouton </> qui ouvre sa forme source en texte brut, pour que vous puissiez lire ou copier l'expression exacte plutôt que seulement la vue case par case.

Le modèle mental : sujet, prédicat, valeur

Chaque règle a la même forme : un sujet (le code de statut, le corps, un en-tête, le temps de réponse), un prédicat (égal à, contient, existe, est inférieur à) et, pour la plupart des prédicats, une valeur à laquelle comparer. status eq 200 est un sujet, un prédicat et une valeur ; body.json exists est un sujet et un prédicat sans valeur, car « exists » n'a besoin de rien d'autre.

Construire une règle dans l'éditeur commence par choisir quoi vérifier, puis la condition, puis la valeur :

Construction d'une deuxième règle : le sélecteur de champ liste chaque sujet avec son type et un exemple

Les règles de la liste sont combinées avec AND : une vérification échoue quand une seule règle échoue et ne réussit que quand chaque règle réussit. Il n'y a pas encore de OR, donc pour accepter l'un de plusieurs statuts ou chaînes, exprimez cela à l'intérieur d'une seule règle (status in [200, 301, 302], body containsAny ["In stock", "Pre-order"]). Une règle qui échoue se nomme elle-même dans l'alerte, donnez donc à chacune un court libellé quand vous le pouvez et l'alerte dira quelle attente a été rompue.

Ce que vous pouvez vérifier

Le sélecteur regroupe les sujets entre le document propre de la réponse (le corps, les en-têtes) et son transport (statut, timing, redirections, TLS). Quelques-uns des sujets les plus importants, avec la liste complète dans la référence qui suit :

SujetCe que c'estExemple
statusLe code de statut HTTP de la réponse finale, après suivi des redirectionsstatus isOk
bodyLe corps de la réponse en texte brutbody contains "Add to cart"
body.json / body.xml / body.html / body.yamlLe corps, mais seulement quand il s'analyse vraiment comme ce format - sinon le sujet est simplement absentbody.json exists
body.json.path("$.a")Une requête JSONPath dans un corps JSON (le même langage de requête fonctionne aussi sur YAML, puisque YAML s'analyse dans le même modèle d'objet)body.json.path("$.status") eq "ok"
body.size / body.hashLa taille de la réponse en octets, et une empreinte du contenu du corpsbody.size gt 1kb
header("Name")Un en-tête de réponse, recherché par nomheader("Content-Type") isJson
time et time.connect / time.tls / time.dns / time.headLe temps de réponse total, et ses phases réseau, poignée de main TLS, DNS et temps de réflexion du serveurtime lt 2s
redirects / requestsLes sauts qu'une vérification a suivis, et la chaîne complète (y compris la réponse finale)redirects.count eq 0
url et ses parties (.host, .scheme, .path...)L'URL finale sur laquelle la vérification a atterriurl.scheme eq "https"
cert.days.leftJours restants avant l'expiration du certificat TLScert.days.left gt 14

Les nombres acceptent des suffixes d'unité pour que vous n'ayez jamais à convertir à la main : 2s signifie 2000 millisecondes, 1kb signifie 1024 octets. Les comparaisons de texte sont sensibles à la casse sauf si vous ajoutez nocase à la règle.

La référence complète

Ce qui suit est chaque sujet, opérateur, réducteur, raccourci sucré, filtre et forme de syntaxe que le moteur d'assertion enregistre pour les vérifications HTTP et API, tiré du propre registre du moteur (les mêmes données qui alimentent les sélecteurs de l'éditeur de règles et sa documentation). Les entrées pas encore généralement disponibles portent une note entre parenthèses : des champs réservés que le moteur n'a pas encore commencé à peupler, des candidats encore en cours de déploiement vers les agents, et la famille à état qui nécessite un forfait précis. Tout ce qui n'a pas une telle note est vivant aujourd'hui sur tout forfait ayant le mode assertion.

La référence suit le propre regroupement du moteur : les champs de la réponse, puis les façons d'atteindre l'intérieur d'un corps, puis le timing, le réseau et le TLS, puis les opérateurs, réducteurs et raccourcis qui fonctionnent sur tous, puis les types de vérification au-delà de HTTP qui parlent le même langage.

Réponse

Les sujets qui décrivent la réponse elle-même : son statut, son corps brut, ses en-têtes, l'URL depuis laquelle elle a réellement répondu, et la chaîne de requêtes qui y a mené.

NomCe que c'estType/valeursExemple
bodyLe corps de la réponse en texte décodé.stringbody contains "Welcome"
headerUn en-tête de la réponse finale, par nom.stringheader("Content-Type") isJson
redirectsLes sauts de redirection qui ont été suivis - la chaîne de requêtes sans son dernier élément.collectionredirects.count eq 0
statusLe code de statut HTTP de la réponse finale, après suivi des redirections.numberstatus isOk
body.sizeLa taille du corps téléchargé, en octets.numberbody.size lt 500000
urlL'URL qui a réellement répondu, après toutes les redirections. Une url : comparez-la comme du texte, ou lisez ses parties (url.host, .port, .path, .query, .scheme).urlurl.host eq "www.example.com"
requestsChaque requête faite par cette vérification, dans l'ordre - les sauts de redirection puis la requête finale.collectionrequests.count le 2
url.hostLa partie hôte de l'URL.stringurl.host eq "example.com"
url.pathLa partie chemin de l'URL.stringurl.path startsWith "/api"
url.portLa partie port de l'URL.numberurl.port eq 443
url.queryLa chaîne de requête de l'URL.stringurl.query contains "token"
url.schemeLe schéma de l'URL (http ou https).stringurl.scheme eq "https"
body.hashUn condensé du corps de la réponse - comparez-le avec previous.body.hash pour détecter des changements de contenu.stringbody.hash eq previous.body.hash
httpVersion (réservé - pas encore peuplé)La version HTTP négociée.stringhttpVersion eq "HTTP/2"
setCookieLes valeurs Set-Cookie de la réponse finale, un élément par cookie - repérez-en un avec contains ou matches, comptez-les avec .count.collectionsetCookie exists
steps (pas encore disponible)Les étapes d'une vérification multi-étapes. Pas encore disponible.collectionsteps.count le 1
url.originalL'URL avec laquelle la vérification a été configurée, avant toute redirection. Une url comme url elle-même : elle a les mêmes parties (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.original.hostLa partie hôte de l'URL.stringurl.original.host eq "example.com"
url.original.pathLa partie chemin de l'URL.stringurl.original.path startsWith "/start"
url.original.portLa partie port de l'URL.numberurl.original.port eq 80
url.original.queryLa chaîne de requête de l'URL.stringurl.original.query contains "utm_"
url.original.schemeLe schéma de l'URL (http ou https).stringurl.original.scheme eq "http"

Deux alias : redirectCount est un raccourci pour redirects.count - redirectCount eq 0 se lit un peu plus naturellement que la forme longue équivalente quand vous voulez dire « la vérification a répondu directement, sans redirection ». Et setCookie au niveau supérieur est la liste de cookies de la réponse finale ; le même nom réapparaît par saut à l'intérieur de requests/redirects (voir les sujets de saut ci-dessous), ne portant que les cookies de cette seule requête.

Extraire des valeurs du corps

Ces sujets ne se résolvent que quand le corps est le format qu'ils nomment : un espace de noms JSON sur une page HTML est simplement absent, pas une erreur typée. Cela fait de exists le moyen standard de sonder le format, et body.json exists demande si le corps s'est analysé comme du JSON. Les quatre espaces de noms de format portent chacun une fonction de requête .path(...) correspondante (JSONPath pour json/yaml, XPath pour xml, des sélecteurs CSS pour html) et un .regex(...) correspondant, plus un body.regex(...) agnostique du format qui lit le texte brut quel que soit le format. body.html.a, body.html.script et body.html.link sont des collections toutes prêtes de chaque lien, script et élément <link> de la page ; voir les portées d'élément ci-dessous pour les champs disponibles sur chacun.

NomCe que c'estType/valeursExemple
body.jsonLe corps de la réponse, mais seulement quand c'est vraiment du JSON.stringbody.json exists
body.json.pathInterroger le corps JSON avec une expression JSONPath.jsonbody.json.path("$.status") eq "ok"
body.htmlLe corps de la réponse, mais seulement quand c'est vraiment du HTML.stringbody.html exists
body.html.pathSélectionner des éléments de page avec un sélecteur CSS.collectionbody.html.path("h1").first contains "Welcome"
body.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists
body.xmlLe corps de la réponse, mais seulement quand c'est vraiment du XML.stringbody.xml exists
body.xml.pathInterroger le corps XML avec une expression XPath.stringbody.xml.path("//item/@id") exists
body.html.aChaque lien de la page.collectionbody.html.a.count gt 0
body.html.linkChaque <link> que la page déclare. Une simple mention signifie les cibles des liens.collectionbody.html.link.count gt 0
body.html.scriptChaque script que la page charge. Une simple mention signifie les sources des scripts.collectionbody.html.script.count gt 0
body.yamlLe corps de la réponse, mais seulement quand c'est vraiment du YAML.stringbody.yaml exists
body.yaml.pathInterroger le corps YAML avec une expression JSONPath.jsonbody.yaml.path("$.services.web.image") contains ":1."
body.html.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists
body.json.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists
body.xml.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists
body.yaml.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists

Un détail de la famille regex qui mérite d'être signalé : les groupes de capture nommés ((?<id>...)) à l'intérieur d'une règle .regex(...) écrivent dans un espace de noms de liaison propre à la vérification, qu'une règle ultérieure peut relire avec bind("id") ou bind[0] par position - voir Valeurs capturées ci-dessous.

Valeurs capturées

Un sujet vit dans son propre groupe du registre car il ne lit pas la réponse directement - il lit ce qu'une règle antérieure en a capturé.

NomCe que c'estType/valeursExemple
bindUne valeur capturée par une règle regex antérieure, par nom de capture ou par position.stringbind("id") gt 1000

Associez-le à une règle regex plus tôt dans la liste : une règle comme body.regex("order-(?<id>\d+)") exists capture l'identifiant de commande dans le nom id, et une règle ultérieure peut le tester avec bind("id") gt 1000 ou, pour une capture positionnelle (sans nom), bind[0].

Timing

Un total plus une répartition par phase, pour qu'une alerte « ça a ralenti » puisse aussi dire quelle partie a ralenti.

NomCe que c'estType/valeursExemple
timeTemps de réponse total : connexion + TLS + attente + téléchargement. La résolution DNS n'est pas incluse.numbertime lt 2000
ttfb (réservé - pas encore peuplé)Délai jusqu'au premier octet.numberttfb lt 200
time.connectTemps pris pour établir la connexion TCP.numbertime.connect lt 500
time.dataTemps pris pour télécharger le corps de la réponse.numbertime.data lt 1000
time.dnsTemps pris pour résoudre le nom de domaine. Non inclus dans le sujet time nu.numbertime.dns lt 200
time.headTemps attendu pour les en-têtes de la réponse.numbertime.head lt 500
time.tlsTemps pris pour la poignée de main TLS.numbertime.tls lt 300

Le sujet time nu est connexion + TLS + attente-des-en-têtes + téléchargement du corps. La résolution DNS est exclue et ne vit que dans le sujet frère time.dns, car le DNS est souvent mis en cache et ferait sinon paraître le même point de terminaison tantôt rapide tantôt lent de façon incohérente entre les vérifications.

Réseau : DNS et connexion

dns et conn sont des espaces de noms purs dans le registre - un groupe sans valeur propre, donc une règle ne peut jamais s'arrêter sur le nom nu (l'éditeur et le moteur refusent tous deux une chaîne qui se termine sur dns ou conn seul, et vous orientent vers les vrais champs ci-dessous).

NomCe que c'estType/valeursExemple
connLa connexion réseau que la vérification a établie - l'adresse qui a servi la réponse et tout échec de connexion.string-
conn.failedCombien des adresses résolues ont échoué à se connecter.numberconn.failed eq 0
conn.failedIps (candidat - en cours de déploiement vers les agents)Les adresses résolues qui ont échoué à se connecter.collectionconn.failedIps.count eq 0
conn.ipL'adresse IP qui a réellement servi la réponse.stringconn.ip eq "203.0.113.10"
conn.ip.family (candidat - en cours de déploiement vers les agents)Si la réponse a été servie en IPv4 ou en IPv6.stringconn.ip.family eq "IPv4"
dnsRésolution DNS du nom surveillé - vers quelles adresses il a résolu et quel serveur a répondu.string-
dns.ipsToutes les adresses IP vers lesquelles le nom de domaine a résolu pendant cette vérification.collectiondns.ips contains "1.2.3.4"
dns.serverLe serveur DNS qui a répondu à la résolution.stringdns.server eq "8.8.8.8"

TLS et certificat

Comme dns et conn, tls et cert sont des espaces de noms purs - les informations de certificat/poignée de main vivent un niveau plus bas.

NomCe que c'estType/valeursExemple
cert.days.leftJours restants avant l'expiration du certificat du site.numbercert.days.left gt 14
certLe certificat présenté par le serveur - jours avant expiration, émetteur et champs d'identité.string-
cert.daysJours depuis l'émission du certificat.numbercert.days gt 0
cert.issuerL'autorité de certification qui a émis le certificat du site.stringcert.issuer contains "Let's Encrypt"
cert.sanLes noms de domaine pour lesquels le certificat est valide.collectioncert.san contains "www.example.com"
cert.serialLe numéro de série du certificat.stringcert.serial exists
cert.subject (réservé - pas encore peuplé)Le sujet du certificat. Pas encore capturé - à venir avec une future version d'agent.stringcert.subject contains "example.com"
tlsLa poignée de main TLS de la connexion sécurisée - version de protocole et chiffrement négociés.string-
tls.cipherLa suite de chiffrement négociée.stringtls.cipher contains "AES"
tls.protocolLa version TLS négociée.stringtls.protocol eq "Tls13"

cert.subject est listé ici par souci d'exhaustivité mais n'est pas encore peuplé - voir la section Honnêteté ci-dessous pour ce que « réservé » signifie en pratique. La règle de certificat du quotidien est cert.days.left gt 14, couverte dans la section des règles concrètes.

Sujets de saut : champs à l'intérieur de requests et redirects

requests et redirects sont des collections, et chaque élément est un enregistrement complet de requête/réponse avec son propre ensemble de champs réduit. Tous les sujets de premier niveau n'ont pas de sens par saut (un saut n'a pas son propre certificat), et un champ n'existe que par saut : hstsHeader, l'en-tête Strict-Transport-Security de cette requête dans la chaîne.

NomCe que c'estType/valeursExemple
statusLe code de statut de cette requête dans la chaîne.numberstatus eq 200
urlL'URL vers laquelle cette requête a été faite.urlurl startsWith "https://"
headerUn en-tête de réponse de cette requête. Un saut garde un enregistrement d'en-tête réduit, à valeur unique - les prédicats de type liste (containsAny, containsAll, unique) ne s'appliquent qu'à l'en-tête de la réponse finale.stringheader("Content-Type") contains "json"
hstsHeaderL'en-tête Strict-Transport-Security de cette requête.stringrequests[0].hstsHeader exists
setCookieLes valeurs d'en-tête Set-Cookie de cette requête.collectionsetCookie exists
url.originalL'URL avec laquelle la vérification a été configurée, avant toute redirection. Une url comme url elle-même : elle a les mêmes parties (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.hostLa partie hôte de l'URL.stringurl.host eq "example.com"
url.portLa partie port de l'URL.numberurl.port eq 443
url.pathLa partie chemin de l'URL.stringurl.path startsWith "/api"
url.queryLa chaîne de requête de l'URL.stringurl.query contains "token"
url.schemeLe schéma de l'URL (http ou https).stringurl.scheme eq "https"
url.original.hostLa partie hôte de l'URL.stringurl.original.host eq "example.com"
url.original.portLa partie port de l'URL.numberurl.original.port eq 80
url.original.pathLa partie chemin de l'URL.stringurl.original.path startsWith "/start"
url.original.queryLa chaîne de requête de l'URL.stringurl.original.query contains "utm_"
url.original.schemeLe schéma de l'URL (http ou https).stringurl.original.scheme eq "http"

Le header(...) par saut garde un enregistrement réduit, à valeur unique : des prédicats de forme liste comme containsAny ou unique n'ont de sens que sur la carte d'en-têtes complète de la réponse finale, donc ils s'y appliquent et pas par saut. Les deux collections signifient des choses différentes. requests est la chaîne entière incluant la réponse finale qui a répondu, elle n'est donc jamais vide même pour un 200 direct, tandis que redirects ne comprend que les sauts suivis en chemin, vide quand rien n'a redirigé.

Portées d'élément : champs à l'intérieur d'un élément de collection

Une portée d'élément est l'ensemble de champs disponible sur UN élément d'une collection - après indexation dedans (requests[0]) ou lors du filtrage avec where(current. ...) (voir la section suivante). Six collections portent leur propre portée d'élément : les quatre collections d'éléments HTML partagent une forme, et requests/redirects partagent la forme des sujets de saut documentée juste au-dessus.

Portée d'élémentÀ quoi ressemble un élément
body.html.pathUn élément trouvé par une requête CSS body.html.path("selector").
body.html.aUn élément lien <a> de body.html.a.
body.html.scriptUn élément <script> de body.html.script.
body.html.linkUn élément <link> de body.html.link.
requestsUne requête dans la chaîne complète (voir le tableau des sujets de saut ci-dessus).
redirectsUn saut de redirection suivi (les mêmes champs que requests, voir ci-dessus).

La forme partagée pour body.html.path(...), body.html.a, body.html.script et body.html.link - une ligne par lien, balise script ou élément <link> :

NomCe que c'estType/valeursExemple
urlLa cible du lien exactement telle que le balisage l'écrit.stringbody.html.a.url contains "/checkout"
textLe texte visible de l'élément.stringbody.html.a.text contains "Sign in"
absoluteLa cible du lien résolue contre l'URL de la page en une adresse absolue - une liste d'urls, avec les parties de l'url disponibles par élément (.host, .path, .port, .query, .scheme).urlbody.html.a.absolute.scheme in ["https"]
relL'attribut rel de l'élément.stringbody.html.a.where(current.rel eq "nofollow").count eq 0
absolute.hostLa partie hôte de l'URL.stringbody.html.a.absolute.host.unique.count le 3
absolute.portLa partie port de l'URL.numberbody.html.a.absolute.port in [443]
absolute.pathLa partie chemin de l'URL.stringbody.html.a.absolute.path startsWith "/"
absolute.queryLa chaîne de requête de l'URL.stringbody.html.a.absolute.query not contains "session"
absolute.schemeLe schéma de l'URL (http ou https).stringbody.html.a.absolute.scheme in ["https"]

Deux valeurs par défaut s'appliquent avant que vous n'écriviez une règle contre ces collections. Une simple mention de body.html.a (ou .script/.link) signifie sa projection .url, donc body.html.a.count gt 0 compte les hrefs, et une règle enregistrée se relit avec .url écrit explicitement, car une règle stockée dit toujours exactement ce qu'elle évalue. Et .url est l'attribut href brut exactement tel que le balisage l'a écrit, donc un lien relatif reste relatif ; .absolute est ce même lien résolu contre l'URL propre de la page, ce que vous voulez quand vous vérifiez le schéma ou l'hôte des liens sortants (body.html.a.absolute.scheme in ["https"]).

Opérateurs

La moitié prédicat de chaque règle : quel test exécuter contre le sujet. Les 15 sont partagés entre tous les types de vérification, et lesquels conviennent à un sujet donné dépend de son type (un code de statut prend lt/gt, un corps prend contains, une collection prend exists/unique/in).

NomCe que c'estS'applique àExemple
eqÉgal à. Contre un littéral json("…") / xml("…") / yaml("…") c'est une correspondance structurelle EXACTE : mêmes clés (dans n'importe quel ordre), tableaux dans l'ordre, mêmes valeurs.tout typebody.json eq json("{\"ok\": true}")
ltInférieur à.nombrestime lt 2000
leInférieur ou égal à.nombrescert.days.left le 30
gtSupérieur à.nombresbody.size gt 0
geSupérieur ou égal à.nombresstatus ge 500
containsContient le texte - sur une liste, réussit quand la valeur EST l'un des éléments (correspondance exacte ; utilisez matches pour chercher à l'intérieur des éléments). Contre un littéral json("…") / xml("…") / yaml("…") c'est un confinement STRUCTUREL : tout ce que le littéral énonce doit être présent et correspondre ; la réponse peut en avoir plus.texte ou listebody.json contains json("{\"status\": \"ok\"}")
startsWithCommence par le texte - sur une liste, quand N'IMPORTE QUEL élément le fait.texteurl.path startsWith "/api"
endsWithSe termine par le texte - sur une liste, quand N'IMPORTE QUEL élément le fait.texteurl.path endsWith ".json"
matchesCorrespond à l'expression régulière n'importe où dans le texte - sur une liste, quand N'IMPORTE QUEL élément le fait.textebody matches "order-\\d+"
containsAnyContient au moins une des valeurs listées (sur une liste : un élément quelconque ÉGALE l'une d'elles).listebody containsAny ["In stock", "Pre-order"]
containsAllContient chacune des valeurs listées (sur une liste : chaque valeur égale un élément quelconque - les témoins peuvent différer).listebody.html.a.text containsAll ["Home", "Contact"]
inEst l'une des valeurs ou plages listées - sur une liste, chaque élément l'est.valeur(s) ou plagestatus in [200, 301, 302]
existsLe sujet est présent.tout sujetheader("ETag") exists
isNumberLa valeur se lit comme un nombre.texte ou toutbind("id") isNumber
uniqueLa liste n'a pas de doublons.listedns.ips unique

Deux opérateurs signifient quelque chose de plus étroit qu'il n'y paraît. contains sur une liste est une appartenance exacte : la valeur doit égaler un élément entier, pas apparaître comme une sous-chaîne à l'intérieur d'un élément, donc utilisez matches quand vous voulez un comportement de sous-chaîne à travers les éléments d'une collection. Et eq contre un littéral json(...)/xml(...)/yaml(...) est une correspondance structurelle complète (mêmes clés, tableaux dans le même ordre, mêmes valeurs), tandis que contains contre le même type de littéral est un confinement structurel : tout ce que le littéral énonce doit être présent, mais la vraie réponse peut en porter plus.

Réducteurs

Un réducteur réduit une collection à une seule valeur et ne peut apparaître qu'à la fin d'une chaîne. Les exemples ci-dessous utilisent requests.status, la collection naturellement numérique que forment les sujets HTTP, comme illustration ; les huit mêmes réducteurs fonctionnent sur n'importe quelle collection numérique dans n'importe quel type de vérification (les temps d'aller-retour d'une vérification Ping, un ensemble filtré de lignes de base de données).

NomCe qu'il réduitS'applique àExemple
countCombien d'éléments la liste a.toute collectionrequests.count le 2
minLe plus petit nombre de la liste.collection numériquerequests.status.min ge 200
maxLe plus grand nombre de la liste.collection numériquerequests.status.max lt 500
sumLa somme des nombres de la liste.collection numériquerequests.status.sum gt 0
avgLa moyenne des nombres de la liste.collection numériquerequests.status.avg lt 300
firstLe premier élément de la liste.toute collectionredirects.status.first eq 301
lastLe dernier élément de la liste.toute collectionrequests.status.last eq status
uniqueLa liste sans les doublons.toute collectiondns.ips.unique.count le 3

unique est surchargé, et l'écriture distingue les deux sens. Écrit comme opérateur sans point (x unique), c'est un prédicat, « cette collection n'a pas de doublons », et il échoue en nommant la répétition. Écrit comme réducteur avec un point (x.unique), c'est une transformation, la collection dédupliquée elle-même, qui a encore besoin de quelque chose après elle (x.unique.count eq 1). Un x.unique en suspens sans rien qui suit est une erreur de syntaxe, car le moteur ne peut pas deviner lequel des deux sens vous vouliez.

Sucre syntaxique

Les prédicats sucrés sont des raccourcis que le moteur développe en prédicats de base ordinaires avant même que la règle ne soit envoyée à un agent - ajouter un prédicat sucré ne coûte rien de plus (pas de paquet d'agent, pas de plancher de version) car au moment où il atteint le fil, il ressemble déjà à une règle ordinaire. Préférez le sucre dès qu'il existe : cela se lit mieux, et c'est exactement équivalent à écrire la forme longue à la main.

NomCe que ça signifieS'applique àExemple
isOkLe statut est un code de succès (200-299).status-
isRedirectLe statut est un code de redirection (300-399).statusstatus isRedirect
isClientErrorLe statut est une erreur client (400-499).statusstatus isClientError
isServerErrorLe statut est une erreur serveur (500-599).statusstatus isServerError
isJsonLe contenu est vraiment du JSON.document ou texte de type de médiaheader("Content-Type") isJson
isXmlLe contenu est vraiment du XML - le corps s'analyse comme du XML, ou un en-tête nomme un type de média XML.document ou texte de type de médiabody isXml
isHtmlLe contenu est vraiment du HTML - le corps s'analyse comme du HTML, ou un en-tête nomme un type de média HTML.document ou texte de type de médiabody isHtml
isFormUn type de média nomme un encodage de formulaire : application/x-www-form-urlencoded ou multipart/form-data. Contrairement à isJson/isXml/isHtml il n'y a pas d'espace de noms de corps correspondant, donc cela ne s'applique qu'à une valeur de type de média comme un en-tête Content-Type.texte de type de média seulementheader("Content-Type") isForm
isEmptyRien là : un texte vide, une taille de zéro ou une liste vide.texte, taille ou listebody isEmpty
isNullLa valeur est null.toute valeurbody.json.path("$.deletedAt") isNull
absentLe sujet n'est pas du tout présent.tout sujetheader("X-Debug") absent
betweenUn nombre dans une plage incluse.nombres (2 opérandes)body.size between 50 and 500kb

isJson/isXml/isHtml sont sensibles au contexte à dessein, et ce sur quoi vous les écrivez détermine quel sens s'applique. Écrits sur le document lui-même (body isJson), ils signifient « est-ce que ceci s'analyse comme ce format », la même chose que body.json exists. Écrits sur une valeur texte qui nomme un type de média, comme un en-tête (header("Content-Type") isJson), ils signifient « est-ce que ceci nomme la famille MIME de ce format » ; voir les familles MIME ci-dessous pour savoir quels types de média se qualifient. isForm n'a que le second sens, puisqu'il n'y a pas d'espace de noms body.form dans lequel s'analyser, donc body isForm est une erreur statique plutôt qu'une règle qui ne pourrait jamais être vraie.

Le filtre where(...)

Ne garder que les éléments qui correspondent, puis continuer à partir de là. C'est l'unique construction de filtrage du langage, et elle a exactement une forme : where(current.<field> <condition> <value>).

Filtrer diffère de projeter : requests.url contains "cart" demande si un tel saut existe n'importe où dans la chaîne, tandis que requests.where(current.url contains "cart").status demande ce que ce saut a renvoyé. Filtrer ne réduit pas la liste, donc terminez avec .first, une vérification in [...], ou .count. Cela ne va qu'à un seul niveau, et prend exactement une condition.

PartieCe qu'elle nommeNotes
current.<field>Un champ de chaque élément filtré, écrit après current.C'est la moitié que les gens confondent : current.url est l'URL du saut individuel, pas celle de la réponse finale. Seuls les propres champs de l'élément peuvent suivre current..
la conditionN'importe quel prédicat ordinaire, y compris not et nocaseToute condition qui fonctionne au niveau supérieur d'une règle fonctionne aussi ici.
la valeurCe à quoi le champ de chaque élément est comparéGénéralement une valeur simple. Un sujet écrit ici est lu depuis la réponse EXTÉRIEURE, pas l'élément - where(current.url eq url.original) compare chaque saut à l'URL avec laquelle la vérification a été configurée, c'est pourquoi le côté élément doit dire current. explicitement.

Exemple : requests.where(current.url contains "cart").status.first eq 301 - ne garder que les sauts dont l'URL contient « cart », puis regarder le statut du premier qui a correspondu.

Deux limites de plus, toutes deux imposées par l'analyseur avec leur propre message : where ne peut pas être imbriqué dans un autre where, et son argument est exactement une condition, sans and/or à l'intérieur. Il ne s'applique qu'à une collection dont les éléments portent des champs nommés (requests, body.html.a), pas à une simple liste projetée comme dns.ips, où il n'y a rien pour que current. nomme.

Référence de syntaxe

Tout le reste que la grammaire définit : comment nommer une règle, comment écrire des plages et des listes, ce que signifie un sujet nu, et les petites formes de ponctuation qui apparaissent dans beaucoup de règles.

FormeCe qu'elle faitGenreExemple
whereNe garder que les éléments qui correspondent, puis continuer à partir de là.filtre de collectionrequests.where(current.url contains "cart").status.first eq 301
notInverse la condition qui suit.drapeaubody not contains "error"
nocaseComparer le texte sans tenir compte de la casse.drapeaubody contains "welcome" nocase
currentÀ l'intérieur de where(…), nomme l'unique élément filtré.référence d'élément (à l'intérieur de where)requests.where(current.status eq 301)
rangeUne plage de nombres, les deux bornes INCLUSES.plage de nombresstatus in [200..299]
listUne liste de valeurs à comparer.liste de valeursstatus in [200, 301, 302]
docLiteralUne valeur de document typée pour comparaison structurelle : le texte entre guillemets est analysé comme JSON, XML ou YAML au moment où la règle est enregistrée.texte json/xml/yamlbody.json contains json("{\"user\": {\"active\": true}}")
implicitExistsUne règle qui ne nomme qu'un sujet vérifie qu'il est présent : écrire simplement body.json s'enregistre comme body.json exists.ligne sujet nubody.json
indexChoisit UN élément d'une liste par position, en comptant depuis 0.entier basé sur 0requests[0].status
labelUn nom optionnel pour la règle, écrit avant un deux-points.nom avant un deux-points"json ok": body.json exists
commentTout ce qui suit # est une note pour vous-même ; cela n'affecte pas la vérification.texte # finalstatus isOk # the happy path

Quelques-unes méritent un passage en langage clair. label donne à une règle un nom qui apparaît dans l'alerte au lieu de l'expression rendue ; écrivez-le avant un deux-points, comme dans "json ok": body.json exists. implicitExists signifie qu'une ligne ne nommant qu'un sujet et aucun prédicat est un raccourci pour exists : écrire body.json s'enregistre comme body.json exists, et rouvrir la règle montre la forme écrite en toutes lettres. range et list sont les deux formes qu'une valeur peut prendre après in : une plage ([200..299], les deux bornes incluses) ou une liste explicite ([200, 301, 302]), et une valeur peut être ouverte d'un côté ou de l'autre ([400..]). docLiteral est l'enveloppe json(...)/xml(...)/yaml(...) utilisée pour la comparaison structurelle contre le corps (couverte sous Opérateurs ci-dessus et dans les règles concrètes ci-dessous). index choisit un élément d'une collection par position, basé sur 0, de la même façon que bind[0] lit une capture positionnelle. current n'a de sens qu'à l'intérieur d'un filtre where(...), couvert dans sa propre section plus haut.

Enveloppes : previous, delta et delta2

Trois formes qui regardent en arrière au lieu de seulement la réponse actuelle - chacune est réservée aux forfaits avec assertions à état, et chacune est expliquée en détail dans « Comparer à la vérification précédente » ci-dessous.

NomCe que c'estType/valeursExemple
delta (nécessite un forfait avec assertions à état)De combien une valeur numérique a changé depuis la vérification précédente - optionnellement comme un taux par ms/s/m/h.numberdelta(body.size, h) lt 1mb
delta2 (nécessite un forfait avec assertions à état)Le changement du changement - une valeur est-elle en train d'accélérer ?numberdelta2(time) gt 0
previous (nécessite un forfait avec assertions à état)La valeur que ce sujet avait lors de la vérification précédente.anystatus eq previous.status

Drapeaux : not et nocase

Deux modificateurs qui s'attachent à une règle plutôt que de se tenir comme des sujets ou des prédicats à part entière.

DrapeauCe qu'il faitGenreExemple
notInverse la condition qui suit.drapeau (s'attache à une règle)body not contains "error"
nocaseComparer le texte sans tenir compte de la casse.drapeau (s'attache à une règle)body contains "welcome" nocase

not se compose avec le prédicat qui suit plutôt que de nier la règle entière comme un tout - x not != y se lit comme x eq y, pas comme une double négation. Quand un sujet peut être totalement absent, préférez le sucre absent à not exists : les deux signifient exactement la même chose, mais absent le dit directement. nocase ne change quelque chose que sur une comparaison réellement textuelle ; l'éditeur (et cette référence) vous laissent quand même l'écrire n'importe où, mais c'est silencieusement sans effet sur un test numérique comme status eq 200 nocase.

Familles MIME

Les tables de correspondance derrière isJson, isXml, isHtml et isForm quand ils sont appliqués à une valeur de type de média comme un en-tête. Chaque famille fait correspondre le type de média de premier niveau évident plus, pour JSON et XML, tout type se terminant par le suffixe de syntaxe structurée correspondant - ce qui fait que header("Content-Type") isJson réussit correctement sur application/problem+json ou application/vnd.api+json et pas seulement le simple application/json.

FamilleCorrespond àSucre associéExemple
jsonapplication/json, text/json, ou tout type de média se terminant par +json (application/problem+json, application/vnd.api+json, application/ld+json, ...).sucre : isJsonheader("Content-Type") isJson
xmlapplication/xml, text/xml, ou tout type de média se terminant par +xml (image/svg+xml, application/atom+xml, ...).sucre : isXmlheader("Content-Type") isXml
htmltext/html ou application/xhtml+xml.sucre : isHtmlheader("Content-Type") isHtml
formapplication/x-www-form-urlencoded ou multipart/form-data.sucre : isFormheader("Content-Type") isForm

La correspondance ignore tout à partir du premier ; (donc application/json; charset=utf-8 correspond quand même) et ne tient pas compte de la casse.

Sujets pour les vérifications base de données, compteur, SNMP, port et ping

Chaque opérateur, réducteur, raccourci sucré et forme de syntaxe ci-dessus est identique pour ces cinq types de vérification : le moteur enregistre les mêmes 15 opérateurs, 8 réducteurs, 12 prédicats sucrés et 11 formes de syntaxe pour les six types sans exception. Ce qui diffère par type est la liste de sujets. Chaque type expose un petit ensemble de sujets propres à ce qu'il mesure, plus un sous-ensemble des sujets réseau/timing/TLS déjà documentés ci-dessus, dont le sens s'adapte au type (le time d'une vérification Database est connexion-plus-requête plutôt que connexion-plus-TLS-plus-téléchargement, puisqu'il n'y a pas de réponse HTTP à télécharger).

Vérifications base de données

Partage time, time.connect et time.dns avec les sujets documentés ci-dessus (recentrés sur une connexion de base de données : connexion-plus-requête, résolution DNS de l'hôte de base de données). Propres aux vérifications base de données :

NomCe que c'estType/valeursExemple
scalarLa valeur unique renvoyée par la requête (mode Scalar).any-
rowsLes lignes que la requête a affectées ou renvoyées (mode NonQuery).collection-
time.queryLe temps qu'a pris la requête elle-même.number-

Un exemple concret se trouve dans la section suivante : utilisez rows.count pour vérifier combien de lignes une requête a affectées ou renvoyées, et scalar pour vérifier directement une seule valeur renvoyée.

Vérifications compteur

Partage time avec les sujets documentés ci-dessus - comme champ à statut candidat spécifiquement pour les vérifications Counter (temps d'aller-retour de la requête du compteur ; voir la section Honnêteté pour ce que « candidat » signifie). Propre aux vérifications compteur :

NomCe que c'estType/valeursExemple
valueLa valeur mesurée du compteur.number-

Vérifications SNMP

Partage time et time.dns avec les sujets documentés ci-dessus (résolution du nom d'hôte plus la requête SNMP elle-même). Propres aux vérifications SNMP :

NomCe que c'estType/valeursExemple
time.requestLe temps qu'a pris la requête SNMP.number-
valueLa valeur renvoyée par l'OID.any-
value.type (candidat - en cours de déploiement vers les agents)Le nom du type de donnée SNMP de la valeur renvoyée.string-

value.type est à statut candidat ; voir la section Honnêteté. Remarque sur la disponibilité : l'interrupteur Validation de la réponse du mode assertion n'a pas encore atteint l'éditeur de moniteur SNMP. Il affiche un panneau « Bientôt disponible » nommant ces deux sujets plutôt qu'une liste de règles fonctionnelle. Les sujets et l'évaluateur sous-jacent sont déjà enregistrés ; seule l'interface de l'éditeur SNMP est en attente.

Vérifications port

La plus grande liste partagée de tous les types non-HTTP. Une vérification de port TCP porte essentiellement les mêmes sujets de connexion, DNS, TLS et certificat qu'une vérification HTTP, puisqu'une vérification de port peut aussi négocier TLS : bind, cert et ses six sous-champs, conn et ses quatre sous-champs, dns et ses deux sous-champs, time/time.connect/time.dns/time.tls, et tls/tls.cipher/tls.protocol - tous documentés dans les sections ci-dessus, avec les mêmes sens. Propres aux vérifications port :

NomCe que c'estType/valeursExemple
bannerLes données lues sur le socket après la connexion.string-
banner.hash (candidat - en cours de déploiement vers les agents)Un condensé de la bannière - comparez avec previous.banner.hash pour détecter des changements de service.string-
banner.regexFaire correspondre le texte avec une expression régulière et prendre ce qui a été capturé.stringbody.regex("order-(?<id>\\d+)") exists
banner.size (candidat - en cours de déploiement vers les agents)La taille de la bannière, en octets.number-

banner.hash et banner.size sont à statut candidat - voir la section Honnêteté. banner.regex est vivant aujourd'hui et fonctionne exactement comme body.regex(...) sur une vérification HTTP : les captures nommées alimentent le même espace de noms bind(...).

Vérifications ping

Partage les sujets de connexion et DNS avec les sections ci-dessus : conn, conn.failed, conn.failedIps, conn.ip, conn.ip.family, dns, dns.ips, dns.server, time (ici, le temps d'aller-retour moyen des réponses réussies) et time.dns. Propres aux vérifications ping :

NomCe que c'estType/valeursExemple
lossLe pourcentage de requêtes echo qui n'ont eu aucune réponse.numberloss eq 0
replyLes réponses echo réussies.collection-
sentCount (candidat - en cours de déploiement vers les agents)Combien de requêtes echo ont été envoyées.number-
time.maxLe temps d'aller-retour de la réponse la plus lente.number-
time.minLe temps d'aller-retour de la réponse la plus rapide.number-
ttlLe TTL de la première réponse réussie - comparez avec previous.ttl pour repérer des changements de route.number-

sentCount est à statut candidat - voir la section Honnêteté. ttl est bon à connaître même en dehors d'une règle stricte de réussite/échec : l'associer avec previous.ttl (voir Enveloppes ci-dessus) signale un changement de route entre deux vérifications, puisque le temps de vie d'un paquet à son arrivée reflète combien de sauts il a traversés.

Les règles que les gens veulent vraiment écrire

La page est en ligne et dit vraiment ce qu'il faut

Un code de statut seul ne peut pas vous dire qu'une page s'est bien affichée - une réponse 200 avec une coquille vide est l'échec silencieux classique qu'une vérification limitée au statut manque.

status isOk
body contains "Add to cart"

Une API répond en JSON avec le champ attendu

Vérifiez que le point de terminaison parle toujours JSON, puis allez chercher dedans. La première ligne attrape une page d'erreur HTML servie là où du JSON était attendu, une forme de panne courante derrière un proxy ; la seconde vérifie l'état de santé rapporté par l'API elle-même, pas seulement son statut de transport.

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

La réponse a ralenti plus qu'elle ne le devrait

Décomposez quand vous avez besoin de savoir quoi corriger plutôt que juste que quelque chose est lent - time.connect, time.tls, time.dns et time.head séparent le temps réseau, de poignée de main, de résolveur et d'application.

time lt 2s

Une redirection a envoyé les visiteurs hors de votre propre domaine

Compare là où la vérification a atterri à l'URL que vous avez configurée - elle échoue dès qu'une chaîne de redirection, détournée, mal configurée, ou simplement changée par un déploiement, atterrit quelque part que vous ne vouliez pas.

url.host eq url.original.host

La page a changé depuis la dernière vérification

Utile sur un contenu censé rester stable entre les vérifications - tarification, conditions, une politique publiée - et fait aussi office de signal basique de défiguration.

previous.body.hash eq body.hash

Un nombre dans une plage, écrit de la façon courte

Attrape à la fois une page dépouillée et une page qui s'emballe dans une seule règle, sans écrire une plage explicite.

body.size between 50 and 500kb

Un certificat sur le point d'expirer

La vérification TLS la plus courante de loin, et l'une qu'un simple moniteur actif/en panne ne peut pas exprimer du tout - un certificat encore valide aujourd'hui mais qui expire la semaine prochaine ne donne aucun autre signe d'alerte. Associez-la à cert.issuer si vous voulez aussi attraper un certificat émis discrètement par la mauvaise autorité.

cert.days.left gt 14

Une requête de base de données renvoyant le mauvais nombre de lignes

Sur une vérification Database, rows est la collection qu'une requête a affectée ou renvoyée - la compter attrape une requête censée renvoyer exactement un enregistrement de compte qui se met silencieusement à en renvoyer zéro (supprimé, ou une jointure cassée) ou plus d'un (un doublon qui ne devrait pas exister).

rows.count eq 1

Une valeur SNMP qui dérive hors de sa plage

Un équipement SNMP qui répond n'est pas la même chose qu'un équipement en bonne santé - un OID surveillé (utilisation disque, profondeur de file d'attente, température) peut grimper bien au-delà d'un seuil sûr pendant que l'équipement lui-même reste parfaitement joignable. Comparer la value interrogée à une plage attrape ce qu'une simple vérification de joignabilité ne peut pas.

value lt 90

Un service TCP qui répond avec la mauvaise bannière

Un port qui accepte les connexions n'est pas la même chose que le bon service qui écoute dessus - un processus figé, un proxy mal configuré, ou un service dégradé/substitué peuvent tous quand même compléter une poignée de main TCP. Lire le texte d'accueil qu'un service envoie juste après la connexion (une bannière SMTP, FTP ou similaire) attrape ce qu'une simple vérification de port ouvert ne peut pas.

banner contains "220"

Comparer à la vérification précédente

Une poignée de sujets regardent en arrière au lieu de seulement la réponse actuelle : mettez previous. devant un sujet pour lire ce qu'il était à la dernière vérification, ou enveloppez-le dans delta(...) pour obtenir la différence entre alors et maintenant, ou dans delta2(...) pour obtenir le changement de ce changement - utile pour repérer une valeur qui accélère plutôt qu'elle ne dérive (un temps de réponse qui monte plus vite à chaque vérification). previous.body.hash eq body.hash ci-dessus est exactement cela - « l'empreinte du corps correspond-elle à ce qu'elle était la dernière fois ». delta(body.size, h) lit le changement comme un taux par heure plutôt qu'une différence brute, pour des valeurs censées croître régulièrement plutôt que sauter.

La première fois qu'une règle comme celle-ci s'exécute, elle n'a rien à quoi comparer, donc elle est ignorée plutôt qu'en échec : la vérification est marquée « en chauffe », pas cassée, et ajouter la règle ne déclenche aucune fausse alerte. La chauffe ne s'applique que quand la lecture actuelle est saine et que la référence manque. Si la lecture actuelle elle-même échoue (disons, le corps n'est pas du JSON valide cette fois), la règle échoue exactement comme le ferait sa version simple, sans previous.. Une telle règle a aussi besoin que la valeur change entre les vérifications, ce qui la rend dénuée de sens sur une méthode de vérification qui ne fait jamais avancer l'état, une requête HEAD par exemple.

Comparer à la vérification précédente nécessite un forfait de niveau supérieur ; sans cela, ces sujets apparaissent grisés dans l'éditeur avec une explication.

Limites, et ce qui manque délibérément

Combien de règles vous pouvez ajouter dépend de votre forfait, montré comme un compteur en direct à côté de « Ajouter une règle ». Le moteur impose aussi un plafond absolu sur chaque vérification quel que soit le forfait, une protection contre les abus plutôt qu'une limite sur l'usage ordinaire : une vérification approchant ce nombre de règles serait déjà inhabituellement grande.

Il n'y a aucun moyen d'écrire du JavaScript personnalisé pour une règle, et il n'y en aura jamais. Chaque règle est construite à partir d'un vocabulaire fixe et nommé de sujets et de prédicats plutôt que d'un bac à sable de script ouvert, ce qui garde une règle lisible d'un coup d'œil et sûre à exécuter sur chaque agent de surveillance dans le monde.

Toutes les règles ne fonctionnent pas partout dès l'instant où elles sont écrites : certaines conditions plus récentes nécessitent une version récente de l'agent de surveillance qui exécute votre vérification, donc une nouvelle capacité met du temps à atteindre chaque vérification de votre compte à mesure que les agents se mettent à jour en arrière-plan. Les règles construites sur le socle stable du langage ne sont pas affectées.

Une poignée d'entrées de cette référence ne sont pas encore pleinement en service, et chacune est étiquetée dans son tableau ci-dessus :

  • Réservé (déclaré, pas encore peuplé par aucun agent) : ttfb, httpVersion, cert.subject.
  • Candidat (déjà en cours de déploiement, pas encore sur tous les agents) : conn.ip.family et conn.failedIps sur les vérifications HTTP, Port et Ping, value.type sur les vérifications SNMP, banner.hash et banner.size sur les vérifications Port, sentCount sur les vérifications Ping, et le time propre à la vérification Counter.
  • Pas encore disponible : steps, réservé à un futur type de vérification multi-étapes.
  • Nécessite un forfait avec assertions à état : toute la famille d'enveloppes previous / delta / delta2, sur chaque type de vérification.

Tout le reste de cette référence est vivant aujourd'hui sur tout forfait ayant le mode assertion.

Où le mode assertion fonctionne aujourd'hui

L'interrupteur Validation de la réponse pour le mode assertion apparaît sur les moniteurs HTTP (site web) et API, qui partagent le même éditeur de règles et la même syntaxe. Le même langage et le même évaluateur tournent déjà en dessous des vérifications Database, Counter, Port, Ping et SNMP au niveau du protocole : le registre ci-dessus sert les six types de vérification, et une règle enregistrée pour l'un se lit de la même façon si le mode atteint l'éditeur d'un autre type plus tard.

SNMP montre l'aperçu le plus clair : son éditeur a déjà un panneau Règles d'assertion nommant value et value.type, étiqueté « Bientôt disponible », sans liste de règles fonctionnelle derrière pour l'instant. Les vérifications Database, Counter et Ping ne montrent aucun panneau de mode assertion du tout, même si leurs sujets sont tout aussi vivants dans le moteur sous-jacent.

Mettre en place une vraie vérification

Si vous validez une API REST plutôt qu'une simple page web, commencez par la validation de réponse API, qui couvre ensemble l'uptime, le temps de réponse et le corps de votre propre API. Pour une page ou un site qui doit rester en ligne et répondre correctement depuis partout où se trouvent vos utilisateurs, la surveillance d'uptime mondiale depuis plus de 300 emplacements est le tableau d'ensemble dans lequel s'insère le mode assertion. Pour définir des règles par le code plutôt que par le panneau, la propre API v2 de HostTracker crée et met à jour les règles d'assertion d'un moniteur de la même façon que l'éditeur. Pour la règle d'expiration de certificat ci-dessus et tout ce qui touche à TLS, la surveillance de domaine et de certificat TLS couvre le type de vérification sur lequel vivent cert.days.left et les autres sujets TLS. Pour voir une règle s'évaluer contre une vraie URL dès maintenant, sans compte, utilisez l'outil gratuit de vérification HTTP. Pour les codes de statut auxquels le sujet status compare, commencez par 200 OK, et les guides de surveillance couvrent la mise en place de chaque type de vérification sous lequel ce langage tourne.

Questions fréquentes

Qu'advient-il de mes anciens réglages de code de statut et de mot-clé si j'active le mode assertion ?

Ils sont remplacés par la liste de règles tant que le mode est actif. Le désactiver de nouveau avant d'enregistrer restaure les champs classiques exactement comme ils étaient : rien n'est supprimé, les deux modes ne peuvent simplement pas être actifs en même temps.

Puis-je combiner plusieurs conditions dans un seul moniteur ?

Oui : chaque règle de la liste doit réussir. Il n'y a pas encore de « OU » entre des règles séparées, donc pour accepter l'une de plusieurs valeurs, utilisez une seule règle avec in [...] ou containsAny [...].

Le mode assertion me laissera-t-il un jour écrire mon propre script ?

Non. Chaque règle est composée à partir de l'ensemble fixe de sujets et de prédicats du langage. Il n'y a pas de JavaScript personnalisé, par conception.

Que se passe-t-il la première fois que j'ajoute une règle qui compare à la vérification précédente ?

Elle n'a encore rien à quoi comparer, donc elle est marquée comme en chauffe et ignorée plutôt qu'en échec. Ajouter une règle « est-ce que ça a changé » ne déclenche jamais de fausse alerte à elle seule.

Ai-je besoin d'un forfait précis pour utiliser le mode assertion ?

Le mode lui-même et les règles du quotidien (statut, corps, en-têtes, timing, redirections) sont largement disponibles ; combien de règles vous pouvez ajouter à la fois dépend de votre forfait et est montré en direct dans l'éditeur. Les règles qui comparent à une vérification précédente (previous, delta, delta2) nécessitent un forfait de niveau supérieur et sont grisées avec une explication.

Le mode assertion fonctionne-t-il sur les moniteurs API de la même façon que sur les moniteurs de site web ?

Oui. Les moniteurs HTTP et API partagent le même éditeur de règles, les mêmes sujets et les mêmes prédicats, et une règle écrite pour l'un se lit de façon identique sur l'autre.

Que fait vraiment where(...), et quand en ai-je besoin ?

Il filtre une collection jusqu'aux éléments correspondant à une condition avant que vous ne lisiez un champ du résultat. Utilisez-le quand une simple projection comme requests.status n'est pas assez précise et que vous avez besoin d'un saut, d'un lien ou d'un élément particulier plutôt que de toute la collection (voir la section ci-dessus).

Puis-je écrire une règle contre une requête de base de données, une valeur SNMP, une bannière de port ou un résultat de ping aujourd'hui ?

Le langage et l'évaluateur les prennent tous en charge, et les tableaux de sujets ci-dessus couvrent chacun d'eux. L'éditeur de règles, non : seuls les moniteurs HTTP et API montrent l'interrupteur Validation de la réponse aujourd'hui. SNMP montre un aperçu « Bientôt disponible » de ses deux sujets, et Database, Counter et Ping ne montrent aucun panneau de mode assertion du tout.

Pourquoi certains sujets de cette référence disent-ils « réservé » ou « candidat » plutôt que d'être simplement listés normalement ?

« Réservé » signifie que le champ est déclaré dans le registre mais qu'aucun agent ne le peuple encore ; « candidat » signifie qu'il est en cours de déploiement vers les agents mais ne les a pas tous atteints. Les deux sont signalés partout où ils apparaissent dans cette référence et dans la liste récapitulative de la section Limites ci-dessus.

Vérifier maintenant

Lancez la vérification gratuite sur votre propre site, sans créer de compte.

Web api validation

Surveiller en permanence

Soyez alerté dès que quelque chose casse : HostTracker vérifie depuis plus de 300 emplacements et vous prévient par e-mail, SMS, Slack, Telegram et plus encore.

Fonctionnalités HostTracker

Plus dans cette section: Guides de surveillance : chaque type de vérification, pas à pas