Логи собраны, разобраны на поля и лежат в Elasticsearch. Дежурный «Гонца» открывает Kibana, раздел Discover, и пишет в строке поиска. Не JSON на десять строк, как в консоли, а короткую строку вроде service.name : payments and log.level : ERROR. Это KQL, язык запросов Kibana. Разберём его по шагам.
Экран Discover
У Discover четыре части:
- строка запроса сверху, туда пишут KQL;
- полоса времени рядом с ней: за какой период искать. Kibana превратит её в фильтр по полю
@timestamp; - гистограмма: сколько событий в каждый отрезок времени. По ней сразу видно всплески;
- таблица документов и список полей слева. Клик по полю добавляет его колонкой.
Какие индексы Discover ищет, задаёт data view, об этом урок 14. В нашей учебной Discover это logs-*.
Основы KQL
| Запрос | Что найдёт |
|---|---|
service.name : payments | поле равно значению |
log.level : ERROR and service.name : payments | оба условия |
log.level : (ERROR or WARN) | любое из значений поля |
not log.level : INFO | всё, кроме |
http.response.status_code >= 500 | сравнение чисел и дат: >, >=, <, <= |
url.original : /api/payments* | звёздочка: любое продолжение |
error.type : * | у документа есть поле |
message : "Bank gateway" | фраза в кавычках, слова подряд |
Bank | слово в любом поле |
Пара тонкостей:
andсильнееor, как в математике умножение сильнее сложения. Если сомневаешься, ставь скобки:(a or b) and c.- Текстовые поля сравниваются по словам после анализа, как
match, а точные поляkeywordцеликом, какterm.service.name : Paymentsс большой буквы не найдётpayments. - Запрос без имени поля ищет по всем полям сразу. Удобно, но медленнее и находит случайные совпадения.
Поле меняет смысл запроса
Представь карточку заказа. На ней есть номер, имя клиента и свободный комментарий. Номер ищут целиком: заказ 104549 не тот же самый, что 10454. Комментарий ищут по словам: фраза «позвони перед доставкой» должна находиться по слову «доставкой». У логов такая же разница.
service.name и log.level описывают категории, поэтому в учебных данных имеют тип keyword. Запрос service.name : payments проверяет одно точное значение. Поле message содержит человеческое описание события и имеет тип text. Для него Elasticsearch разбирает запрос и документ на слова своим анализатором. Поэтому message : gateway может найти и Bank gateway timeout, и Bank gateway connection reset.
Кавычки не превращают текстовое поле в точное. Они задают фразу: message : "Bank gateway" ищет эти слова рядом в указанном порядке. Полная строка документа при этом может содержать ещё слово timeout. Если нужно проверить всю строку целиком, нужен подходящий маппинг, а не ещё одна пара кавычек.
Проверяй имя поля по списку Discover, а не по внешнему виду сообщения. Число 504 внутри message и число в http.response.status_code различаются: первое часть текста, второе значение типизированного поля. Условие http.response.status_code >= 500 сравнивает числа. Поиск message : 504 ищет слово и может пропустить событие, где текст ошибки другой.
Скобки задают границу выбора
Дежурному нужны ошибки платежей и предупреждения платежей. Правильная мысль: «сервис payments, а уровень один из двух». Её прямо выражает service.name : payments and log.level : (ERROR or WARN). Скобки после имени поля позволяют не повторять log.level для каждого значения.
Без скобок запрос service.name : payments and log.level : ERROR or log.level : WARN читается иначе: сначала объединяются условия с and, потом добавляются все WARN, уже независимо от сервиса. Это не ошибка синтаксиса. Такой запрос выполнится и вернёт лишние события, поэтому опаснее незакрытой скобки.
Можно записать выбор и полностью: service.name : payments and (log.level : ERROR or log.level : WARN). Две записи дают одну и ту же границу поиска. Начни с полной формы, если сокращение мешает понять, к какому полю относится значение.
Звёздочка: продолжение или наличие
В url.original : /api/payments* звёздочка разрешает любое продолжение пути. Она не означает «похожий текст» и не исправляет опечатки. Например, путь /api/orders не подойдёт, а /api/payments/104549 подойдёт, если такое значение есть в данных.
В error.type : * перед звёздочкой нет начала слова. Здесь вопрос другой: есть ли у события индексированное значение поля. Это полезно, когда разные исключения имеют разные имена, а дежурному пока нужны все записи с заполненным типом ошибки.
Не путай отсутствие поля с безопасным событием. Лог nginx может описывать ответ 504, но вообще не иметь error.type. Для него ошибка выражена кодом HTTP. Выбор поля зависит от источника и вопроса расследования, а не от слова «ошибка» в голове.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.