Przejdź do treści głównej

Poradniki / Przewodniki po monitoringu: każdy typ kontroli krok po kroku

Tryb asercji: pełny słownik weryfikacji odpowiedzi

Tryb asercji zastępuje stałe pola przejścia/niepowodzenia monitora listą reguł, które piszesz sam, a każda reguła nazywa dokładnie to, co musi być prawdą w odpowiedzi. Większość monitorów uptime osądza sprawdzenie na podstawie garstki stałych pól: kodu statusu, który liczy się jako "Down", listy statusów do zignorowania, może słowa kluczowego, które musi się gdzieś pojawić w treści. Te pola nie potrafią wyrazić API, które zgodnie z zamierzeniem odpowiada 404 dla brakującego zasobu, strony, która zwraca 200 z pustą powłoką, bo baza danych przekroczyła czas oczekiwania, albo łańcucha przekierowań, który zaczyna prowadzić przez cudzą domenę.

Tryb asercji HostTracker zastępuje te stałe pola niewielkim językiem reguł, który piszesz sam, regułę po regule, wewnątrz edytora monitora. Każda reguła mówi dokładnie, co musi być prawdą w odpowiedzi: status, fragment treści, nagłówek, jak długo to trwało, dokąd trafiło przekierowanie. Sprawdzenie zawodzi tylko wtedy, gdy zawiedzie jedna z Twoich reguł. To ten sam język dla strony internetowej, REST API, zapytania do bazy danych, portu TCP, celu Ping, licznika SNMP czy ogólnego sprawdzenia Counter: jeden zestaw podmiotów, jeden zestaw predykatów, używany wszędzie tam, gdzie pojawia się ten tryb. Ten poradnik omawia każdy podmiot, operator, reduktor, skrót cukru składniowego i formę składni, którą implementuje silnik.

Co zastępuje tryb asercji

Klasyczne pola Weryfikacji odpowiedzi wciąż tam są, gdy tryb asercji jest wyłączony: oczekiwany zakres statusu, lista statusów do zignorowania, słowo kluczowe, które musi (lub nie może) się pojawić. Tryb to przełącznik, który zamienia ten stały zestaw na listę reguł budowaną przez Ciebie, a jego ponowne wyłączenie przed zapisaniem przywraca klasyczne pola dokładnie takimi, jakie były. Żaden monitor nie jest przypisany na stałe do jednego trybu.

Jeden język zamiast stosu osobnych gadżetów dla każdego typu składa się w całość. Sprawdzenie "musi być JSON i zawierać pole", sprawdzenie "musi nadal mówić Add to cart" i sprawdzenie "nie może zwolnić" to trzy reguły w tej samej składni, na tej samej liście, każda przechodzi lub zawodzi niezależnie.

Włączanie trybu

Tryb asercji znajduje się wewnątrz sekcji Weryfikacja odpowiedzi edytora monitora, dla monitorów HTTP (strona) i API. Przełącz przełącznik, a klasyczne pola zostaną zastąpione numerowaną listą reguł z przyciskiem "Add rule" i żywym licznikiem pokazującym, ile reguł wykorzystałeś względem limitu swojego planu.

Tryb asercji włączony, zbudowana i zwalidowana pierwsza reguła

Każda reguła jest walidowana w miarę budowania: reguła jeszcze nieukończona niesie odrębny stan "niedokończona", a reguła, którą edytor potrafi obliczyć, jest oznaczana jako kompletna. Każda reguła ma też mały przycisk </>, który otwiera jej formę w postaci zwykłego tekstu, więc możesz odczytać lub skopiować dokładne wyrażenie zamiast patrzeć tylko na widok pole po polu.

Model myślowy: podmiot, predykat, wartość

Każda reguła ma tę samą postać: podmiot (kod statusu, treść, nagłówek, czas odpowiedzi), predykat (równe, zawiera, istnieje, jest mniejsze niż) i, dla większości predykatów, wartość do porównania. status eq 200 to podmiot, predykat i wartość; body.json exists to podmiot i predykat bez wartości, bo "exists" niczego więcej nie potrzebuje.

Budowanie reguły w edytorze zaczyna się od wybrania, co sprawdzić, potem warunku, potem wartości:

Budowanie drugiej reguły: selektor pola wymienia każdy podmiot z jego typem i przykładem

Reguły na liście są łączone przez AND: sprawdzenie zawodzi, gdy zawiedzie choćby jedna reguła, i przechodzi tylko wtedy, gdy przejdą wszystkie. OR jeszcze nie istnieje, więc żeby zaakceptować jeden z kilku statusów lub ciągów znaków, wyraź to wewnątrz jednej reguły (status in [200, 301, 302], body containsAny ["In stock", "Pre-order"]). Reguła, która zawodzi, nazywa samą siebie w alercie, więc nadawaj każdej krótką etykietę tam, gdzie możesz, a alert powie, które oczekiwanie zostało złamane.

Co możesz sprawdzać

Selektor grupuje podmioty według własnego dokumentu odpowiedzi (treść, nagłówki) i jej transportu (status, czas, przekierowania, TLS). Kilka najważniejszych podmiotów, z pełną listą w dalszym słowniku:

PodmiotCo to jestPrzykład
statusKod statusu HTTP odpowiedzi końcowej, po przejściu przekierowaństatus isOk
bodyTreść odpowiedzi jako zwykły tekstbody contains "Add to cart"
body.json / body.xml / body.html / body.yamlTreść, ale tylko gdy rzeczywiście da się ją sparsować w tym formacie - w przeciwnym razie podmiot po prostu nie istniejebody.json exists
body.json.path("$.a")Zapytanie JSONPath do treści JSON (ten sam język zapytań działa też nad YAML, bo YAML parsuje się do tego samego modelu obiektowego)body.json.path("$.status") eq "ok"
body.size / body.hashRozmiar odpowiedzi w bajtach i odcisk palca treścibody.size gt 1kb
header("Name")Jeden nagłówek odpowiedzi, wyszukany po nazwieheader("Content-Type") isJson
time oraz time.connect / time.tls / time.dns / time.headCałkowity czas odpowiedzi oraz jego fazy: sieć, handshake TLS, DNS i czas myślenia serweratime lt 2s
redirects / requestsPrzeskoki, przez które przeszło sprawdzenie, i cały łańcuch (łącznie z odpowiedzią końcową)redirects.count eq 0
url i jego części (.host, .scheme, .path...)Końcowy URL, na którym sprawdzenie wylądowałourl.scheme eq "https"
cert.days.leftDni pozostałe do wygaśnięcia certyfikatu TLScert.days.left gt 14

Liczby przyjmują sufiksy jednostek, więc nigdy nie musisz przeliczać ręcznie: 2s oznacza 2000 milisekund, 1kb oznacza 1024 bajty. Porównania tekstu są wrażliwe na wielkość liter, chyba że dodasz do reguły nocase.

Pełny słownik

Poniżej znajduje się każdy podmiot, operator, reduktor, skrót cukru składniowego, filtr i forma składni, które silnik asercji rejestruje dla sprawdzeń HTTP i API, zaczerpnięte wprost z własnego rejestru silnika (te same dane, które zasilają selektory edytora reguł i jego dokumentację). Wpisy, które nie są jeszcze w pełni dostępne, niosą notatkę w nawiasie: zarezerwowane pola, których silnik jeszcze nie zaczął wypełniać, kandydaci wciąż wdrażani na agentów, oraz rodzina ze stanem, wymagająca konkretnego planu. Wszystko bez takiej notatki działa już dziś na każdym planie z trybem asercji.

Słownik podąża za własnym grupowaniem silnika: najpierw pola odpowiedzi, potem sposoby sięgania w głąb treści, potem czas, sieć i TLS, potem operatory, reduktory i skróty działające na nich wszystkich, a na końcu rodzaje sprawdzeń poza HTTP mówiące tym samym językiem.

Odpowiedź

Podmioty opisujące samą odpowiedź: jej status, surową treść, jej nagłówki, URL, z którego faktycznie odpowiedziała, oraz łańcuch żądań, które do niej doprowadziły.

NazwaCo to jestTyp/wartościPrzykład
bodyTreść odpowiedzi jako zdekodowany tekst.stringbody contains "Welcome"
headerJeden nagłówek odpowiedzi końcowej, po nazwie.stringheader("Content-Type") isJson
redirectsPrzeskoki przekierowań, które zostały przebyte - łańcuch żądań bez jego ostatniego elementu.collectionredirects.count eq 0
statusKod statusu HTTP odpowiedzi końcowej, po przejściu przekierowań.numberstatus isOk
body.sizeRozmiar pobranej treści, w bajtach.numberbody.size lt 500000
urlURL, który faktycznie odpowiedział, po wszystkich przekierowaniach. url: porównaj go jako tekst albo odczytaj jego części (url.host, .port, .path, .query, .scheme).urlurl.host eq "www.example.com"
requestsKażde żądanie wykonane przez to sprawdzenie, w kolejności - przeskoki przekierowań, a potem żądanie końcowe.collectionrequests.count le 2
url.hostCzęść URL z hostem.stringurl.host eq "example.com"
url.pathCzęść URL ze ścieżką.stringurl.path startsWith "/api"
url.portCzęść URL z portem.numberurl.port eq 443
url.queryCiąg zapytania URL.stringurl.query contains "token"
url.schemeSchemat URL (http lub https).stringurl.scheme eq "https"
body.hashSkrót treści odpowiedzi - porównaj z previous.body.hash, aby wykryć zmiany treści.stringbody.hash eq previous.body.hash
httpVersion (zarezerwowane - jeszcze niewypełniane)Wynegocjowana wersja HTTP.stringhttpVersion eq "HTTP/2"
setCookieWartości Set-Cookie odpowiedzi końcowej, po jednym elemencie na ciasteczko - dopasuj jedno przez contains lub matches, policz przez .count.collectionsetCookie exists
steps (jeszcze niedostępne)Kroki sprawdzenia wieloetapowego. Jeszcze niedostępne.collectionsteps.count le 1
url.originalURL, z którym skonfigurowano sprawdzenie, przed jakimkolwiek przekierowaniem. url taki jak sam url: te same części (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.original.hostCzęść URL z hostem.stringurl.original.host eq "example.com"
url.original.pathCzęść URL ze ścieżką.stringurl.original.path startsWith "/start"
url.original.portCzęść URL z portem.numberurl.original.port eq 80
url.original.queryCiąg zapytania URL.stringurl.original.query contains "utm_"
url.original.schemeSchemat URL (http lub https).stringurl.original.scheme eq "http"

Dwa aliasy: redirectCount to skrót od redirects.count - redirectCount eq 0 brzmi trochę naturalniej niż równoważna długa forma, gdy chodzi Ci o "sprawdzenie odpowiedziało bezpośrednio, bez przekierowań." A setCookie na najwyższym poziomie to lista ciasteczek odpowiedzi końcowej; ta sama nazwa pojawia się ponownie per-przeskok wewnątrz requests/redirects (zobacz Podmioty przeskoków poniżej), przechowując ciasteczka tylko tego jednego żądania.

Wyciąganie wartości z treści

Te podmioty rozwiązują się tylko wtedy, gdy treść jest w formacie, który nazywają: przestrzeń nazw JSON na stronie HTML po prostu nie istnieje, to nie jest typowany błąd. To sprawia, że exists jest standardowym sposobem sprawdzenia formatu, a body.json exists pyta, czy treść sparsowała się jako JSON. Każda z czterech przestrzeni nazw formatów niesie pasującą funkcję zapytania .path(...) (JSONPath dla json/yaml, XPath dla xml, selektory CSS dla html) i pasujące .regex(...), plus niezależne od formatu body.regex(...), które odczytuje surowy tekst niezależnie od formatu. body.html.a, body.html.script i body.html.link to gotowe kolekcje każdego linku, skryptu i elementu <link> na stronie; zobacz Zakresy elementów poniżej dla pól dostępnych na każdym z nich.

NazwaCo to jestTyp/wartościPrzykład
body.jsonTreść odpowiedzi, ale tylko gdy rzeczywiście jest JSON.stringbody.json exists
body.json.pathZapytaj treść JSON wyrażeniem JSONPath.jsonbody.json.path("$.status") eq "ok"
body.htmlTreść odpowiedzi, ale tylko gdy rzeczywiście jest HTML.stringbody.html exists
body.html.pathWybierz elementy strony selektorem CSS.collectionbody.html.path("h1").first contains "Welcome"
body.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists
body.xmlTreść odpowiedzi, ale tylko gdy rzeczywiście jest XML.stringbody.xml exists
body.xml.pathZapytaj treść XML wyrażeniem XPath.stringbody.xml.path("//item/@id") exists
body.html.aKażdy link na stronie.collectionbody.html.a.count gt 0
body.html.linkKażdy <link> zadeklarowany przez stronę. Sama wzmianka oznacza cele linków.collectionbody.html.link.count gt 0
body.html.scriptKażdy skrypt wczytywany przez stronę. Sama wzmianka oznacza źródła skryptów.collectionbody.html.script.count gt 0
body.yamlTreść odpowiedzi, ale tylko gdy rzeczywiście jest YAML.stringbody.yaml exists
body.yaml.pathZapytaj treść YAML wyrażeniem JSONPath.jsonbody.yaml.path("$.services.web.image") contains ":1."
body.html.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists
body.json.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists
body.xml.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists
body.yaml.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists

Szczegół rodziny regex wart wspomnienia: nazwane grupy przechwytujące ((?<id>...)) wewnątrz reguły .regex(...) zapisują się do przestrzeni powiązań w zasięgu sprawdzenia, którą późniejsza reguła może odczytać przez bind("id") lub bind[0] po pozycji - zobacz Przechwycone wartości poniżej.

Przechwycone wartości

Jeden podmiot ma własną grupę w rejestrze, bo nie czyta odpowiedzi bezpośrednio - czyta to, co przechwyciła z niej wcześniejsza reguła.

NazwaCo to jestTyp/wartościPrzykład
bindWartość przechwycona przez wcześniejszą regułę regex, po nazwie przechwycenia lub po pozycji.stringbind("id") gt 1000

Połącz to z regułą regex wcześniej na liście: reguła taka jak body.regex("order-(?<id>\d+)") exists przechwytuje id zamówienia pod nazwą id, a późniejsza reguła może to przetestować przez bind("id") gt 1000 albo, dla przechwycenia pozycyjnego (bez nazwy), bind[0].

Czas

Jedna suma plus podział na fazy, żeby alert "spowolniło" mógł też powiedzieć, która część zwolniła.

NazwaCo to jestTyp/wartościPrzykład
timeCałkowity czas odpowiedzi: connect + TLS + oczekiwanie + pobieranie. Rozwiązywanie DNS nie jest wliczone.numbertime lt 2000
ttfb (zarezerwowane - jeszcze niewypełniane)Czas do pierwszego bajtu.numberttfb lt 200
time.connectCzas ustanowienia połączenia TCP.numbertime.connect lt 500
time.dataCzas pobrania treści odpowiedzi.numbertime.data lt 1000
time.dnsCzas rozwiązania nazwy domeny. Niewliczony do samego podmiotu time.numbertime.dns lt 200
time.headCzas oczekiwania na nagłówki odpowiedzi.numbertime.head lt 500
time.tlsCzas handshake TLS.numbertime.tls lt 300

Sam podmiot time to connect + TLS + oczekiwanie na nagłówki + pobieranie treści. Rozwiązywanie DNS jest wykluczone i żyje tylko w bratnim time.dns, bo DNS jest często cache'owany i w przeciwnym razie ten sam endpoint wyglądałby na niespójnie szybki lub wolny między sprawdzeniami.

Sieć: DNS i połączenie

dns i conn to czyste przestrzenie nazw w rejestrze - grupa bez własnej wartości, więc reguła nigdy nie może zakończyć się na samej nazwie (zarówno edytor, jak i silnik odrzucają łańcuch kończący się na samym dns lub conn, kierując Cię do prawdziwych pól poniżej).

NazwaCo to jestTyp/wartościPrzykład
connPołączenie sieciowe wykonane przez sprawdzenie - adres, który obsłużył odpowiedź, i wszelkie błędy połączenia.string-
conn.failedIle z rozwiązanych adresów nie udało się połączyć.numberconn.failed eq 0
conn.failedIps (kandydat - wdrażane na agentów)Rozwiązane adresy, które nie połączyły się.collectionconn.failedIps.count eq 0
conn.ipAdres IP, który faktycznie obsłużył odpowiedź.stringconn.ip eq "203.0.113.10"
conn.ip.family (kandydat - wdrażane na agentów)Czy odpowiedź została obsłużona przez IPv4, czy IPv6.stringconn.ip.family eq "IPv4"
dnsRozwiązywanie DNS monitorowanej nazwy - na jakie adresy się rozwiązała i który serwer odpowiedział.string-
dns.ipsWszystkie adresy IP, na które rozwiązała się nazwa domeny podczas tego sprawdzenia.collectiondns.ips contains "1.2.3.4"
dns.serverSerwer DNS, który odpowiedział na rozwiązanie.stringdns.server eq "8.8.8.8"

TLS i certyfikat

Podobnie jak dns i conn, tls i cert to czyste przestrzenie nazw - fakty o certyfikacie/handshake żyją jeden poziom niżej.

NazwaCo to jestTyp/wartościPrzykład
cert.days.leftDni pozostałe do wygaśnięcia certyfikatu witryny.numbercert.days.left gt 14
certCertyfikat przedstawiony przez serwer - dni do wygaśnięcia, wystawca i pola tożsamości.string-
cert.daysDni od wystawienia certyfikatu.numbercert.days gt 0
cert.issuerUrząd certyfikacji, który wystawił certyfikat witryny.stringcert.issuer contains "Let's Encrypt"
cert.sanNazwy domen, dla których certyfikat jest ważny.collectioncert.san contains "www.example.com"
cert.serialNumer seryjny certyfikatu.stringcert.serial exists
cert.subject (zarezerwowane - jeszcze niewypełniane)Podmiot certyfikatu. Jeszcze nieprzechwytywane - pojawi się z przyszłą wersją agenta.stringcert.subject contains "example.com"
tlsHandshake TLS zabezpieczonego połączenia - wynegocjowana wersja protokołu i szyfr.string-
tls.cipherWynegocjowany zestaw szyfrów.stringtls.cipher contains "AES"
tls.protocolWynegocjowana wersja TLS.stringtls.protocol eq "Tls13"

cert.subject jest wymieniony tutaj dla kompletności, ale nie jest jeszcze wypełniany - zobacz sekcję Uczciwość poniżej, co w praktyce oznacza "zarezerwowane". Codzienna reguła certyfikatu to cert.days.left gt 14, omówiona w sekcji gotowych reguł.

Podmioty przeskoków: pola wewnątrz requests i redirects

requests i redirects to kolekcje, a każdy element to pełny rekord żądania/odpowiedzi z własnym, zredukowanym zestawem pól. Nie każdy podmiot najwyższego poziomu ma sens per-przeskok (przeskok nie ma własnego certyfikatu), a jedno pole istnieje tylko per-przeskok: hstsHeader, nagłówek Strict-Transport-Security tego żądania w łańcuchu.

NazwaCo to jestTyp/wartościPrzykład
statusKod statusu tego żądania w łańcuchu.numberstatus eq 200
urlURL, do którego wykonano to żądanie.urlurl startsWith "https://"
headerNagłówek odpowiedzi tego żądania. Przeskok trzyma zredukowany, jednowartościowy rekord nagłówka - predykaty listowe (containsAny, containsAll, unique) stosują się tylko do nagłówka odpowiedzi końcowej.stringheader("Content-Type") contains "json"
hstsHeaderNagłówek Strict-Transport-Security tego żądania.stringrequests[0].hstsHeader exists
setCookieWartości nagłówka Set-Cookie tego żądania.collectionsetCookie exists
url.originalURL, z którym skonfigurowano sprawdzenie, przed jakimkolwiek przekierowaniem. url taki jak sam url: te same części (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.hostCzęść URL z hostem.stringurl.host eq "example.com"
url.portCzęść URL z portem.numberurl.port eq 443
url.pathCzęść URL ze ścieżką.stringurl.path startsWith "/api"
url.queryCiąg zapytania URL.stringurl.query contains "token"
url.schemeSchemat URL (http lub https).stringurl.scheme eq "https"
url.original.hostCzęść URL z hostem.stringurl.original.host eq "example.com"
url.original.portCzęść URL z portem.numberurl.original.port eq 80
url.original.pathCzęść URL ze ścieżką.stringurl.original.path startsWith "/start"
url.original.queryCiąg zapytania URL.stringurl.original.query contains "utm_"
url.original.schemeSchemat URL (http lub https).stringurl.original.scheme eq "http"

Per-przeskokowy header(...) trzyma zredukowany, jednowartościowy rekord: predykaty listowe, takie jak containsAny czy unique, mają sens tylko na pełnej mapie nagłówków odpowiedzi końcowej, więc stosują się tam, a nie per-przeskok. Te dwie kolekcje znaczą coś innego. requests to cały łańcuch łącznie z odpowiedzią końcową, więc nigdy nie jest pusty nawet dla bezpośredniej odpowiedzi 200, podczas gdy redirects to tylko przeskoki przebyte po drodze, pusty, gdy nic nie przekierowało.

Zakresy elementów: pola wewnątrz jednego elementu kolekcji

Zakres elementu to zestaw pól dostępnych na JEDNYM elemencie kolekcji - po zaindeksowaniu do niego (requests[0]) albo przy filtrowaniu przez where(current. ...) (zobacz kolejną sekcję). Sześć kolekcji ma własny zakres elementu: cztery kolekcje elementów HTML dzielą jeden kształt, a requests/redirects dzielą kształt podmiotów przeskoku udokumentowany powyżej.

Zakres elementuJak wygląda jeden element
body.html.pathJeden element dopasowany przez zapytanie CSS body.html.path("selector").
body.html.aJeden element linku <a> z body.html.a.
body.html.scriptJeden element <script> z body.html.script.
body.html.linkJeden element <link> z body.html.link.
requestsJedno żądanie w pełnym łańcuchu (zobacz tabelę podmiotów przeskoku powyżej).
redirectsJeden przebyty przeskok przekierowania (te same pola co requests, zobacz powyżej).

Wspólny kształt dla body.html.path(...), body.html.a, body.html.script i body.html.link - jeden wiersz na link, tag script albo element <link>:

NazwaCo to jestTyp/wartościPrzykład
urlCel linku dokładnie tak, jak zapisuje go znacznik.stringbody.html.a.url contains "/checkout"
textWidoczny tekst elementu.stringbody.html.a.text contains "Sign in"
absoluteCel linku rozwiązany względem URL strony do adresu absolutnego - lista url, z częściami url dostępnymi na element (.host, .path, .port, .query, .scheme).urlbody.html.a.absolute.scheme in ["https"]
relAtrybut rel elementu.stringbody.html.a.where(current.rel eq "nofollow").count eq 0
absolute.hostCzęść URL z hostem.stringbody.html.a.absolute.host.unique.count le 3
absolute.portCzęść URL z portem.numberbody.html.a.absolute.port in [443]
absolute.pathCzęść URL ze ścieżką.stringbody.html.a.absolute.path startsWith "/"
absolute.queryCiąg zapytania URL.stringbody.html.a.absolute.query not contains "session"
absolute.schemeSchemat URL (http lub https).stringbody.html.a.absolute.scheme in ["https"]

Zanim napiszesz regułę wobec tych kolekcji, obowiązują dwa domyślne ustawienia. Sama wzmianka body.html.a (albo .script/.link) oznacza jej projekcję .url, więc body.html.a.count gt 0 liczy hrefy, a zapisana reguła odczytuje się z powrotem z wypisanym .url, bo zapisana reguła zawsze mówi dokładnie, co ocenia. A .url to surowy atrybut href dokładnie tak, jak zapisał go znacznik, więc link względny zostaje względny; .absolute to ten sam link rozwiązany względem własnego URL strony, czego chcesz przy sprawdzaniu schematu czy hosta linków wychodzących (body.html.a.absolute.scheme in ["https"]).

Operatory

Połowa predykatowa każdej reguły: jaki test uruchomić wobec podmiotu. Wszystkie 15 jest wspólnych dla każdego rodzaju sprawdzenia, a to, które pasują do danego podmiotu, zależy od jego typu (kod statusu przyjmuje lt/gt, treść przyjmuje contains, kolekcja przyjmuje exists/unique/in).

NazwaCo to jestStosuje się doPrzykład
eqRówne. Wobec literału json("…") / xml("…") / yaml("…") to DOKŁADNE dopasowanie strukturalne: te same klucze (w dowolnej kolejności), tablice w kolejności, te same wartości.dowolny typbody.json eq json("{\"ok\": true}")
ltMniejsze niż.liczbytime lt 2000
leMniejsze lub równe.liczbycert.days.left le 30
gtWiększe niż.liczbybody.size gt 0
geWiększe lub równe.liczbystatus ge 500
containsZawiera tekst - nad listą przechodzi, gdy wartość JEST jednym z elementów (dopasowanie dokładne; użyj matches, żeby szukać wewnątrz elementów). Wobec literału json("…") / xml("…") / yaml("…") to STRUKTURALNE zawieranie: wszystko, co stwierdza literał, musi być obecne i pasować; odpowiedź może mieć więcej.tekst lub listabody.json contains json("{\"status\": \"ok\"}")
startsWithZaczyna się od tekstu - nad listą, gdy KTÓRYKOLWIEK element tak zaczyna.teksturl.path startsWith "/api"
endsWithKończy się tekstem - nad listą, gdy KTÓRYKOLWIEK element tak się kończy.teksturl.path endsWith ".json"
matchesPasuje do wyrażenia regularnego gdziekolwiek w tekście - nad listą, gdy pasuje KTÓRYKOLWIEK element.tekstbody matches "order-\\d+"
containsAnyZawiera co najmniej jedną z wymienionych wartości (nad listą: jakiś element RÓWNA SIĘ jednej z nich).listabody containsAny ["In stock", "Pre-order"]
containsAllZawiera każdą z wymienionych wartości (nad listą: każda wartość równa się jakiemuś elementowi - świadkowie mogą się różnić).listabody.html.a.text containsAll ["Home", "Contact"]
inJest jedną z wymienionych wartości lub zakresów - nad listą, każdy element jest.wartość/wartości lub zakresstatus in [200, 301, 302]
existsPodmiot jest obecny.dowolny podmiotheader("ETag") exists
isNumberWartość da się odczytać jako liczbę.tekst lub dowolnebind("id") isNumber
uniqueLista nie ma duplikatów.listadns.ips unique

Dwa operatory znaczą coś węższego, niż brzmią. contains nad listą to dokładne członkostwo: wartość musi równać się całemu elementowi, a nie pojawiać się jako podciąg wewnątrz jednego, więc sięgnij po matches, gdy chcesz zachowania podciągu w elementach kolekcji. A eq wobec literału json(...)/xml(...)/yaml(...) to pełne dopasowanie strukturalne (te same klucze, tablice w tej samej kolejności, te same wartości), podczas gdy contains wobec tego samego rodzaju literału to strukturalne zawieranie: wszystko, co stwierdza literał, musi być obecne, ale prawdziwa odpowiedź może nieść więcej.

Reduktory

Reduktor zwija kolekcję do jednej wartości i może pojawić się tylko na końcu łańcucha. Poniższe przykłady używają requests.status, naturalnie numerycznej kolekcji tworzonej przez podmioty HTTP, jako ilustracji; tych samych osiem reduktorów działa na dowolnej kolekcji numerycznej w dowolnym rodzaju sprawdzenia (czasy round-trip sprawdzenia Ping, przefiltrowany zestaw wierszy bazy danych).

NazwaCo zwijaStosuje się doPrzykład
countIle elementów ma lista.dowolna kolekcjarequests.count le 2
minNajmniejsza liczba na liście.kolekcja numerycznarequests.status.min ge 200
maxNajwiększa liczba na liście.kolekcja numerycznarequests.status.max lt 500
sumSuma liczb na liście.kolekcja numerycznarequests.status.sum gt 0
avgŚrednia liczb na liście.kolekcja numerycznarequests.status.avg lt 300
firstPierwszy element listy.dowolna kolekcjaredirects.status.first eq 301
lastOstatni element listy.dowolna kolekcjarequests.status.last eq status
uniqueLista z usuniętymi duplikatami.dowolna kolekcjadns.ips.unique.count le 3

unique jest przeciążone, a zapis odróżnia dwa znaczenia. Zapisane jako operator bez kropki (x unique) to predykat, "ta kolekcja nie ma duplikatów", i zawodzi, nazywając powtórkę. Zapisane jako reduktor z kropką (x.unique) to transformacja, sama zdeduplikowana kolekcja, która wciąż potrzebuje czegoś po sobie (x.unique.count eq 1). Wiszące x.unique bez niczego po sobie to błąd składni, bo silnik nie potrafi odgadnąć, które z dwóch znaczeń miałeś na myśli.

Cukier składniowy

Predykaty cukru składniowego to skróty, które silnik rozwija w zwykłe predykaty rdzenia, zanim reguła w ogóle zostanie wysłana do agenta - dodanie predykatu cukru nie kosztuje nic dodatkowego (żadnego pakietu agenta, żadnego progu wersji), bo zanim dotrze na drut, już wygląda jak zwykła reguła. Preferuj cukier, gdziekolwiek istnieje: czyta się lepiej i jest dokładnie równoważny ręcznemu wypisaniu długiej formy.

NazwaCo oznaczaStosuje się doPrzykład
isOkStatus to kod sukcesu (200-299).status-
isRedirectStatus to kod przekierowania (300-399).statusstatus isRedirect
isClientErrorStatus to błąd klienta (400-499).statusstatus isClientError
isServerErrorStatus to błąd serwera (500-599).statusstatus isServerError
isJsonTreść rzeczywiście jest JSON.dokument lub tekst typu mediaheader("Content-Type") isJson
isXmlTreść rzeczywiście jest XML - treść parsuje się jako XML, albo nagłówek nazywa typ media XML.dokument lub tekst typu mediabody isXml
isHtmlTreść rzeczywiście jest HTML - treść parsuje się jako HTML, albo nagłówek nazywa typ media HTML.dokument lub tekst typu mediabody isHtml
isFormTyp media nazywa kodowanie formularza: application/x-www-form-urlencoded lub multipart/form-data. W odróżnieniu od isJson/isXml/isHtml nie ma pasującej przestrzeni nazw treści, więc to stosuje się tylko do wartości typu media, na przykład nagłówka Content-Type.tylko tekst typu mediaheader("Content-Type") isForm
isEmptyNic tam nie ma: pusty tekst, zerowy rozmiar albo pusta lista.tekst, rozmiar lub listabody isEmpty
isNullWartość jest null.dowolna wartośćbody.json.path("$.deletedAt") isNull
absentPodmiot w ogóle nie jest obecny.dowolny podmiotheader("X-Debug") absent
betweenLiczba w zakresie domkniętym.liczby (2 operandy)body.size between 50 and 500kb

isJson/isXml/isHtml są celowo zależne od kontekstu, a to, na czym je zapiszesz, decyduje, które znaczenie się stosuje. Zapisane na samym dokumencie (body isJson) oznaczają "czy to parsuje się jako ten format", tak samo jak body.json exists. Zapisane na wartości tekstowej nazywającej typ media, na przykład na nagłówku (header("Content-Type") isJson), oznaczają "czy to nazywa tę rodzinę MIME formatu"; zobacz Rodziny MIME poniżej, które typy media się kwalifikują. isForm ma tylko to drugie znaczenie, bo nie istnieje przestrzeń nazw body.form do sparsowania, więc body isForm to błąd statyczny, a nie reguła, która nigdy nie mogłaby być prawdziwa.

Filtr where(...)

Zachowaj tylko elementy, które pasują, a potem kontynuuj od nich. To jedyna konstrukcja filtrująca w języku i ma dokładnie jeden kształt: where(current.<pole> <warunek> <wartość>).

Filtrowanie różni się od projekcji: requests.url contains "cart" pyta, czy taki przeskok istnieje gdziekolwiek w łańcuchu, podczas gdy requests.where(current.url contains "cart").status pyta, co ten przeskok zwrócił. Filtrowanie nie zwija listy, więc zakończ przez .first, sprawdzenie in [...] albo .count. Idzie tylko jeden poziom i przyjmuje dokładnie jeden warunek.

CzęśćCo nazywaUwagi
current.<pole>Pole każdego filtrowanego elementu, zapisane po current.To połowa, którą ludzie mylą: current.url to URL pojedynczego przeskoku, nie odpowiedzi końcowej. Po current. mogą następować tylko własne pola elementu.
warunekDowolny zwykły predykat, łącznie z not i nocaseKażdy warunek, który działa na najwyższym poziomie reguły, działa też tutaj.
wartośćZ czym porównywane jest pole każdego elementuZwykle zwykła wartość. Podmiot zapisany tutaj jest czytany z ZEWNĘTRZNEJ odpowiedzi, nie z elementu - where(current.url eq url.original) porównuje każdy przeskok z URL, z którym skonfigurowano sprawdzenie, dlatego strona elementu musi wprost powiedzieć current..

Przykład: requests.where(current.url contains "cart").status.first eq 301 - zachowaj tylko przeskoki, których URL zawiera "cart", potem spójrz na status pierwszego z pasujących.

Jeszcze dwa ograniczenia, oba egzekwowane przez parser z własnym komunikatem: where nie może być zagnieżdżone wewnątrz innego where, a jego argument to dokładnie jeden warunek, bez and/or w środku. Stosuje się tylko do kolekcji, której elementy niosą nazwane pola (requests, body.html.a), nie do zwykłej zrzutowanej listy, takiej jak dns.ips, gdzie nie ma niczego, co mogłoby nazwać current..

Słownik składni

Wszystko inne, co definiuje gramatyka: jak nazwać regułę, jak zapisywać zakresy i listy, co oznacza sam podmiot bez niczego więcej, i drobne formy interpunkcyjne pojawiające się w wielu regułach.

FormaCo robiRodzajPrzykład
whereZachowaj tylko elementy, które pasują, a potem kontynuuj od nich.filtr kolekcjirequests.where(current.url contains "cart").status.first eq 301
notOdwraca warunek, który następuje.flagabody not contains "error"
nocasePorównaj tekst bez rozróżniania wielkości liter.flagabody contains "welcome" nocase
currentWewnątrz where(…) nazywa jeden filtrowany element.odniesienie do elementu (wewnątrz where)requests.where(current.status eq 301)
rangeZakres liczb, oba końce WŁĄCZONE.zakres liczbstatus in [200..299]
listLista wartości do porównania.lista wartościstatus in [200, 301, 302]
docLiteralTypowana wartość dokumentu do porównania strukturalnego: cytowany tekst jest parsowany jako JSON, XML lub YAML przy zapisie reguły.tekst json/xml/yamlbody.json contains json("{\"user\": {\"active\": true}}")
implicitExistsReguła nazywająca tylko podmiot sprawdza, że jest obecny: samo napisanie body.json zapisuje się jako body.json exists.linia z samym podmiotembody.json
indexWybiera JEDEN element listy po pozycji, licząc od 0.liczba całkowita od 0requests[0].status
labelOpcjonalna nazwa reguły, zapisana przed dwukropkiem.nazwa przed dwukropkiem"json ok": body.json exists
commentWszystko po # to notatka dla Ciebie samego; nie wpływa na sprawdzenie.tekst # na końcustatus isOk # the happy path

Kilka wartych zwykłego omówienia. label nadaje regule nazwę, która pojawia się w alercie zamiast wyrenderowanego wyrażenia; zapisz ją przed dwukropkiem, jak w "json ok": body.json exists. implicitExists oznacza, że linia nazywająca tylko podmiot bez predykatu to skrót od exists: zapisanie body.json zapisuje się jako body.json exists, a ponowne otwarcie reguły pokazuje wypisaną formę. range i list to dwa kształty, jakie może przyjąć wartość po in: zakres ([200..299], oba końce włączone) albo jawna lista ([200, 301, 302]), a wartość może być otwarta na jednym z końców ([400..]). docLiteral to opakowanie json(...)/xml(...)/yaml(...) używane do porównania strukturalnego z treścią (omówione w Operatorach powyżej i w gotowych regułach poniżej). index wybiera jeden element kolekcji po pozycji, licząc od 0, tak samo jak bind[0] odczytuje przechwycenie pozycyjne. current ma znaczenie tylko wewnątrz filtra where(...), omówionego we własnej sekcji powyżej.

Opakowania: previous, delta i delta2

Trzy formy patrzące wstecz zamiast tylko na bieżącą odpowiedź - każda jest zablokowana za planami z asercjami stanowymi, a każda jest wyjaśniona w pełni w sekcji "Porównywanie z poprzednim sprawdzeniem" poniżej.

NazwaCo to jestTyp/wartościPrzykład
delta (wymaga planu z asercjami stanowymi)Jak bardzo wartość numeryczna zmieniła się od poprzedniego sprawdzenia - opcjonalnie jako tempo na ms/s/m/h.numberdelta(body.size, h) lt 1mb
delta2 (wymaga planu z asercjami stanowymi)Zmiana zmiany - czy wartość przyspiesza?numberdelta2(time) gt 0
previous (wymaga planu z asercjami stanowymi)Wartość tego podmiotu z poprzedniego sprawdzenia.dowolnestatus eq previous.status

Flagi: not i nocase

Dwa modyfikatory dołączane do reguły, a nie stojące jako samodzielne podmioty czy predykaty.

FlagaCo robiRodzajPrzykład
notOdwraca warunek, który następuje.flaga (dołącza się do reguły)body not contains "error"
nocasePorównaj tekst bez rozróżniania wielkości liter.flaga (dołącza się do reguły)body contains "welcome" nocase

not łączy się z predykatem, który następuje, a nie neguje całej reguły jako jednostki - x not != y czyta się jak x eq y, nie jak podwójne zaprzeczenie. Gdy podmiot może być całkowicie nieobecny, preferuj cukier absent zamiast not exists: te dwa znaczą dokładnie to samo, ale absent mówi to wprost. nocase zmienia coś tylko przy porównaniu naprawdę tekstowym; edytor (i ten słownik) wciąż pozwala zapisać to wszędzie, ale jest bez znaczenia przy teście numerycznym, jak status eq 200 nocase.

Rodziny MIME

Tabele wyszukiwania stojące za isJson, isXml, isHtml i isForm, gdy stosuje się je do wartości typu media, takiej jak nagłówek. Każda rodzina dopasowuje oczywisty typ media najwyższego poziomu plus, dla JSON i XML, dowolny typ kończący się pasującym sufiksem składni strukturalnej - to sprawia, że header("Content-Type") isJson poprawnie przechodzi na application/problem+json czy application/vnd.api+json, a nie tylko na zwykłym application/json.

RodzinaDopasowujeSparowany cukierPrzykład
jsonapplication/json, text/json albo dowolny typ media kończący się na +json (application/problem+json, application/vnd.api+json, application/ld+json, ...).cukier: isJsonheader("Content-Type") isJson
xmlapplication/xml, text/xml albo dowolny typ media kończący się na +xml (image/svg+xml, application/atom+xml, ...).cukier: isXmlheader("Content-Type") isXml
htmltext/html albo application/xhtml+xml.cukier: isHtmlheader("Content-Type") isHtml
formapplication/x-www-form-urlencoded albo multipart/form-data.cukier: isFormheader("Content-Type") isForm

Dopasowanie ignoruje wszystko od pierwszego ; wzwyż (więc application/json; charset=utf-8 wciąż pasuje) i nie rozróżnia wielkości liter.

Podmioty dla sprawdzeń bazy danych, licznika, SNMP, portu i ping

Każdy operator, reduktor, skrót cukru i forma składni powyżej jest identyczny dla tych pięciu rodzajów sprawdzeń: silnik rejestruje te same 15 operatorów, 8 reduktorów, 12 predykatów cukru i 11 form składni dla wszystkich sześciu rodzajów bez wyjątku. Tym, co różni się w zależności od rodzaju, jest lista podmiotów. Każdy rodzaj eksponuje mały zestaw podmiotów unikalnych dla tego, co mierzy, plus podzbiór podmiotów sieciowych/czasowych/TLS już udokumentowanych powyżej, ze znaczeniem dostosowanym do rodzaju (time sprawdzenia Database to connect-plus-zapytanie, a nie connect-plus-TLS-plus-pobieranie, bo nie ma odpowiedzi HTTP do pobrania).

Sprawdzenia bazy danych

Dzieli time, time.connect i time.dns z podmiotami udokumentowanymi powyżej (przeskalowane do połączenia z bazą danych: connect-plus-zapytanie, rozwiązywanie DNS hosta bazy danych). Unikalne dla sprawdzeń bazy danych:

NazwaCo to jestTyp/wartościPrzykład
scalarPojedyncza wartość zwrócona przez zapytanie (tryb Scalar).dowolne-
rowsWiersze, na które zapytanie wpłynęło lub które zwróciło (tryb NonQuery).collection-
time.queryCzas, jaki zajęło samo zapytanie.number-

Gotowy przykład jest w kolejnej sekcji: użyj rows.count, żeby sprawdzić, na ile wierszy wpłynęło lub ile zwróciło zapytanie, i scalar, żeby sprawdzić bezpośrednio pojedynczą zwróconą wartość.

Sprawdzenia licznika

Dzieli time z podmiotami udokumentowanymi powyżej - jako pole ze statusem kandydata specyficznie dla sprawdzeń Counter (czas round-trip żądania licznika; zobacz sekcję Uczciwość, co znaczy "kandydat"). Unikalne dla sprawdzeń licznika:

NazwaCo to jestTyp/wartościPrzykład
valueZmierzona wartość licznika.number-

Sprawdzenia SNMP

Dzieli time i time.dns z podmiotami udokumentowanymi powyżej (rozwiązywanie nazwy hosta plus samo żądanie SNMP). Unikalne dla sprawdzeń SNMP:

NazwaCo to jestTyp/wartościPrzykład
time.requestCzas, jaki zajęło żądanie SNMP.number-
valueWartość zwrócona przez OID.dowolne-
value.type (kandydat - wdrażane na agentów)Nazwa typu danych SNMP zwróconej wartości.string-

value.type ma status kandydata; zobacz sekcję Uczciwość. Uwaga o dostępności: przełącznik Weryfikacji odpowiedzi trybu asercji nie dotarł jeszcze do edytora monitora SNMP. Pokazuje panel "Wkrótce" nazywający te dwa podmioty zamiast działającej listy reguł. Podmioty i leżący pod nimi ewaluator są już zarejestrowane; tylko interfejs edytora SNMP wciąż czeka.

Sprawdzenia portu

Największa wspólna lista spośród wszystkich rodzajów innych niż HTTP. Sprawdzenie portu TCP niesie zasadniczo te same podmioty połączenia, DNS, TLS i certyfikatu co sprawdzenie HTTP, bo sprawdzenie portu też może negocjować TLS: bind, cert i jego sześć podpól, conn i jego cztery podpola, dns i jego dwa podpola, time/time.connect/time.dns/time.tls, oraz tls/tls.cipher/tls.protocol - wszystkie udokumentowane w sekcjach powyżej, z tymi samymi znaczeniami. Unikalne dla sprawdzeń portu:

NazwaCo to jestTyp/wartościPrzykład
bannerDane odczytane z gniazda po połączeniu.string-
banner.hash (kandydat - wdrażane na agentów)Skrót bannera - porównaj z previous.banner.hash, aby wykryć zmiany usługi.string-
banner.regexDopasuj tekst wyrażeniem regularnym i weź to, co przechwyciło.stringbody.regex("order-(?<id>\\d+)") exists
banner.size (kandydat - wdrażane na agentów)Rozmiar bannera, w bajtach.number-

banner.hash i banner.size mają status kandydata - zobacz sekcję Uczciwość. banner.regex działa już dziś i funkcjonuje dokładnie jak body.regex(...) w sprawdzeniu HTTP: nazwane przechwycenia zasilają tę samą przestrzeń nazw bind(...).

Sprawdzenia ping

Dzieli podmioty połączenia i DNS z sekcjami powyżej: conn, conn.failed, conn.failedIps, conn.ip, conn.ip.family, dns, dns.ips, dns.server, time (tutaj średni czas round-trip udanych odpowiedzi) oraz time.dns. Unikalne dla sprawdzeń ping:

NazwaCo to jestTyp/wartościPrzykład
lossProcent żądań echo, które nie doczekały się odpowiedzi.numberloss eq 0
replyUdane odpowiedzi echo.collection-
sentCount (kandydat - wdrażane na agentów)Ile żądań echo zostało wysłanych.number-
time.maxCzas round-trip najwolniejszej odpowiedzi.number-
time.minCzas round-trip najszybszej odpowiedzi.number-
ttlTTL pierwszej udanej odpowiedzi - porównaj z previous.ttl, żeby wykryć zmiany trasy.number-

sentCount ma status kandydata - zobacz sekcję Uczciwość. ttl warto znać nawet poza ścisłą regułą przejścia/niepowodzenia: sparowanie go z previous.ttl (zobacz Opakowania powyżej) sygnalizuje zmianę trasy między sprawdzeniami, bo TTL pakietu przy przybyciu odzwierciedla, ile przeskoków przebył.

Reguły, które ludzie naprawdę chcą pisać

Strona działa i faktycznie mówi to, co trzeba

Sam kod statusu nie potrafi powiedzieć, czy strona wyrenderowała się poprawnie - odpowiedź 200 z pustą powłoką to klasyczna cicha awaria, którą pomija sprawdzenie oparte tylko na statusie.

status isOk
body contains "Add to cart"

API odpowiada JSON-em i oczekiwanym polem

Sprawdź, że endpoint wciąż mówi JSON, a potem sięgnij w głąb. Pierwsza linia wyłapuje stronę błędu HTML serwowaną tam, gdzie powinien być JSON, częsty kształt awarii za proxy; druga sprawdza własny zgłaszany stan zdrowia API, nie tylko jego status transportu.

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

Odpowiedź zwolniła bardziej, niż powinna

Rozbij to na części, gdy musisz wiedzieć, co naprawić, a nie tylko, że coś jest wolne - time.connect, time.tls, time.dns i time.head rozdzielają czas sieci, handshake, resolvera i aplikacji.

time lt 2s

Przekierowanie wysłało odwiedzających poza Twoją własną domenę

Porównuje, gdzie wylądowało sprawdzenie, z URL, który skonfigurowałeś - zawodzi w chwili, gdy łańcuch przekierowań, przejęty, źle skonfigurowany albo po prostu zmieniony przez wdrożenie, wyląduje tam, gdzie nie zamierzałeś.

url.host eq url.original.host

Strona zmieniła się od ostatniego sprawdzenia

Przydatne na treści, które powinny być stabilne między sprawdzeniami - cennik, regulamin, opublikowana polityka - i podwaja się jako podstawowy sygnał defacementu.

previous.body.hash eq body.hash

Liczba w zakresie, zapisana krótszym sposobem

Wyłapuje jednocześnie okrojoną stronę i rozpędzoną, w jednej regule, bez wypisywania jawnego zakresu.

body.size between 50 and 500kb

Certyfikat, który zaraz wygaśnie

Najczęstsze ze wszystkich sprawdzeń TLS, i takie, którego zwykły monitor działa/nie działa w ogóle nie potrafi wyrazić - certyfikat, który dziś wciąż się waliduje, ale wygasa za tydzień, nie daje żadnego innego ostrzeżenia. Sparuj to z cert.issuer, jeśli chcesz też wyłapać certyfikat po cichu wystawiony przez niewłaściwy urząd.

cert.days.left gt 14

Zapytanie do bazy danych zwracające złą liczbę wierszy

W sprawdzeniu Database rows to kolekcja, na którą zapytanie wpłynęło lub którą zwróciło - liczenie jej wyłapuje zapytanie, które powinno zwracać dokładnie jeden rekord konta, cicho zaczynające zwracać zero (usunięty, albo zepsuty join) albo więcej niż jeden (duplikat, który nie powinien istnieć).

rows.count eq 1

Wartość SNMP dryfująca poza zakres

Urządzenie SNMP, które w ogóle odpowiada, to nie to samo co zdrowe - monitorowany OID (wykorzystanie dysku, głębokość kolejki, temperatura) może wspiąć się dobrze poza bezpieczny próg, podczas gdy samo urządzenie pozostaje w pełni osiągalne. Porównanie odpytanej value z zakresem wyłapuje to, czego zwykłe sprawdzenie osiągalności nie potrafi.

value lt 90

Usługa TCP odpowiadająca złym bannerem

Port, który przyjmuje połączenia, to nie to samo co właściwa usługa na nim nasłuchująca - zawieszony proces, źle skonfigurowane proxy albo obniżona/podmieniona usługa wciąż mogą dokończyć handshake TCP. Odczytanie tekstu powitalnego wysyłanego przez usługę zaraz po połączeniu (banner SMTP, FTP lub podobny) wyłapuje to, czego samo sprawdzenie otwartego portu nie potrafi.

banner contains "220"

Porównywanie z poprzednim sprawdzeniem

Garstka podmiotów patrzy wstecz zamiast tylko na bieżącą odpowiedź: umieść previous. przed podmiotem, żeby odczytać, jaki był przy ostatnim sprawdzeniu, albo opakuj go w delta(...), żeby uzyskać różnicę między wtedy a teraz, albo w delta2(...), żeby uzyskać zmianę tej zmiany - przydatne do wyłapania wartości przyspieszającej, a nie tylko dryfującej (czas odpowiedzi rosnący coraz szybciej z każdym sprawdzeniem). previous.body.hash eq body.hash powyżej to dokładnie to - "czy odcisk palca treści pasuje do tego, jaki był ostatnim razem." delta(body.size, h) odczytuje zmianę jako tempo na godzinę zamiast surowej różnicy, dla wartości, które oczekujesz, że będą rosły stopniowo, a nie skakały.

Za pierwszym razem, gdy taka reguła się uruchamia, nie ma niczego do porównania, więc jest pomijana zamiast zawodzić: sprawdzenie jest oznaczane jako "rozgrzewa się", nie jako zepsute, a dodanie reguły nie wywołuje fałszywego alertu. Rozgrzewanie stosuje się tylko wtedy, gdy bieżący odczyt jest poprawny, a brakuje punktu odniesienia. Jeśli sam bieżący odczyt zawodzi (powiedzmy, treść tym razem nie jest poprawnym JSON-em), reguła zawodzi dokładnie tak, jak zawiodłaby jej zwykła wersja bez previous.. Taka reguła wymaga też, żeby wartość zmieniała się między sprawdzeniami, co czyni ją bez znaczenia przy metodzie sprawdzenia, która nigdy nie przesuwa stanu, na przykład żądaniu HEAD.

Porównywanie z poprzednim sprawdzeniem wymaga planu wyższego poziomu; bez niego te podmioty pojawiają się w edytorze wyszarzone, z wyjaśnieniem.

Limity i to, czego celowo brakuje

Ile reguł możesz dodać, zależy od Twojego planu, pokazywane jako żywy licznik obok "Add rule." Silnik egzekwuje też bezwzględny sufit na każde sprawdzenie niezależnie od planu, zabezpieczenie przed nadużyciem, a nie limit dla zwykłego użycia: sprawdzenie z liczbą reguł zbliżoną do tego sufitu byłoby już niezwykle duże.

Nie ma sposobu, by napisać własny JavaScript dla reguły, i nigdy nie będzie. Każda reguła jest zbudowana ze stałego, nazwanego słownictwa podmiotów i predykatów, a nie z otwartej piaskownicy skryptowej, co utrzymuje regułę czytelną na pierwszy rzut oka i bezpieczną do uruchomienia na każdym agencie monitoringu na świecie.

Nie każda reguła działa wszędzie w chwili, gdy zostanie napisana: niektóre nowsze warunki potrzebują niedawnej wersji agenta monitoringu wykonującego Twoje sprawdzenie, więc nowa możliwość potrzebuje czasu, żeby dotrzeć do każdego sprawdzenia na Twoim koncie, w miarę jak agenci aktualizują się w tle. Reguły zbudowane na stabilnym rdzeniu języka nie są tym dotknięte.

Garstka wpisów w tym słowniku nie jest jeszcze w pełni aktywna, każdy oznaczony w tabeli powyżej:

  • Zarezerwowane (zadeklarowane, jeszcze niewypełniane przez żadnego agenta): ttfb, httpVersion, cert.subject.
  • Kandydat (już się wdraża, jeszcze nie na każdym agencie): conn.ip.family i conn.failedIps w sprawdzeniach HTTP, Port i Ping, value.type w sprawdzeniach SNMP, banner.hash i banner.size w sprawdzeniach Port, sentCount w sprawdzeniach Ping, oraz własne time sprawdzenia Counter.
  • Jeszcze niedostępne: steps, zarezerwowane dla przyszłego typu sprawdzenia wieloetapowego.
  • Wymaga planu z asercjami stanowymi: cała rodzina opakowań previous / delta / delta2, w każdym rodzaju sprawdzenia.

Wszystko inne w tym słowniku działa już dziś na każdym planie z trybem asercji.

Gdzie tryb asercji działa już dziś

Przełącznik Weryfikacji odpowiedzi dla trybu asercji pojawia się w monitorach HTTP (strona) i API, które dzielą ten sam edytor reguł i składnię. Ten sam język i ewaluator już działają pod spodem sprawdzeń Database, Counter, Port, Ping i SNMP na poziomie protokołu: powyższy rejestr obsługuje wszystkie sześć rodzajów sprawdzeń, a reguła zapisana dla jednego czyta się tak samo, jeśli tryb dotrze później do edytora innego typu.

SNMP pokazuje najwyraźniejszy podgląd: jego edytor ma już panel reguł asercji nazywający value i value.type, oznaczony "Wkrótce", jeszcze bez działającej listy reguł za nim. Sprawdzenia Database, Counter i Ping w ogóle nie pokazują panelu trybu asercji, mimo że ich podmioty są równie aktywne w silniku pod spodem.

Konfigurowanie prawdziwego sprawdzenia

Jeśli walidujesz REST API, a nie zwykłą stronę internetową, zacznij od walidacji odpowiedzi API, która obejmuje razem uptime, czas odpowiedzi i treść Twojego własnego API. Dla strony lub serwisu, który musi działać i odpowiadać poprawnie wszędzie tam, gdzie są Twoi użytkownicy, globalne monitorowanie uptime z ponad 300 lokalizacji to szerszy obraz, w który wpina się tryb asercji. Żeby ustawiać reguły przez kod zamiast przez panel, własne API v2 HostTracker tworzy i aktualizuje reguły asercji monitora tak samo jak edytor. Dla powyższej reguły wygaśnięcia certyfikatu i wszystkiego innego związanego z TLS, monitorowanie domeny i certyfikatu TLS obejmuje rodzaj sprawdzenia, na którym żyje cert.days.left i inne podmioty TLS. Żeby zobaczyć, jak jedna reguła ocenia prawdziwy URL już teraz, bez konta, użyj darmowego narzędzia do sprawdzania HTTP. Dla kodów statusu, z którymi porównuje podmiot status, zacznij od 200 OK, a poradniki monitoringu obejmują konfigurowanie każdego rodzaju sprawdzenia, pod którym działa ten język.

Najczęściej zadawane pytania

Co się stanie z moimi starymi ustawieniami kodu statusu i słów kluczowych, jeśli włączę tryb asercji?

Są zastępowane listą reguł, dopóki tryb jest włączony. Ponowne wyłączenie go przed zapisaniem przywraca klasyczne pola dokładnie takimi, jakie były: nic nie jest usuwane, oba tryby po prostu nie mogą być aktywne jednocześnie.

Czy mogę połączyć wiele warunków w jednym monitorze?

Tak: każda reguła na liście musi przejść. Nie ma jeszcze "OR" między osobnymi regułami, więc żeby zaakceptować jedną z kilku wartości, użyj pojedynczej reguły z in [...] albo containsAny [...].

Czy tryb asercji kiedykolwiek pozwoli mi napisać własny skrypt?

Nie. Każda reguła jest złożona ze stałego zestawu podmiotów i predykatów języka. Nie ma własnego JavaScriptu, celowo.

Co się dzieje, gdy pierwszy raz dodaję regułę porównującą z poprzednim sprawdzeniem?

Nie ma jeszcze niczego do porównania, więc jest oznaczana jako rozgrzewająca się i pomijana zamiast zawodzić. Dodanie reguły "czy to się zmieniło" nigdy samo z siebie nie wywołuje fałszywego alertu.

Czy potrzebuję konkretnego planu, żeby używać trybu asercji?

Sam tryb i codzienne reguły (status, treść, nagłówki, czas, przekierowania) są szeroko dostępne; ile reguł możesz dodać naraz, zależy od Twojego planu i jest pokazywane na żywo w edytorze. Reguły porównujące z poprzednim sprawdzeniem (previous, delta, delta2) wymagają planu wyższego poziomu i są wyszarzone z wyjaśnieniem.

Czy tryb asercji działa w monitorach API tak samo jak w monitorach strony internetowej?

Tak. Monitory HTTP i API dzielą ten sam edytor reguł, podmioty i predykaty, a reguła napisana dla jednego czyta się identycznie w drugim.

Co właściwie robi where(...) i kiedy go potrzebuję?

Filtruje kolekcję do elementów pasujących do warunku, zanim odczytasz pole wyniku. Użyj go, gdy zwykła projekcja jak requests.status nie jest wystarczająco precyzyjna, a potrzebujesz jednego konkretnego przeskoku, linku czy elementu zamiast całej kolekcji (zobacz sekcję powyżej).

Czy mogę już dziś napisać regułę wobec zapytania do bazy danych, wartości SNMP, bannera portu czy wyniku ping?

Język i ewaluator obsługują je wszystkie, a powyższe tabele podmiotów obejmują każde z nich. Edytor reguł nie: tylko monitory HTTP i API pokazują dziś przełącznik Weryfikacji odpowiedzi. SNMP pokazuje podgląd "Wkrótce" swoich dwóch podmiotów, a Database, Counter i Ping w ogóle nie pokazują panelu trybu asercji.

Dlaczego niektóre podmioty w tym słowniku mówią "zarezerwowane" albo "kandydat" zamiast po prostu być wymienione normalnie?

"Zarezerwowane" oznacza, że pole jest zadeklarowane w rejestrze, ale żaden agent jeszcze go nie wypełnia; "kandydat" oznacza, że wdraża się na agentów, ale jeszcze nie dotarło do wszystkich. Oba są oznaczone wszędzie tam, gdzie się pojawiają w tym słowniku, oraz na liście podsumowującej w sekcji Limity powyżej.

Sprawdź teraz

Uruchom darmowe sprawdzenie na swojej stronie - bez zakładania konta.

Web api validation

Monitoruj to na stałe

Otrzymasz powiadomienie w chwili awarii: HostTracker sprawdza z ponad 300 lokalizacji i powiadamia e-mailem, SMS-em, przez Slack, Telegram i nie tylko.

Funkcje HostTracker

Więcej w tej sekcji: Przewodniki po monitoringu: każdy typ kontroli krok po kroku