Как искать в Kibana уже написано (1, 2, 3, 4, 5, 6) но для себя еще коротко:
| Описание | SQL | Kibana | Найдет строку | Не найдет строку |
| неточный поиск во всех полях | нет аналога | "value1" | - MY value1 bar | - MY bar |
| неточный поиск по части | нет аналога | - field:"value1" - field:/value1/ | - MY value1 bar - MY value1-bar | - MYvalue1 bar - MYvalue1Bar |
| неточный поиск по полю слева | field like '%value1' | field: *value1 | - MYvalue1 - MYvalue1 bar - MYvalue1-bar | - MYvalue1Bar |
| неточный поиск по полю, более сложный способ это использовать регулярку (о ней смотрите ниже) | field like '%value1%' | field: *value1* | - MYvalue1 - MYvalue1 bar - MYvalue1-bar - MYvalue1Bar | - MY bar |
| поиск по двум значениям (раньше работало, в 7-ой версии нет) | field like '%value1%' OR field like '%value2%' | field: "value1, value2" | - MYvalue1 - MYvalue1 bar | |
| точный поиск по полю | field like 'value1' | field.keyword: "value1" | - value1 | все остальное |
| поиск по диапазону: | field >= 500 field BETWEEN 500 AND X | field: [500 TO *] field: {500 TO *} | ||
| наличие поля или любой записи | field like '%' | field: * | все строки |
{
"query": {
"wildcard": {
"request.keyword": "*.json*"
}
}
}как видите, не смотря на то, что строки при индексировании обрабатываются анализатором (Analyzer), который разбирает строку на части, например www.google.com станет "www, google, com", в поле keyword хранит оригинал, по которому можно "грепать".
Поиск сразу по двум значениям (one OR two):
{
"query": {
"bool": {
"should": [
{
"wildcard": {
"request.keyword": "*.json*"
}
},
{
"wildcard": {
"request.keyword": "*/api/*"
}
}
],
"minimum_should_match": 1
}
}
}Поиск по регулярке:
curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"regexp": {
"user.id": {
"value": "k.*y",
"flags": "ALL",
"case_insensitive": true,
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}
'* в версии 6.8 флаг невалидно указывать: "case_insensitive": true,
Отрицание ненужных уровней и ошибок:

Фильтр по файлу делается так:


Поиск по float >= 0.5
{
"query": {
"bool": {
"filter": [
{
"range": {
"request_time": {
"gte": "0.5"
}
}
}
]
}
}
}Поиск по началу строки (префикс): 1 - 2 - 3
{
"query": {
"match_phrase_prefix": {
"api_method": {
"query": "seo"
}
}
}
}Количество записей в каждом лог-файле за последние 4 часа:

Фильтр, который группирует по типу ошибок:

Визуализация по кол-ву запросов:

Http статусы

p.s. к сожалению с значением float, так не получится (Kibana будет показывать неправильные данные), попробуйте просто использовать перцентели.
Время запроса максимальное и среднее



Еще несколько примеров



Построение графика по 5 наиболее запрашиваемым страницам на сайте (визуализация Visual Builder):

а индекс и параметры выборки указываются на вкладке Panel options:

Список наиболее часто запрашиваемых адресов (с информацией о кол-ве запросов, максимальному и среднему времени выполнения запроса, а так же по 95 и 97 перцентелям).


Чтобы добавить на дашборд список записей из которых построены графики, нужно при добавлении визуализации выбрать вкладку Saved Search (конечно предварительно нужно такой сохранить, а сохранятся он на странице Discover и минимально может состоять только из выбора индекса):

Есть и нотификации, для этого компания Elasticsearch предлагает инструменты Watcher и Observability.
Логировать можно за большее кол-во дней (по возможности 2 недели, чтобы отслеживать тенденцию).
Как просматривать логи (фильтрация):
a) выбрал название сервиса ( project_name, если говорить о веб-приложении, то это http host )
б) выбрал source_name ( все или на выбор: https://www.php.net/manual/ru/function.php-sapi-name.php#refsect1-function.php-sapi-name-returnvalues )
* логи веб-сервиса должны использовать source_name возвращаемое пхп функцией php_sapi_name
в) выбрал уровень логирования (level_name)
* логи веб-сервиса должны использовать отличное значение от level_name используемое в приложении или виртуальной машине, например есть:
- access статики
- access пхп-фпм
Все виды логов должны реализовывать единый формат:
{
"project_name": "wosy",
"source_name": "cli",
"level_name": "ERROR",
"message": "phpErrorHandler error",
"datetime": {
"date": "2018-07-13 11:35:58.248318",
"timezone_type": 3,
"timezone": "Europe/Moscow"
},
Дополнительные данные, которые могут отсутсвовать:
"http_request_id": "490d25d", -- часто используется для связывания запросов в микросервисах
"channel": "time_balance", -- часто используется в монологе
"context": { -- место в проекте, которое вызвало запись в лог
"code": 123,
"message": "Call to a member function verify_phone() on null",
"file": "/var/www/builds/api2-9fd503b71cf911e6621af710e077e1bf88760935-20180710T102106/app/src/Customer/V1/VerifyResource.php",
"line": 28,
"trace": "any string"
},
"extra": { -- остальные данные, могут присутствовать в логах, но не обязаны индексироваться
"http_method": "GET",
"http_host": "test-api2.gemotest.ru",
"url": "/customer/v2/verify?phone=79258277651",
"referrer": null,
"function": "MyFunction",
"session": {
"id": "fkajsldfkjalsdhfasldkfjaFHdksjlfsd",
"user_id": 54546
}
"server_ip": "10.128.71.100",
"remote_addr": "10.128.71.200",
}
}Важно: регламентировать глубину вложенности логов - обычно достаточно глубины равной трем (остальное обрезается).
Напомню, что обычно php-приложение состоит из:
- логи приложения (например monolog в формате json)
- логов php (ошибки в самом php)
Статьи по теме:
https://habr.com/ru/post/345968/
Вот в таком виде приходят логи из Haproxy:
{
"_index": "logstash-haproxylog-2019.08.20",
"_type": "doc",
"_id": "mw4QrmwBHMig4HowlNn0",
"_version": 1,
"_score": null,
"_source": {
"source": "/var/log/haproxy/haproxy.log",
"prospector": {
"type": "log"
},
"time_queue": 0,
"beconn": 0,
"srvconn": 0,
"syslog_server": "sl-app-13",
"type": "haproxylog",
"captured_response_cookie": "-",
"frontend_name": "ft_web~",
"offset": 1591510441,
"@version": "1",
"request_header_accept_language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
"termination_state": "sH--",
"server_name": "sl-sky-03",
"time_backend_response": -1,
"time_duration": 240000,
"actconn": 693,
"backend_name": "office2",
"http_request": "/index.php?r=gemopay/Purchase/PaymentForm&model_id=51782369&module_type=lis&model_type=order",
"syslog_timestamp": "Aug 20 11:06:56",
"bytes_read": 195,
"tags": [
"beats_input_codec_plain_applied",
"filter.grok.haproxy.log"
],
"retries": 0,
"srv_queue": 0,
"http_status_code": 504,
"request_header_user_agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
"http_version": "1.1",
"host": "sl-app-13",
"request_header_referer": "https://office2.gemotest.ru/inputOrder/inputMain_test.php?oid=51782369",
"client_port": 4956,
"@timestamp": "2019-08-20T08:02:56.330Z",
"client_ip": "87.117.56.253",
"time_backend_connect": 0,
"captured_request_cookie": "-",
"feconn": 693,
"backend_queue": 0,
"http_verb": "GET",
"time_request": 0,
"beat": {
"version": "6.2.3",
"name": "sl-app-13",
"hostname": "sl-app-13"
},
"request_header_host": "office2.gemotest.ru"
},
"fields": {
"@timestamp": [
"2019-08-20T08:02:56.330Z"
]
},
"highlight": {
"request_header_host": [
"office2.@kibana-highlighted-field@gemotest.ru@/kibana-highlighted-field@"
],
"request_header_referer": [
"https://office2.@kibana-highlighted-field@gemotest.ru@/kibana-highlighted-field@/inputOrder/inputMain_test.php?oid=51782369"
]
},
"sort": [
1566288176330
]
}Из mono.log :
{
"_index": "logstash-%{[type]}-2019.08.21",
"_type": "doc",
"_id": "E2Q5s2wBHMig4Howd7LG",
"_version": 1,
"_score": null,
"_source": {
"@timestamp": "2019-08-21T08:09:35.789Z",
"source": "/var/log/php-app/mono.log",
"prospector": {
"type": "log"
},
"beat": {
"version": "6.4.3",
"name": "sl-sky-02",
"hostname": "sl-sky-02"
},
"host": {
"name": "sl-sky-02"
},
"offset": 42778529,
"tags": [
"beats_input_codec_plain_applied",
"_grokparsefailure"
],
"@version": "1",
"message": "{\"message\":\"Sending message\",\"context\":{\"classMethod\":\"Gs\\\\Gemopay\\\\Handler\\\\Handler::request\",\"requestId\":0},\"level\":300,\"level_name\":\"WARNING\",\"channel\":\"gemopay\",\"datetime\":{\"date\":\"2019-08-21 11:09:35.740972\",\"timezone_type\":3,\"timezone\":\"Europe/Moscow\"},\"extra\":{\"session\":{\"id\":\"4diuompce3bv26eilknn0d6bur\",\"user_id\":4000746},\"trace\":\"#11 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/src/Gemopay/Handler/Handler.php(310): Monolog\\\\Logger->warning('Sending message', Array)\\n#10 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/src/Gemopay/Handler/FiscalPrinterHandler.php(50): Gs\\\\Gemopay\\\\Handler\\\\Handler->request('Status', Array, 15)\\n#9 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/src/Gemopay/Service/Payment/FiscalPrinterStatusFactory.php(38): Gs\\\\Gemopay\\\\Handler\\\\FiscalPrinterHandler->Status()\\n#8 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/src/Gemopay/Service/Payment/PaymentService.php(211): Gs\\\\Gemopay\\\\Service\\\\Payment\\\\FiscalPrinterStatusFactory->create('0617740006060912')\\n#7 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/www/protected/modules/gemopay/controllers/PurchaseController.php(33): Gs\\\\Gemopay\\\\Service\\\\Payment\\\\PaymentService->initByGemopay('0617740006060912', 4000746, '50091', '50091_ЛОКАЛМЕДСЕРВИС_Московская область_Балашиха_янтарный_2', 'lis', '51785947', 'order', 8)\\n#6 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/web/CController.php(306): PurchaseController->beforeAction(CInlineAction)\\n#5 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/web/CController.php(286): CController->runAction(CInlineAction)\\n#4 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/web/CController.php(265): CController->runActionWithFilters(CInlineAction, Array)\\n#3 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/web/CWebApplication.php(282): CController->run('PaymentForm')\\n#2 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/web/CWebApplication.php(141): CWebApplication->runController('gemopay/Purchase/PaymentForm')\\n#1 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/vendor/yiisoft/yii/framework/base/CApplication.php(185): CWebApplication->processRequest()\\n#0 /var/www/builds/gemosystem-daa29b362d0c3b65faed5b075d4ef9ae1f774f3f-20190814T155407/www/index.php(17): CApplication->run()\\n\",\"url\":\"/index.php?r=gemopay/Purchase/PaymentForm&model_id=51785947&module_type=lis&model_type=order\",\"ip\":\"185.13.112.232\",\"http_method\":\"GET\",\"server\":\"office.gemotest.ru\",\"referrer\":\"https://office.gemotest.ru/inputOrder/inputMain_test.php?oid=51785947\",\"uid\":\"2b753f0\"}}",
"input": {
"type": "log"
}
},
"fields": {
"@timestamp": [
"2019-08-21T08:09:35.789Z"
]
},
"highlight": {
"source.keyword": [
"@kibana-highlighted-field@/var/log/php-app/mono.log@/kibana-highlighted-field@"
]
},
"sort": [
1566374975789
]
}Elasticsearch as a Time Series Data Store : 1 - 2