Перейти к основному содержимому

Руководства / Руководства по мониторингу: каждый тип проверки шаг за шагом

Режим ассертов: полный справочник по проверке ответа

Режим ассертов заменяет фиксированные поля прохождения/провала монитора списком правил, которые вы пишете сами, и каждое правило называет ровно то, что должно быть истинно в ответе. Большинство мониторов аптайма судят о проверке по горстке фиксированных полей: код состояния, который считается "недоступностью", список статусов, которые нужно игнорировать, возможно, ключевое слово, которое должно где-то встретиться в теле. Этих полей не хватает, чтобы выразить API, которое на законных основаниях отвечает 404 для отсутствующего ресурса, страницу, которая возвращает 200 с пустой оболочкой из-за таймаута базы данных, или цепочку редиректов, которая вдруг начинает вести через чужой домен.

Режим ассертов HostTracker заменяет эти фиксированные поля небольшим языком правил, который вы пишете сами, правило за правилом, прямо в редакторе монитора. Каждое правило говорит ровно, что должно быть истинно в ответе: статус, часть тела, заголовок, сколько времени это заняло, куда в итоге привел редирект. Проверка проваливается только тогда, когда проваливается одно из ваших правил. Это один и тот же язык для сайта, REST API, запроса к базе данных, TCP-порта, цели Ping, счетчика SNMP или обычной проверки Counter: один набор субъектов, один набор предикатов, переиспользуемый везде, где появляется этот режим. Это руководство разбирает каждый субъект, оператор, редьюсер, сахарную конструкцию и синтаксическую форму, которые реализует движок.

Что заменяет режим ассертов

Классические поля проверки ответа никуда не деваются, пока режим ассертов выключен: ожидаемый диапазон статуса, список игнорируемых статусов, ключевое слово, которое должно (или не должно) встретиться. Режим - это переключатель, меняющий этот фиксированный набор на список правил, который вы строите сами, а выключение режима обратно перед сохранением возвращает классические поля как были. Ни один монитор не привязан к одному режиму навсегда.

Один язык вместо кучи разрозненных штучек под каждый тип складывается воедино. Проверка "должен быть JSON и содержать поле", проверка "должна по-прежнему говорить Add to cart" и проверка "не должно стать медленнее" - это три правила на одном и том же синтаксисе, в одном списке, каждое проходит или проваливается само по себе.

Как включить

Режим ассертов находится внутри раздела Проверка ответа редактора монитора, для мониторов HTTP (сайт) и API. Переключите тумблер, и классические поля сменятся пронумерованным списком правил с кнопкой "Add rule" и живым счетчиком, показывающим, сколько правил вы использовали относительно лимита вашего тарифа.

Режим ассертов включен, построено и проверено первое правило

Каждое правило проверяется по мере построения: незавершенное правило несет отдельное состояние "не завершено", а правило, которое редактор способен вычислить, помечается как готовое. У каждого правила также есть небольшая кнопка </>, открывающая его форму в виде обычного текста, так что вы можете прочитать или скопировать точное выражение, а не только смотреть на него по полям.

Мысленная модель: субъект, предикат, значение

У каждого правила одна и та же форма: субъект (код состояния, тело, заголовок, время отклика), предикат (равно, содержит, существует, меньше чем) и, для большинства предикатов, значение для сравнения. status eq 200 - это субъект, предикат и значение; body.json exists - субъект и предикат без значения, потому что "exists" больше ничего не требует.

Построение правила в редакторе начинается с выбора того, что проверять, затем условия, затем значения:

Построение второго правила: селектор поля перечисляет каждый субъект с его типом и примером

Правила в списке объединяются через AND: проверка проваливается, если провалилось хотя бы одно правило, и проходит, только если прошли все. Оператора OR пока нет, поэтому чтобы принять один из нескольких статусов или строк, выразите это внутри одного правила (status in [200, 301, 302], body containsAny ["In stock", "Pre-order"]). Провалившееся правило называет себя в оповещении, поэтому давайте каждому короткую метку там, где можете, - и оповещение скажет, какое именно ожидание не оправдалось.

Что можно проверять

Селектор группирует субъекты по документу самого ответа (тело, заголовки) и по его транспорту (статус, время, редиректы, TLS). Несколько самых важных субъектов, с полным списком в справочнике ниже:

СубъектЧто этоПример
statusКод состояния HTTP итогового ответа, после прохождения редиректовstatus isOk
bodyТело ответа как обычный текстbody contains "Add to cart"
body.json / body.xml / body.html / body.yamlТело, но только когда оно действительно разбирается в этот формат - иначе субъект просто отсутствуетbody.json exists
body.json.path("$.a")Запрос JSONPath к телу JSON (тот же язык запросов работает и над YAML, поскольку YAML разбирается в ту же модель объекта)body.json.path("$.status") eq "ok"
body.size / body.hashРазмер ответа в байтах и отпечаток содержимого телаbody.size gt 1kb
header("Name")Один заголовок ответа, по имениheader("Content-Type") isJson
time и time.connect / time.tls / time.dns / time.headОбщее время отклика и его фазы: сеть, TLS-рукопожатие, DNS и время раздумий сервераtime lt 2s
redirects / requestsПройденные проверкой переходы и вся цепочка (включая итоговый ответ)redirects.count eq 0
url и его части (.host, .scheme, .path...)Итоговый URL, на котором проверка остановиласьurl.scheme eq "https"
cert.days.leftДней до истечения TLS-сертификатаcert.days.left gt 14

Числа принимают суффиксы единиц измерения, чтобы вам никогда не пришлось переводить их вручную: 2s означает 2000 миллисекунд, 1kb означает 1024 байта. Сравнение текста чувствительно к регистру, если не добавить в правило nocase.

Полный справочник

Дальше идет каждый субъект, оператор, редьюсер, сахарная конструкция, фильтр и синтаксическая форма, которые движок ассертов регистрирует для проверок HTTP и API, взятые прямо из собственного реестра движка (те же данные, что питают селекторы редактора правил и его документацию). Записи, которые пока не полностью доступны, несут пометку в скобках: зарезервированные поля, которые движок еще не начал заполнять, кандидаты, еще выкатывающиеся на агенты, и семейство с состоянием, требующее конкретного тарифа. Все, что без такой пометки, работает уже сегодня на любом тарифе с режимом ассертов.

Справочник следует собственной группировке движка: сначала поля ответа, затем способы заглянуть внутрь тела, затем время, сеть и TLS, затем операторы, редьюсеры и сокращения, работающие со всеми ними, а затем виды проверок помимо HTTP, говорящие на том же самом языке.

Ответ

Субъекты, описывающие сам ответ: его статус, его сырое тело, его заголовки, URL, с которого он на самом деле ответил, и цепочку запросов, которая до него довела.

ИмяЧто этоТип/значенияПример
bodyТело ответа как декодированный текст.stringbody contains "Welcome"
headerОдин заголовок итогового ответа, по имени.stringheader("Content-Type") isJson
redirectsПройденные переходы редиректа - цепочка запросов без ее последнего элемента.collectionredirects.count eq 0
statusКод состояния HTTP итогового ответа, после прохождения редиректов.numberstatus isOk
body.sizeРазмер скачанного тела, в байтах.numberbody.size lt 500000
urlURL, который на самом деле ответил, после всех редиректов. url: сравнивайте его как текст либо читайте его части (url.host, .port, .path, .query, .scheme).urlurl.host eq "www.example.com"
requestsКаждый запрос, сделанный этой проверкой, по порядку - переходы редиректа, а затем итоговый запрос.collectionrequests.count le 2
url.hostЧасть URL с хостом.stringurl.host eq "example.com"
url.pathЧасть URL с путем.stringurl.path startsWith "/api"
url.portЧасть URL с портом.numberurl.port eq 443
url.queryСтрока запроса URL.stringurl.query contains "token"
url.schemeСхема URL (http или https).stringurl.scheme eq "https"
body.hashДайджест тела ответа - сравните с previous.body.hash, чтобы обнаружить изменение содержимого.stringbody.hash eq previous.body.hash
httpVersion (зарезервировано - пока не заполняется)Согласованная версия HTTP.stringhttpVersion eq "HTTP/2"
setCookieЗначения Set-Cookie итогового ответа, по одному элементу на cookie - сопоставляйте одно через contains или matches, считайте через .count.collectionsetCookie exists
steps (пока недоступно)Шаги многошаговой проверки. Пока недоступно.collectionsteps.count le 1
url.originalURL, с которым была настроена проверка, до какого-либо редиректа. url вроде самого url: те же части (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.original.hostЧасть URL с хостом.stringurl.original.host eq "example.com"
url.original.pathЧасть URL с путем.stringurl.original.path startsWith "/start"
url.original.portЧасть URL с портом.numberurl.original.port eq 80
url.original.queryСтрока запроса URL.stringurl.original.query contains "utm_"
url.original.schemeСхема URL (http или https).stringurl.original.scheme eq "http"

Два псевдонима: redirectCount - сокращение для redirects.count - redirectCount eq 0 читается чуть естественнее эквивалентной длинной формы, когда вы имеете в виду "проверка ответила напрямую, без редиректов". А setCookie на верхнем уровне - это список cookie итогового ответа; то же имя повторяется на уровне каждого перехода внутри requests/redirects (см. субъекты перехода ниже), храня cookie именно этого запроса.

Извлечение значений из тела

Эти субъекты разрешаются только тогда, когда тело - это именно тот формат, который они называют: пространство имен JSON на HTML-странице просто отсутствует, а не является типизированной ошибкой. Именно поэтому exists - стандартный способ проверить формат, а body.json exists спрашивает, разобралось ли тело как JSON. Каждое из четырех пространств имен форматов несет соответствующую функцию запроса .path(...) (JSONPath для json/yaml, XPath для xml, CSS-селекторы для html) и соответствующий .regex(...), а также не зависящий от формата body.regex(...), читающий сырой текст независимо от формата. body.html.a, body.html.script и body.html.link - это готовые коллекции всех ссылок, скриптов и элементов <link> на странице; см. области элементов ниже про доступные для каждого поля.

ИмяЧто этоТип/значенияПример
body.jsonТело ответа, но только когда это действительно JSON.stringbody.json exists
body.json.pathЗапрос к телу JSON выражением JSONPath.jsonbody.json.path("$.status") eq "ok"
body.htmlТело ответа, но только когда это действительно HTML.stringbody.html exists
body.html.pathВыбор элементов страницы CSS-селектором.collectionbody.html.path("h1").first contains "Welcome"
body.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists
body.xmlТело ответа, но только когда это действительно XML.stringbody.xml exists
body.xml.pathЗапрос к телу XML выражением XPath.stringbody.xml.path("//item/@id") exists
body.html.aКаждая ссылка на странице.collectionbody.html.a.count gt 0
body.html.linkКаждый элемент <link>, объявленный на странице. Голое упоминание означает цели ссылок.collectionbody.html.link.count gt 0
body.html.scriptКаждый скрипт, загружаемый страницей. Голое упоминание означает источники скриптов.collectionbody.html.script.count gt 0
body.yamlТело ответа, но только когда это действительно YAML.stringbody.yaml exists
body.yaml.pathЗапрос к телу YAML выражением JSONPath.jsonbody.yaml.path("$.services.web.image") contains ":1."
body.html.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists
body.json.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists
body.xml.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists
body.yaml.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists

Деталь про семейство регулярных выражений, о которой стоит упомянуть отдельно: именованные группы захвата ((?<id>...)) внутри правила .regex(...) записываются в пространство имен привязок, действующее в рамках проверки, а более позднее правило может прочитать их обратно через bind("id") или по позиции через bind[0] - см. захваченные значения ниже.

Захваченные значения

Один субъект живет в собственной группе реестра, потому что он не читает ответ напрямую - он читает то, что захватило более раннее правило.

ИмяЧто этоТип/значенияПример
bindЗначение, захваченное более ранним правилом regex, по имени захвата или по позиции.stringbind("id") gt 1000

Сочетайте с правилом regex выше по списку: правило вроде body.regex("order-(?<id>\d+)") exists захватывает id заказа в имя id, а более позднее правило может проверить его через bind("id") gt 1000 либо, для позиционного (безымянного) захвата, через bind[0].

Время

Один общий показатель плюс разбивка по фазам, так что оповещение "стало медленнее" может заодно сказать, какая часть стала медленнее.

ИмяЧто этоТип/значенияПример
timeОбщее время отклика: соединение + TLS + ожидание + скачивание. Разрешение DNS не входит.numbertime lt 2000
ttfb (зарезервировано - пока не заполняется)Время до первого байта.numberttfb lt 200
time.connectВремя установления TCP-соединения.numbertime.connect lt 500
time.dataВремя скачивания тела ответа.numbertime.data lt 1000
time.dnsВремя разрешения доменного имени. Не входит в голый субъект time.numbertime.dns lt 200
time.headВремя ожидания заголовков ответа.numbertime.head lt 500
time.tlsВремя TLS-рукопожатия.numbertime.tls lt 300

Голый субъект time - это соединение + TLS + ожидание заголовков + скачивание тела. Разрешение DNS исключено и живет только в соседнем time.dns, потому что DNS часто кэшируется, и иначе один и тот же эндпоинт выглядел бы то быстрым, то медленным от проверки к проверке без всякой причины.

Сеть: DNS и соединение

dns и conn - чистые пространства имен в реестре: группа без собственного значения, поэтому правило никогда не может остановиться на голом имени (и редактор, и движок отклоняют цепочку, заканчивающуюся просто на dns или conn, указывая на настоящие поля ниже).

ИмяЧто этоТип/значенияПример
connСетевое соединение, установленное проверкой - адрес, отдавший ответ, и любые сбои соединения.string-
conn.failedСколько из разрешенных адресов не удалось подключить.numberconn.failed eq 0
conn.failedIps (кандидат - выкатывается на агенты)Разрешенные адреса, к которым не удалось подключиться.collectionconn.failedIps.count eq 0
conn.ipIP-адрес, который на самом деле отдал ответ.stringconn.ip eq "203.0.113.10"
conn.ip.family (кандидат - выкатывается на агенты)Отдан ли ответ по IPv4 или IPv6.stringconn.ip.family eq "IPv4"
dnsРазрешение DNS отслеживаемого имени - в какие адреса оно разрешилось и какой сервер ответил.string-
dns.ipsВсе IP-адреса, в которые разрешилось доменное имя во время этой проверки.collectiondns.ips contains "1.2.3.4"
dns.serverDNS-сервер, ответивший на разрешение.stringdns.server eq "8.8.8.8"

TLS и сертификат

Как и dns и conn, tls и cert - чистые пространства имен: факты о сертификате/рукопожатии живут на уровень ниже.

ИмяЧто этоТип/значенияПример
cert.days.leftДней до истечения сертификата сайта.numbercert.days.left gt 14
certСертификат, предъявленный сервером - дни до истечения, издатель и поля идентификации.string-
cert.daysДней с момента выпуска сертификата.numbercert.days gt 0
cert.issuerУдостоверяющий центр, выпустивший сертификат сайта.stringcert.issuer contains "Let's Encrypt"
cert.sanДоменные имена, для которых действителен сертификат.collectioncert.san contains "www.example.com"
cert.serialСерийный номер сертификата.stringcert.serial exists
cert.subject (зарезервировано - пока не заполняется)Субъект сертификата. Пока не собирается - появится с будущей версией агента.stringcert.subject contains "example.com"
tlsTLS-рукопожатие защищенного соединения - согласованная версия протокола и шифр.string-
tls.cipherСогласованный набор шифров.stringtls.cipher contains "AES"
tls.protocolСогласованная версия TLS.stringtls.protocol eq "Tls13"

cert.subject приведен здесь для полноты, но пока не заполняется - см. раздел о честности ниже про то, что на практике означает "зарезервировано". Повседневное правило для сертификата - cert.days.left gt 14, разобранное в разделе с готовыми правилами.

Субъекты перехода: поля внутри requests и redirects

requests и redirects - это коллекции, и каждый элемент - полная запись запроса/ответа со своим сокращенным набором полей. Не каждый субъект верхнего уровня имеет смысл на уровне одного перехода (у перехода нет собственного сертификата), а одно поле существует только на уровне перехода: hstsHeader, заголовок Strict-Transport-Security этого запроса в цепочке.

ИмяЧто этоТип/значенияПример
statusКод состояния этого запроса в цепочке.numberstatus eq 200
urlURL, на который был сделан этот запрос.urlurl startsWith "https://"
headerЗаголовок ответа этого запроса. Переход хранит сокращенную запись заголовка с одним значением - списочные предикаты (containsAny, containsAll, unique) применимы только к заголовку итогового ответа.stringheader("Content-Type") contains "json"
hstsHeaderЗаголовок Strict-Transport-Security этого запроса.stringrequests[0].hstsHeader exists
setCookieЗначения заголовка Set-Cookie этого запроса.collectionsetCookie exists
url.originalURL, с которым была настроена проверка, до какого-либо редиректа. url вроде самого url: те же части (url.original.host, .port, .path, .query, .scheme).urlurl.original.scheme eq "http"
url.hostЧасть URL с хостом.stringurl.host eq "example.com"
url.portЧасть URL с портом.numberurl.port eq 443
url.pathЧасть URL с путем.stringurl.path startsWith "/api"
url.queryСтрока запроса URL.stringurl.query contains "token"
url.schemeСхема URL (http или https).stringurl.scheme eq "https"
url.original.hostЧасть URL с хостом.stringurl.original.host eq "example.com"
url.original.portЧасть URL с портом.numberurl.original.port eq 80
url.original.pathЧасть URL с путем.stringurl.original.path startsWith "/start"
url.original.queryСтрока запроса URL.stringurl.original.query contains "utm_"
url.original.schemeСхема URL (http или https).stringurl.original.scheme eq "http"

Значение header(...) для одного перехода хранит сокращенную запись с одним значением: списочные предикаты вроде containsAny или unique имеют смысл только для полной карты заголовков итогового ответа, поэтому применяются только там, а не для каждого перехода. Две коллекции означают разное. requests - это вся цепочка, включая итоговый ответ, который в итоге ответил, поэтому она никогда не пуста даже для прямого 200, а redirects - только переходы, пройденные по пути, и пуста, если редиректов не было вовсе.

Области элементов: поля внутри одного элемента коллекции

Область элемента - это набор полей, доступных для ОДНОГО элемента коллекции - после индексации в него (requests[0]) или при фильтрации через where(current. ...) (см. следующий раздел). Шесть коллекций несут собственную область элемента: четыре коллекции элементов HTML имеют одну общую форму, а requests/redirects используют форму субъектов перехода, описанную чуть выше.

Область элементаКак выглядит один элемент
body.html.pathОдин элемент, найденный CSS-запросом body.html.path("selector").
body.html.aОдин элемент <a> из body.html.a.
body.html.scriptОдин элемент <script> из body.html.script.
body.html.linkОдин элемент <link> из body.html.link.
requestsОдин запрос в полной цепочке (см. таблицу субъектов перехода выше).
redirectsОдин пройденный переход редиректа (те же поля, что и у requests, см. выше).

Общая форма для body.html.path(...), body.html.a, body.html.script и body.html.link - по одной строке на ссылку, тег скрипта или элемент <link>:

ИмяЧто этоТип/значенияПример
urlЦель ссылки ровно так, как ее записывает разметка.stringbody.html.a.url contains "/checkout"
textВидимый текст элемента.stringbody.html.a.text contains "Sign in"
absoluteЦель ссылки, разрешенная относительно URL страницы в абсолютный адрес - список url, с частями url, доступными для каждого элемента (.host, .path, .port, .query, .scheme).urlbody.html.a.absolute.scheme in ["https"]
relАтрибут rel элемента.stringbody.html.a.where(current.rel eq "nofollow").count eq 0
absolute.hostЧасть URL с хостом.stringbody.html.a.absolute.host.unique.count le 3
absolute.portЧасть URL с портом.numberbody.html.a.absolute.port in [443]
absolute.pathЧасть URL с путем.stringbody.html.a.absolute.path startsWith "/"
absolute.queryСтрока запроса URL.stringbody.html.a.absolute.query not contains "session"
absolute.schemeСхема URL (http или https).stringbody.html.a.absolute.scheme in ["https"]

Прежде чем писать правило против этих коллекций, действуют два умолчания. Голое упоминание body.html.a (или .script/.link) означает его проекцию .url, поэтому body.html.a.count gt 0 считает href-ы, а сохраненное правило перечитывается со спелленной формой .url, потому что сохраненное правило всегда говорит ровно, что оно вычисляет. И .url - это сырой атрибут href ровно так, как его написала разметка, так что относительная ссылка остается относительной; .absolute - та же ссылка, разрешенная относительно собственного URL страницы, что и нужно при проверке схемы или хоста исходящих ссылок (body.html.a.absolute.scheme in ["https"]).

Операторы

Предикатная половина каждого правила: какую проверку выполнить над субъектом. Все 15 общие для любого вида проверки, а какие из них подходят конкретному субъекту, зависит от его типа (код состояния принимает lt/gt, тело принимает contains, коллекция принимает exists/unique/in).

ИмяЧто этоПрименяется кПример
eqРавно. Против литерала json("…") / xml("…") / yaml("…") - это ТОЧНОЕ структурное совпадение: те же ключи (в любом порядке), массивы по порядку, те же значения.любой типbody.json eq json("{\"ok\": true}")
ltМеньше чем.числаtime lt 2000
leМеньше или равно.числаcert.days.left le 30
gtБольше чем.числаbody.size gt 0
geБольше или равно.числаstatus ge 500
containsСодержит текст - для списка проходит, когда значение ЯВЛЯЕТСЯ одним из элементов (точное совпадение; используйте matches для поиска внутри элементов). Против литерала json("…") / xml("…") / yaml("…") - это СТРУКТУРНОЕ включение: все, что указано в литерале, должно присутствовать и совпадать; в ответе может быть больше.текст или списокbody.json contains json("{\"status\": \"ok\"}")
startsWithНачинается с текста - для списка, когда это верно для ЛЮБОГО элемента.текстurl.path startsWith "/api"
endsWithЗаканчивается текстом - для списка, когда это верно для ЛЮБОГО элемента.текстurl.path endsWith ".json"
matchesСовпадает с регулярным выражением где-либо в тексте - для списка, когда это верно для ЛЮБОГО элемента.текстbody matches "order-\\d+"
containsAnyСодержит хотя бы одно из перечисленных значений (для списка: какой-то элемент РАВЕН одному из них).списокbody containsAny ["In stock", "Pre-order"]
containsAllСодержит каждое из перечисленных значений (для списка: каждое значение равно какому-то элементу - подтверждающие элементы могут различаться).списокbody.html.a.text containsAll ["Home", "Contact"]
inЯвляется одним из перечисленных значений или диапазонов - для списка, верно для каждого элемента.значение(я) или диапазонstatus in [200, 301, 302]
existsСубъект присутствует.любой субъектheader("ETag") exists
isNumberЗначение читается как число.текст или любой типbind("id") isNumber
uniqueВ списке нет дубликатов.списокdns.ips unique

Два оператора значат нечто более узкое, чем кажется на слух. contains для списка - это точное членство: значение должно быть равно целому элементу, а не встречаться как подстрока внутри одного из них, поэтому для поведения "подстрока" внутри элементов коллекции используйте matches. А eq против литерала json(...)/xml(...)/yaml(...) - это полное структурное совпадение (те же ключи, массивы в том же порядке, те же значения), тогда как contains против такого же литерала - структурное включение: все, что указывает литерал, должно присутствовать, но реальный ответ может нести больше.

Редьюсеры

Редьюсер сворачивает коллекцию в одно значение и может стоять только в конце цепочки. Примеры ниже используют requests.status, естественно числовую коллекцию из субъектов HTTP, для иллюстрации; те же восемь редьюсеров работают над любой числовой коллекцией в любом виде проверки (времена кругового пути проверки Ping, отфильтрованный набор строк базы данных).

ИмяЧто сворачиваетПрименяется кПример
countСколько элементов в списке.любая коллекцияrequests.count le 2
minНаименьшее число в списке.числовая коллекцияrequests.status.min ge 200
maxНаибольшее число в списке.числовая коллекцияrequests.status.max lt 500
sumСумма чисел в списке.числовая коллекцияrequests.status.sum gt 0
avgСреднее чисел в списке.числовая коллекцияrequests.status.avg lt 300
firstПервый элемент списка.любая коллекцияredirects.status.first eq 301
lastПоследний элемент списка.любая коллекцияrequests.status.last eq status
uniqueСписок без дубликатов.любая коллекцияdns.ips.unique.count le 3

unique перегружен, и написание отличает эти два значения друг от друга. В форме оператора без точки (x unique) это предикат: "в этой коллекции нет дубликатов" - и он проваливается, называя повтор. В форме редьюсера с точкой (x.unique) это преобразование, сама дедуплицированная коллекция, за которой все еще что-то нужно (x.unique.count eq 1). Висящий x.unique без чего-либо после него - синтаксическая ошибка, потому что движок не может угадать, какой из двух вариантов вы имели в виду.

Сахар

Сахарные предикаты - это сокращения, которые движок разворачивает в обычные базовые предикаты еще до того, как правило вообще отправляется агенту - добавление сахарного предиката ничего не стоит дополнительно (не нужен бандл агента, не нужен порог версии), потому что к моменту попадания на провод он уже выглядит как обычное правило. Предпочитайте сахар везде, где он есть: он читается лучше и полностью эквивалентен написанию длинной формы вручную.

ИмяЧто это значитПрименяется кПример
isOkСтатус - код успеха (200-299).status-
isRedirectСтатус - код редиректа (300-399).statusstatus isRedirect
isClientErrorСтатус - ошибка клиента (400-499).statusstatus isClientError
isServerErrorСтатус - ошибка сервера (500-599).statusstatus isServerError
isJsonСодержимое действительно JSON.документ или текст медиатипаheader("Content-Type") isJson
isXmlСодержимое действительно XML - тело разбирается как XML либо заголовок называет медиатип XML.документ или текст медиатипаbody isXml
isHtmlСодержимое действительно HTML - тело разбирается как HTML либо заголовок называет медиатип HTML.документ или текст медиатипаbody isHtml
isFormМедиатип называет форматом кодировки формы: application/x-www-form-urlencoded или multipart/form-data. В отличие от isJson/isXml/isHtml, здесь нет соответствующего пространства имен тела, так что применимо только к значению медиатипа, например к заголовку Content-Type.только текст медиатипаheader("Content-Type") isForm
isEmptyНичего нет: пустой текст, нулевой размер или пустой список.текст, размер или списокbody isEmpty
isNullЗначение равно null.любое значениеbody.json.path("$.deletedAt") isNull
absentСубъект вообще отсутствует.любой субъектheader("X-Debug") absent
betweenЧисло в пределах включительного диапазона.числа (2 операнда)body.size between 50 and 500kb

isJson/isXml/isHtml намеренно зависят от контекста, и то, на чем вы их пишете, определяет применяемое значение. Написанные на самом документе (body isJson) они значат "разбирается ли это как данный формат" - то же самое, что body.json exists. Написанные на текстовом значении, называющем медиатип, например на заголовке (header("Content-Type") isJson), они значат "называет ли это семейство MIME данного формата"; см. семейства MIME ниже про то, какие медиатипы подходят. У isForm есть только второе значение, поскольку пространства имен body.form для разбора не существует, поэтому body isForm - статическая ошибка, а не правило, которое просто никогда не может быть истинным.

Фильтр where(...)

Оставить только подходящие элементы и продолжить работу с ними. Это единственная фильтрующая конструкция в языке, и у нее ровно одна форма: where(current.<field> <condition> <value>).

Фильтрация отличается от проекции: requests.url contains "cart" спрашивает, существует ли такой переход вообще в цепочке, а requests.where(current.url contains "cart").status спрашивает, что вернул именно этот переход. Фильтрация не сворачивает список, поэтому завершайте выражение через .first, проверку in [...] или .count. Она идет только на один уровень и принимает ровно одно условие.

ЧастьЧто называетЗаметки
current.<field>Поле каждого фильтруемого элемента, записанное после current.Это та половина, в которой чаще всего ошибаются: current.url - это URL отдельного перехода, а не итогового ответа. После current. могут идти только собственные поля элемента.
условиеЛюбой обычный предикат, включая not и nocaseЛюбое условие, работающее на верхнем уровне правила, работает и здесь.
значениеС чем сравнивается поле каждого элементаОбычно простое значение. Субъект, написанный здесь, читается из ВНЕШНЕГО ответа, а не из элемента - where(current.url eq url.original) сравнивает каждый переход с URL, с которым была настроена проверка, поэтому сторона элемента должна явно говорить current..

Пример: requests.where(current.url contains "cart").status.first eq 301 - оставить только переходы, чей URL содержит "cart", затем посмотреть статус первого из подошедших.

Еще два ограничения, оба проверяются парсером с собственным сообщением: where нельзя вложить внутрь другого where, а его аргумент - ровно одно условие, без and/or внутри. Он применим только к коллекции, элементы которой несут именованные поля (requests, body.html.a), а не к простому спроецированному списку вроде dns.ips, где для current. просто нечего называть.

Справочник по синтаксису

Все остальное, что определяет грамматика: как назвать правило, как писать диапазоны и списки, что значит голый субъект, и небольшие пунктуационные формы, встречающиеся во многих правилах.

ФормаЧто делаетВидПример
whereОставить только подходящие элементы и продолжить работу с ними.фильтр коллекцииrequests.where(current.url contains "cart").status.first eq 301
notИнвертирует следующее за ним условие.флагbody not contains "error"
nocaseСравнивает текст без учета регистра.флагbody contains "welcome" nocase
currentВнутри where(…) называет один фильтруемый элемент.ссылка на элемент (внутри where)requests.where(current.status eq 301)
rangeДиапазон чисел, ОБА конца ВКЛЮЧЕНЫ.числовой диапазонstatus in [200..299]
listСписок значений для сравнения.список значенийstatus in [200, 301, 302]
docLiteralТипизированное значение документа для структурного сравнения: текст в кавычках разбирается как JSON, XML или YAML при сохранении правила.текст json/xml/yamlbody.json contains json("{\"user\": {\"active\": true}}")
implicitExistsПравило, называющее только субъект, проверяет его присутствие: запись просто body.json сохраняется как body.json exists.строка с голым субъектомbody.json
indexВыбирает ОДИН элемент списка по позиции, считая от 0.0-based целоеrequests[0].status
labelНеобязательное имя правила, записанное перед двоеточием.имя перед двоеточием"json ok": body.json exists
commentВсе после # - заметка для себя; на проверку не влияет.текст после # в конце строкиstatus isOk # the happy path

Несколько пунктов стоит объяснить обычным языком. label дает правилу имя, которое отображается в оповещении вместо отрисованного выражения; пишите его перед двоеточием, как в "json ok": body.json exists. implicitExists означает, что строка, называющая только субъект без предиката, - это сокращение для exists: запись body.json сохраняется как body.json exists, и при повторном открытии правила видна развернутая форма. range и list - это две формы, которые может принимать значение после in: диапазон ([200..299], оба конца включены) или явный список ([200, 301, 302]), и значение может быть открытым с любой стороны ([400..]). docLiteral - это обертка json(...)/xml(...)/yaml(...), используемая для структурного сравнения с телом (разобрана в разделе "Операторы" выше и в готовых правилах ниже). index выбирает один элемент из коллекции по позиции, с отсчетом от 0, так же как bind[0] читает позиционный захват. current имеет смысл только внутри фильтра where(...), разобранного в собственном разделе выше.

Обертки: previous, delta и delta2

Три формы, которые смотрят назад, а не только на текущий ответ - каждая доступна на тарифах с ассертами с состоянием, и каждая подробно объяснена в разделе "Сравнение с предыдущей проверкой" ниже.

ИмяЧто этоТип/значенияПример
delta (требует тариф с ассертами с состоянием)Насколько изменилось числовое значение с предыдущей проверки - опционально как скорость за мс/с/мин/ч.numberdelta(body.size, h) lt 1mb
delta2 (требует тариф с ассертами с состоянием)Изменение изменения - ускоряется ли значение?numberdelta2(time) gt 0
previous (требует тариф с ассертами с состоянием)Значение этого субъекта на предыдущей проверке.anystatus eq previous.status

Флаги: not и nocase

Два модификатора, которые присоединяются к правилу, а не выступают самостоятельными субъектами или предикатами.

ФлагЧто делаетВидПример
notИнвертирует следующее за ним условие.флаг (присоединяется к правилу)body not contains "error"
nocaseСравнивает текст без учета регистра.флаг (присоединяется к правилу)body contains "welcome" nocase

not сочетается со следующим за ним предикатом, а не отрицает все правило целиком - x not != y читается как x eq y, а не как двойное отрицание. Когда субъект может вовсе отсутствовать, предпочитайте сахар absent вместо not exists: оба значат ровно одно и то же, но absent говорит об этом прямо. nocase меняет что-либо только при действительно текстовом сравнении; редактор (и этот справочник) все равно позволяют написать его где угодно, но на числовой проверке вроде status eq 200 nocase он молча ничего не значит.

Семейства MIME

Таблицы соответствий за isJson, isXml, isHtml и isForm, когда они применяются к значению медиатипа, например к заголовку. Каждое семейство соответствует очевидному медиатипу верхнего уровня плюс, для JSON и XML, любому типу, оканчивающемуся на соответствующий суффикс структурированного синтаксиса - именно это заставляет header("Content-Type") isJson корректно срабатывать на application/problem+json или application/vnd.api+json, а не только на чистый application/json.

СемействоСоответствуетПарный сахарПример
jsonapplication/json, text/json или любой медиатип, оканчивающийся на +json (application/problem+json, application/vnd.api+json, application/ld+json, ...).сахар: isJsonheader("Content-Type") isJson
xmlapplication/xml, text/xml или любой медиатип, оканчивающийся на +xml (image/svg+xml, application/atom+xml, ...).сахар: isXmlheader("Content-Type") isXml
htmltext/html или application/xhtml+xml.сахар: isHtmlheader("Content-Type") isHtml
formapplication/x-www-form-urlencoded или multipart/form-data.сахар: isFormheader("Content-Type") isForm

Сопоставление игнорирует все, начиная с первого ; (так что application/json; charset=utf-8 все равно совпадает), и нечувствительно к регистру.

Субъекты для проверок базы данных, счетчика, SNMP, порта и ping

Каждый оператор, редьюсер, сахарная конструкция и синтаксическая форма выше идентичны для этих пяти видов проверок: движок регистрирует одни и те же 15 операторов, 8 редьюсеров, 12 сахарных предикатов и 11 синтаксических форм для всех шести видов без исключения. Различается по видам список субъектов. Каждый вид предоставляет небольшой набор субъектов, уникальных для того, что он измеряет, плюс подмножество уже описанных выше субъектов сети/времени/TLS, чей смысл подстраивается под вид (у проверки Database субъект time - это соединение-плюс-запрос, а не соединение-плюс-TLS-плюс-скачивание, поскольку HTTP-ответа для скачивания там нет).

Проверки базы данных

Делит time, time.connect и time.dns с субъектами, описанными выше (переосмысленными для соединения с базой данных: соединение-плюс-запрос, разрешение DNS хоста базы данных). Уникальны для проверок базы данных:

ИмяЧто этоТип/значенияПример
scalarЕдинственное значение, которое вернул запрос (режим Scalar).any-
rowsСтроки, затронутые или возвращенные запросом (режим NonQuery).collection-
time.queryВремя, которое занял сам запрос.number-

Разобранный пример - в следующем разделе: используйте rows.count, чтобы проверить, сколько строк затронул или вернул запрос, и scalar, чтобы проверить напрямую одно возвращенное значение.

Проверки Counter

Делит time с субъектами, описанными выше - как поле в статусе "кандидат" именно для проверок Counter (время кругового пути запроса счетчика; см. раздел о честности про то, что означает "кандидат"). Уникально для проверок Counter:

ИмяЧто этоТип/значенияПример
valueИзмеренное значение счетчика.number-

Проверки SNMP

Делит time и time.dns с субъектами, описанными выше (разрешение имени хоста плюс сам запрос SNMP). Уникально для проверок SNMP:

ИмяЧто этоТип/значенияПример
time.requestВремя, которое занял запрос SNMP.number-
valueЗначение, которое вернул OID.any-
value.type (кандидат - выкатывается на агенты)Имя типа данных SNMP для возвращенного значения.string-

value.type в статусе "кандидат"; см. раздел о честности. Примечание о доступности: переключатель проверки ответа в режиме ассертов пока не добрался до редактора монитора SNMP. Он показывает панель "Coming soon", называющую эти два субъекта, а не работающий список правил. Сами субъекты и вычислитель под ними уже зарегистрированы; ожидает своей очереди только интерфейс редактора SNMP.

Проверки портов

Самый большой общий список среди всех видов, кроме HTTP. Проверка TCP-порта несет практически тот же набор субъектов соединения, DNS, TLS и сертификата, что и HTTP-проверка, поскольку проверка порта тоже может согласовывать TLS: bind, cert и его шесть подполей, conn и его четыре подполя, dns и его два подполя, time/time.connect/time.dns/time.tls, а также tls/tls.cipher/tls.protocol - все описаны в разделах выше, с теми же значениями. Уникально для проверок портов:

ИмяЧто этоТип/значенияПример
bannerДанные, прочитанные из сокета после подключения.string-
banner.hash (кандидат - выкатывается на агенты)Дайджест баннера - сравните с previous.banner.hash, чтобы обнаружить изменение сервиса.string-
banner.regexСопоставление текста регулярным выражением и взятие того, что оно захватило.stringbody.regex("order-(?<id>\\d+)") exists
banner.size (кандидат - выкатывается на агенты)Размер баннера, в байтах.number-

banner.hash и banner.size в статусе "кандидат" - см. раздел о честности. banner.regex уже работает сегодня и действует точно так же, как body.regex(...) в HTTP-проверке: именованные захваты питают то же пространство имен bind(...).

Проверки Ping

Делит субъекты соединения и DNS с разделами выше: conn, conn.failed, conn.failedIps, conn.ip, conn.ip.family, dns, dns.ips, dns.server, time (здесь - среднее время кругового пути успешных ответов) и time.dns. Уникально для проверок Ping:

ИмяЧто этоТип/значенияПример
lossПроцент эхо-запросов, оставшихся без ответа.numberloss eq 0
replyУспешные эхо-ответы.collection-
sentCount (кандидат - выкатывается на агенты)Сколько эхо-запросов было отправлено.number-
time.maxВремя кругового пути самого медленного ответа.number-
time.minВремя кругового пути самого быстрого ответа.number-
ttlTTL первого успешного ответа - сравните с previous.ttl, чтобы заметить смену маршрута.number-

sentCount в статусе "кандидат" - см. раздел о честности. О ttl стоит знать даже вне строгого правила прохождения/провала: сочетание с previous.ttl (см. обертки выше) сигнализирует о смене маршрута между проверками, поскольку время жизни пакета к моменту прибытия отражает, сколько переходов он прошел.

Правила, которые люди действительно хотят писать

Страница работает и действительно говорит то, что нужно

Один код состояния не может сказать вам, что страница отрисовалась правильно - ответ 200 с пустой оболочкой - классический тихий сбой, который проверка только по статусу пропускает.

status isOk
body contains "Add to cart"

API отвечает JSON и нужным полем

Проверьте, что эндпоинт по-прежнему говорит на JSON, затем загляните внутрь. Первая строка ловит HTML-страницу ошибки, отданную там, где должен быть JSON, - частая форма сбоя за прокси; вторая проверяет собственное сообщаемое здоровье API, а не только статус транспорта.

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

Ответ стал медленнее, чем должен

Разбейте на части, когда нужно знать, что чинить, а не просто то, что что-то медленно - time.connect, time.tls, time.dns и time.head разделяют время сети, рукопожатия, резолвера и приложения.

time lt 2s

Редирект увел посетителей с вашего собственного домена

Сравнивает, куда в итоге пришла проверка, с URL, который вы настроили - проваливается в тот момент, когда цепочка редиректов, взломанная, неверно настроенная или просто измененная деплоем, приводит не туда, куда вы рассчитывали.

url.host eq url.original.host

Страница изменилась с последней проверки

Полезно для содержимого, которое должно быть стабильным между проверками - цены, условия, опубликованная политика, - а заодно служит базовым сигналом дефейса.

previous.body.hash eq body.hash

Число в диапазоне, записанное коротким способом

Ловит и урезанную страницу, и разросшуюся одним и тем же правилом, без явного написания диапазона.

body.size between 50 and 500kb

Сертификат, который вот-вот истечет

Самая частая проверка TLS, и она же - та, что простой монитор вверх/вниз вообще не способен выразить: сертификат, который сегодня еще проходит проверку, но истекает на следующей неделе, не дает никакого другого предупреждающего сигнала. Сочетайте с cert.issuer, если хотите заодно поймать сертификат, тихо выпущенный не тем удостоверяющим центром.

cert.days.left gt 14

Запрос к базе данных возвращает не то число строк

В проверке Database rows - это коллекция, затронутая или возвращенная запросом - подсчет ловит запрос, который должен возвращать ровно одну запись об аккаунте, но начал незаметно возвращать ноль (удалена, либо сломался join) или больше одной (дубликат, которого не должно существовать).

rows.count eq 1

Значение SNMP уходит за пределы диапазона

Устройство SNMP, которое вообще отвечает, - это не то же самое, что здоровое устройство: отслеживаемый OID (использование диска, глубина очереди, температура) может подняться далеко за безопасный порог, пока само устройство остается прекрасно доступным. Сравнение опрошенного value с диапазоном ловит то, что не способна поймать простая проверка доступности.

value lt 90

Служба TCP отвечает не тем баннером

Порт, принимающий соединения, - это не то же самое, что нужная служба, слушающая на нем: зависший процесс, неверно настроенный прокси или подмененная/устаревшая служба - все они по-прежнему способны завершить TCP-рукопожатие. Чтение приветственного текста, который служба отправляет сразу после подключения (баннер SMTP, FTP или похожий), ловит то, что не способна поймать голая проверка "порт открыт".

banner contains "220"

Сравнение с предыдущей проверкой

Горстка субъектов смотрит назад, а не только на текущий ответ: поставьте previous. перед субъектом, чтобы прочитать, каким он был на прошлой проверке, либо оберните его в delta(...), чтобы получить разницу между тогда и сейчас, либо в delta2(...), чтобы получить изменение этого изменения - полезно, чтобы заметить значение, которое ускоряется, а не просто дрейфует (время отклика, растущее все быстрее с каждой проверкой). previous.body.hash eq body.hash выше - это ровно оно: "совпадает ли отпечаток тела с тем, каким он был в прошлый раз". delta(body.size, h) читает изменение как скорость в час вместо сырой разницы - для значений, которые вы ожидаете расти постепенно, а не скачками.

В первый раз, когда такое правило выполняется, ему не с чем сравнивать, поэтому оно пропускается, а не проваливается: проверка помечается как "прогревается", а не как сломанная, и добавление такого правила не поднимает ложного оповещения. Прогрев применяется только тогда, когда текущее чтение исправно, а базового значения нет. Если само текущее чтение проваливается (скажем, тело в этот раз не валидный JSON), правило проваливается точно так же, как провалилась бы его обычная версия без previous.. Такому правилу также нужно, чтобы значение менялось между проверками, из-за чего оно бессмысленно для метода проверки, который никогда не продвигает состояние, например для запроса HEAD.

Сравнение с предыдущей проверкой требует тарифа более высокого уровня; без него эти субъекты отображаются в редакторе серыми, с объяснением.

Лимиты и то, чего здесь намеренно нет

Сколько правил можно добавить, зависит от вашего тарифа, показано живым счетчиком рядом с "Add rule". Движок также применяет абсолютный потолок для любой проверки независимо от тарифа - это защита от злоупотреблений, а не ограничение обычного использования: проверка с числом правил, приближающимся к этому потолку, уже была бы необычно большой.

Нет способа написать для правила собственный JavaScript, и не будет никогда. Каждое правило строится из фиксированного, именованного словаря субъектов и предикатов, а не из открытой песочницы для скриптов, что делает правило читаемым с первого взгляда и безопасным для выполнения на каждом агенте мониторинга по всему миру.

Не каждое правило работает везде в момент написания: некоторым более новым условиям нужна свежая версия агента мониторинга, выполняющего вашу проверку, поэтому новой возможности требуется время, чтобы дойти до каждой проверки на вашем аккаунте по мере фонового обновления агентов. Правила, построенные на стабильном ядре языка, этого не касаются.

Горстка записей в этом справочнике пока не полностью доступна, и каждая помечена в своей таблице выше:

  • Зарезервировано (объявлено, но пока не заполняется ни одним агентом): ttfb, httpVersion, cert.subject.
  • Кандидат (уже выкатывается, но пока не на каждом агенте): conn.ip.family и conn.failedIps в проверках HTTP, Port и Ping, value.type в проверках SNMP, banner.hash и banner.size в проверках Port, sentCount в проверках Ping, и собственный time проверки Counter.
  • Пока недоступно: steps, зарезервировано для будущего многошагового вида проверки.
  • Требует тариф с ассертами с состоянием: все семейство оберток previous / delta / delta2, для любого вида проверки.

Все остальное в этом справочнике работает уже сегодня на любом тарифе с режимом ассертов.

Где режим ассертов работает уже сегодня

Переключатель проверки ответа для режима ассертов появляется на мониторах HTTP (сайт) и API, которые используют один и тот же редактор правил и синтаксис. Тот же язык и тот же вычислитель уже работают на уровне протокола под проверками Database, Counter, Port, Ping и SNMP: реестр выше обслуживает все шесть видов проверок, и правило, сохраненное для одного из них, читается так же, если режим позже доберется до редактора другого типа.

SNMP показывает самый ясный предпросмотр: в его редакторе уже есть панель правил ассертов, называющая value и value.type, с пометкой "Coming soon", но пока без работающего списка правил за ней. Проверки Database, Counter и Ping вообще не показывают панель режима ассертов, хотя их субъекты в движке под капотом точно так же живы.

Настройка настоящей проверки

Если вы проверяете REST API, а не простую веб-страницу, начните с проверки ответов API, которая охватывает аптайм, время отклика и тело вашего собственного API вместе. Для страницы или сайта, которые должны оставаться доступными и отвечать правильно отовсюду, где находятся ваши пользователи, глобальный мониторинг аптайма из 300+ локаций - более широкая картина, в которую встраивается режим ассертов. Чтобы задавать правила через код, а не через панель, собственный API v2 HostTracker создает и обновляет правила ассертов монитора точно так же, как это делает редактор. Про правило истечения сертификата выше и все, что касается TLS, читайте в мониторинге домена и TLS-сертификата, который охватывает тип проверки, на котором живут cert.days.left и другие субъекты TLS. Чтобы прямо сейчас увидеть, как одно правило вычисляется для настоящего URL, без аккаунта, используйте бесплатный инструмент HTTP-проверки. Про коды состояния, с которыми сравнивает субъект status, начните с 200 OK, а руководства по мониторингу расскажут о настройке каждого вида проверки, под которым работает этот язык.

Часто задаваемые вопросы

Что происходит с моими старыми настройками кода состояния и ключевого слова, если я включу режим ассертов?

Пока режим включен, их заменяет список правил. Выключение режима обратно перед сохранением восстанавливает классические поля точно такими, какими они были: ничего не удаляется, просто оба режима не могут быть активны одновременно.

Можно ли объединить несколько условий в одном мониторе?

Да: каждое правило в списке должно пройти. Оператора "OR" между отдельными правилами пока нет, поэтому чтобы принять одно из нескольких значений, используйте одно правило с in [...] или containsAny [...].

Позволит ли режим ассертов когда-нибудь написать собственный скрипт?

Нет. Каждое правило составляется из фиксированного набора субъектов и предикатов языка. Никакого собственного JavaScript, и это осознанное решение.

Что происходит при первом добавлении правила, сравнивающего с предыдущей проверкой?

Сравнивать пока не с чем, поэтому оно помечается как прогревающееся и пропускается, а не проваливается. Добавление правила "изменилось ли это" само по себе никогда не поднимает ложное оповещение.

Нужен ли для режима ассертов конкретный тариф?

Сам режим и повседневные правила (статус, тело, заголовки, время, редиректы) широко доступны; сколько правил можно добавить одновременно, зависит от вашего тарифа и отображается живьем прямо в редакторе. Правилам, сравнивающим с предыдущей проверкой (previous, delta, delta2), нужен тариф более высокого уровня, и они отображаются серыми с объяснением.

Работает ли режим ассертов на мониторах API так же, как на мониторах сайта?

Да. Мониторы HTTP и API используют один и тот же редактор правил, субъекты и предикаты, и правило, написанное для одного из них, читается идентично на другом.

Что на самом деле делает where(...), и когда он нужен?

Он отфильтровывает коллекцию до элементов, подходящих под условие, прежде чем вы читаете поле результата. Используйте его, когда простой проекции вроде requests.status недостаточно конкретно и вам нужен один конкретный переход, ссылка или элемент, а не вся коллекция целиком (см. раздел выше).

Можно ли уже сегодня написать правило для запроса к базе данных, значения SNMP, баннера порта или результата ping?

Язык и вычислитель поддерживают все это, и таблицы субъектов выше охватывают каждый из них. Редактор правил - нет: переключатель проверки ответа сегодня показывают только мониторы HTTP и API. SNMP показывает предпросмотр "Coming soon" для своих двух субъектов, а проверки Database, Counter и Ping вообще не показывают панель режима ассертов.

Почему некоторые субъекты в этом справочнике помечены как "зарезервировано" или "кандидат", а не просто перечислены как обычно?

"Зарезервировано" значит, что поле объявлено в реестре, но пока ни один агент его не заполняет; "кандидат" значит, что оно уже выкатывается на агенты, но пока не дошло до всех. Оба случая отмечены везде, где встречаются в этом справочнике, и в сводном списке в разделе "Лимиты" выше.

Проверить сейчас

Запустите бесплатную проверку своего сайта - аккаунт не нужен.

Web api validation

Следить за этим постоянно

Получайте оповещение в момент сбоя: HostTracker проверяет более чем из 300 локаций и уведомляет по email, SMS, в Slack, Telegram и не только.

Возможности HostTracker

Ещё в этом разделе: Руководства по мониторингу: каждый тип проверки шаг за шагом