Примеры логов

Материал из Документация Ключ-АСТРОМ
Версия от 23:05, 13 октября 2026; IKuznetsov (обсуждение | вклад) (Новая страница: « = Примеры логов = Управление логами и аналитика позволяют точно определять и извлекать любые данные логов с помощью '''Языка запросов Ключ-АСТРОМ (DQL)'''. После ознакомления с '''основами запросов DQL''' используйте примеры на этой странице, чтобы начать полу...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)

Примеры логов

Управление логами и аналитика позволяют точно определять и извлекать любые данные логов с помощью Языка запросов Ключ-АСТРОМ (DQL). После ознакомления с основами запросов DQL используйте примеры на этой странице, чтобы начать получать ответы из ваших данных логов.

Пример 1: Коды состояния и количество

В этом примере вы получаете распределение кодов состояния HTTP и количество ошибок по типам. Прокси-сервер записывает коды состояния HTTP-ответов. Вам нужно увидеть распределение кодов ответов за определённый временной диапазон и сосредоточиться на ошибках.

Поиск соответствующих логов

Начните с поиска логов от экземпляра HAProxy. Поскольку строка haproxy включена в сообщение лога, используйте функцию contains().

fetch logs
| filter contains(content, "haproxy")

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

fetch logs
| filter dt.entity.process_group=="PROCESS_GROUP-123F4A56BCDA0EA9"

Таблица результатов

timestamp content log.source dt.entity.host
2022-08-10 14:05:42 2022-08-10T11:05:42Z localhost haproxy[12529]: 123.45.67.891:23456 http-in~ individual_servers/abcde1 123/0/0/1/456 HTTP_STATUS 200 284 - - –NN 5749/5745/0/1/0… /var/abcde/abc/defrghytji/HOST-1… HOST-AB-12-34567
2022-08-10 14:05:46 2022-08-10T11:05:46Z localhost haproxy[12528]: 12.345.67.123:12345 http-in~ local/local1 5432/0/0/103/1234 HTTP_STATUS 200 138 - - – 7416/7413/407/408/0 0/… /var/abcde/abc/defrghytji/HOST-A2… HOST-CD-76-54321
2022-08-10 14:05:50 2022-08-10T11:05:50Z localhost haproxy[12529]: 11.222.33.123:45678 http-in~ local/local1 19/0/1/110/123 HTTP_STATUS 204 64 - - – 5753/5749/358/359/0 0/0… /var/abcde/abc/defrghytji/HOST-A23… HOST-AR-78-12345

Извлечение метрики из поля content

Поле content лога содержит нужные коды HTTP_STATUS. Теперь используйте команду parse, чтобы создать шаблон Языка шаблонов Ключ-АСТРОМ со следующими элементами:

  • LD: начните с сопоставления любых строчных данных в начале поля.
  • 'HTTP_STATUS ': литеральное выражение, которое непосредственно предшествует числовому HTTP-статусу и учитывает пробел.
  • INT:httpstatus: целое число, которое будет выделено в новое поле httpstatus.
fetch logs
| filter dt.entity.process_group=="PROCESS_GROUP-123F4A56BCDA0EA9"
| parse content, "LD 'HTTP_STATUS ' INT:httpstatus"

Таблица результатов

timestamp content httpstatus
2022-08-10 14:05:42 2022-08-10T11:05:42Z localhost haproxy[12529]: 123.45.67.891:23456 http-in~ individual_servers/abcde1 123/0/0/1/456 HTTP_STATUS 200 284 - - –NN 5749/5745/0/1/ 0… 200
2022-08-10 14:05:46 2022-08-10T11:05:46Z localhost haproxy[12528]: 12.345.67.123:12345 http-in~ local/local1 5432/0/0/103/1234 HTTP_STATUS 200 138 - - – 7416/7413/407/408/0 0/… 200
2022-08-10 14:05:50 2022-08-10T11:05:50Z localhost haproxy[12529]: 11.222.33.123:45678 http-in~ local/local1 19/0/1/110/123 HTTP_STATUS 204 64 - - – 5753/5749/358/359/0 0/0… 204

Фильтрация диапазона значений

Вы можете выбрать диапазон значений для дальнейшего анализа с помощью DQL. Мы выбираем только коды состояния HTTP, начинающиеся с 400 и выше, так как они включают ошибки на стороне клиента и сервера.

fetch logs
| filter dt.entity.process_group=="PROCESS_GROUP-802F3A32CECA0EA9"
| parse content, "LD 'HTTP_STATUS ' INT:httpstatus"
| filter httpstatus >= 400

Агрегация результатов

Вам нужно агрегировать результаты с помощью count(), чтобы получить сводку о том, сколько раз встречается каждый код состояния.

fetch logs
| filter dt.entity.process_group=="PROCESS_GROUP-802F3A32CECA0EA9"
| parse content, "LD 'HTTP_STATUS ' INT:httpstatus"
| filter httpstatus >= 400
| summarize count(), by:{httpstatus}

Таблица результатов

count() httpstatus
4 403
779 404
1 500
9 503

Пример 2: Средний размер корзины

В этом примере вы определите средний размер корзины на основе логов. Ваше приложение записывает контекстные данные, relevant для вашего бизнеса. Вам нужно извлечь эти данные из логов и создать отчёт за определённый временной диапазон.

Выбор конкретных данных процесса за определённый временной диапазон

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

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"

Таблица результатов

timestamp content log.source dt.process.name
2022-08-05 11:29:57 {"@t":"2022-08-05T08:29:57.6864969Z","@m":"Slow GetCartAsync request detected for userId=a433448b-c38d-4144-9591-f510829d4gh2","@i":"abc0f94a"} /var/log/pods/prod_cartservice-74c8d7d674-7dqf cartservice cartservice-*
2022-08-05 11:29:57 {"@t":"2022-08-05T08:29:57.8068740Z","@m":"No carts for user ab51dc18-7724-44fb-cdf8-8bda633f0022","@i":"c9315217"} /var/log/pods/prod_cartservice-74c8d7d674-7dqf cartservice cartservice-*
2022-08-05 11:29:58 {"@t":"2022-08-05T08:29:57.6864541Z","@m":"GetCartAsync called with userId=z433448a-c38d-4123-9591-f510829d4ab2","@i":"1feab40c"} /var/log/pods/prod_cartservice-74c8d7d674-7dqf cartservice cartservice-*
2022-08-05 11:30:01 {"@t":"2022-08-05T08:30:01.1058085Z","@m":"Checking CartService Health","@i":"a01f1123"} /var/log/pods/prod_cartservice-74c8d7d674-7dqf cartservice cartservice-*

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

Вам нужно получить обзор типов и количества товаров, которые пользователи добавили в свои корзины. Поскольку логи содержат различные события, нужно указать события, в которых товары были добавлены в корзины, используя функцию contains(). Чтобы очистить таблицу результатов, рекомендуется оставить только timestamp и содержимое лога.

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"
| filter contains(content, "AddItemAsync")
| fields timestamp, content

Таблица результатов

timestamp content
2022-08-05 11:55:04 {"@t":"2022-08-05T08:55:04.9934166Z","@m":"AddItemAsync called with userId=a332eabc-f52f-40d5-a09f-51bb96f5d119, productId=1ZYFJ3GM2N, quantity=1","@i":"18b35248"}
2022-08-05 11:55:07 {"@t":"2022-08-05T08:55:07.1405993Z","@m":"AddItemAsync called with userId=5ddcdd66-f0fd-4608-839e-0cd7841a3bbc, productId=L2ECAV7KIM, quantity=5","@i":"04fe325f"}
2022-08-05 11:55:32 {"@t":"2022-08-05T08:55:32.5027148Z","@m":"AddItemAsync called with userId=66734557-683c-4864-b3c7-8f08b52f0b17, productId=LS3PSXUNUM, quantity=5","@i":"987426bd"}
2022-08-05 11:30:01 {"@t":"2022-08-05T08:55:58.6888309Z","@m":"AddItemAsync called with userId=c673ca76-3966-4174-b950-4c3f3aa22dfe, productId=4SIQT8TOJO, quantity=2","@i":"99a07cd5"}

Извлечение товаров и соответствующих количеств

Вам нужно извлечь идентификаторы товаров и количества из логов с помощью команды parse. Используя Язык шаблонов Ключ-АСТРОМ, создайте шаблон и сопоставьте следующие части поля content:

  • LD: начните с сопоставления любых строчных данных в начале поля.
  • 'userId=': литеральное выражение, которое непосредственно предшествует ID пользователя.
  • LD:userId: любые строчные данные, которые будут выделены в новое поле с именем userId.
  • ', productId=': литеральное выражение, которое завершает ID пользователя и отделяет его от ID товара.
  • LD:productId: любые строчные данные, которые будут выделены в новое поле с именем productId.
  • ', quantity=': литеральное выражение, которое завершает ID товара и отделяет его от количества.
  • INT:productQuantity: целое число, которое будет выделено в новое поле с именем productQuantity.

Остальные поля игнорируются.

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"
| filter contains(content, "AddItemAsync")
| fields timestamp, content
| parse content, "LD 'userId=' LD:userId ', productId=' LD:productId ', quantity=' INT:productQuantity"

Таблица результатов

timestamp content userId productId productQuantity
2022-08-05 11:55:04 {"@t":"2022-08-05T08:55:04.9934166Z","@m":"AddItemAsync called with userId=a332efea-f52f-40d5-a09f-51bb96f5d119, productId=1ZYFJ3GM2N, quantity=1","@i":"18b35248"} a332efea-f52f-40d5-a09f-51bb96f5d119 1ZYFJ3GM2N 1
2022-08-05 11:55:07 {"@t":"2022-08-05T08:55:07.1405993Z","@m":"AddItemAsync called with userId=5bdcdd66-f0fd-4608-839e-0cd7841a3bbc, productId=L2ECAV7KIM, quantity=5","@i":"04fe325f"} 5bdcdd66-f0fd-4608-839e-0cd7841a3bbc L2ECAV7KIM 5
2022-08-05 11:55:32 {"@t":"2022-08-05T08:55:32.5027148Z","@m":"AddItemAsync called with userId=66734557-683c-4864-c3c7-8f08b52f0b17, productId=LS3PSXUNUM, quantity=5","@i":"987426bd"} 66734557-683c-4864-c3c7-8f08b52f0b17 LS3PSXUNUM 5
2022-08-05 11:30:01 {"@t":"2022-08-05T08:55:58.6888309Z","@m":"AddItemAsync called with userId=d673ca76-3966-4174-b950-4c3f3aa22dfe, productId=4SIQT8TOJO, quantity=2","@i":"99a07cd5"} d673ca76-3966-4174-b950-4c3f3aa22dfe 4SIQT8TOJO 2

Очистка данных

Поскольку ID пользователя и исходная запись лога больше не relevant, давайте очистим таблицу результатов с помощью команды fields.

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"
| filter contains(content, "AddItemAsync")
| fields timestamp, content
| parse content, "LD 'userId=' LD:userId ', productId=' LD:productId ', quantity=' INT:productQuantity"
| fields productId, productQuantity

Таблица результатов

productId productQuantity
1ZYFJ3GM2N 1
L2ECAV7KIM 5
LS3PSXUNUM 5
4SIQT8TOJO 2

Сводка событий по товарам

Чтобы увидеть общее количество каждого товара, добавленного в корзину, используйте функцию sum().

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"
| filter contains(content, "AddItemAsync")
| fields timestamp, content
| parse content, "LD 'userId=' LD:userId ', productId=' LD:productId ', quantity=' INT:productQuantity"
| fields productId, productQuantity
| summarize sum(productQuantity), by:{productId}

Таблица результатов

productId sum(productQuantity)
APUK6V6EV0 61
B9ECA1YMWWN1N4OV7KIM 47
66CDHSJNUP 38
9DIQT8TOJO 32

Поиск самых популярных товаров

Чтобы понять поведение среднего пользователя, мы хотим определить средний размер корзины для каждого товара. Для этого мы используем функцию avg() и называем новое поле averageProductQuantity. Затем мы сортируем средние значения от наибольшего к наименьшему и ограничиваем результаты, чтобы увидеть пять самых популярных товаров.

fetch logs, from:now()-3h
| filter dt.process.name=="cartservice cartservice-*"
| filter contains(content, "AddItemAsync")
| fields timestamp, content
| parse content, "LD 'userId=' LD:userId ', productId=' LD:productId ', quantity=' INT:productQuantity"
| fields productId, productQuantity
| summarize averageProductQuantity = avg(productQuantity), by:{productId}
| sort averageProductQuantity desc
| limit 5

Таблица результатов

averageProductQuantity productId
4.746268656716418 1ZYFJ3GM2N
4.4375 26VCHSJNUP
4.415584415584416 LS3PSXUNUM
4.3604651162790695 L4ECAV7KIM
4.2682926829268295 1YMWWN1N4O

Пример 3: Отслеживание изменений пользователей

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

Проверка доступности последних логов аудита

  • Узнайте, были ли доступны какие-либо логи аудита за последние пять минут.
  • Установите временной диапазон и отфильтруйте только логи, исходный путь которых заканчивается на ваш designated path.
fetch logs, from:now()-5m
| filter endsWith(log.source,"change.log")

Таблица результатов

content timestamp dt.entity.host dt.entity.process_group
{"eventType":"UPDATE","tenantId":"abc","use… 2022-07-15 09:08:00 UTC 15.7.2022 12:08 HOST-1 PROCESS_GROUP-12ED48520DB559D1
{"eventType":"CREATE","tenantId":"efg","use… 2022-07-15 09:08:07 UTC 15.7.2022 12:08:07 HOST-2 PROCESS_GROUP-34ED48520DB559D2
{"eventType":"UPDATE","tenantId":"hij","use… 2022-07-15 09:11:19 UTC 15.7.2022 12:11:19 HOST-3 PROCESS_GROUP-56ED48520DB559D3
{"eventType":"DELETE","tenantId":"klm","use… 2022-07-15 09:11:19 UTC 15.7.2022 12:11:19 HOST-4 PROCESS_GROUP-78ED48520DB559D4

Извлечение relevant полей для одного пользователя

  • Полученная таблица включает обновления, удаления и создания записей.
  • Если вы ограничите запрос последним результатом, вы сможете понять действия, выполненные одним пользователем. Затем мы делаем следующее:
    • Используйте parse, чтобы превратить поле content в объект JSON.
    • Используйте fieldsAdd, чтобы извлечь relevant поля из этого объекта.
    • Используйте fields, чтобы добавить relevant поле.
    • Используйте fieldsRemove, чтобы получить только нужные столбцы.
fetch logs, from:now()-5m
| filter endsWith(log.source,"change.log")
| limit 1
| parse content, "TIMESTAMP('yyyy-MM-dd HH:mm:ss'):ts LD JSON:settings"
| fields ts, settings
| fieldsAdd type = settings[eventType], tenant = settings[tenantId], user = settings[userId]
| fieldsRemove settings

Таблица результатов

ts type tenant user
2022-07-14 09:19:34 UPDATE abc 1aae042c-ab34-4f01-8d46-128971703d5a

Получение пользователей, выполнивших обновления и удаления

Чтобы получить пользователей, которые выполнили только обновления или удаления:

  • Удалите команду limit.
  • Добавьте фильтр для двух типов действий: update и delete.
fetch logs, from:now()-5m
| filter endsWith(log.source,"change.log")
| parse content, "TIMESTAMP('yyyy-MM-dd HH:mm:ss'):ts LD JSON:settings"
| fields ts, settings
| fieldsAdd type = settings[eventType], tenant = settings[tenantId], user = settings[userId]
| fieldsRemove settings
| filter in(type,array("UPDATE","DELETE"))

Таблица результатов

ts type tenant user
2022-07-14 09:19:34 UPDATE abc 2aae042c-ab34-4f01-8d46-128971703d5b
2022-07-14 05:11:04 UPDATE abc 386b63fc-1516-4b46-9714-ee53dd76c99c
2022-07-14 05:00:49 DELETE abc 486b63fc-1516-4b46-9714-ee53dd76c99d
2022-07-14 04:21:43 DELETE abc 586b63fc-1516-4b46-9714-ee53dd76c99e

Определение типов изменений и количества изменений, выполненных каждым пользователем

Вы можете подсчитать записи с помощью команды summarize.

fetch logs, from:now()-5m
| filter endsWith(log.source,"change.log")
| parse content, "TIMESTAMP('yyyy-MM-dd HH:mm:ss'):ts LD JSON:settings"
| fields ts, settings
| fieldsAdd type = settings[eventType], tenant = settings[tenantId], user = settings[userId]
| fieldsRemove settings
| filter in(type,array("UPDATE","DELETE"))
| summarize count(), by:{user,type}

Таблица результатов

user type count()
686b63fc-1516-4b46-9714-ee53dd76c99f DELETE 78
786b63fc-1516-4b46-9714-ee53dd76c99g UPDATE 34
8aae042c-ab34-4f01-8d46-128971703d5h UPDATE 20
9d4a7ac8-e451-6469-cced-6f4358ef343i UPDATE 17

Подсчёт событий по пользователю с разбивкой по типу действия

Вы можете выполнить расчёт, объединив команду summarize с функцией countIf.

fetch logs, from:now()-5m
| filter endsWith(log.source,"change.log")
| parse content, "TIMESTAMP('yyyy-MM-dd HH:mm:ss'):ts LD JSON:settings"
| fields ts, settings
| fieldsAdd type = settings[eventType], tenant = settings[tenantId], user = settings[userId]
| fieldsRemove settings
| filter in(type,array("UPDATE","DELETE"))
| summarize {countIf(type=="CREATE"), countIf(type=="UPDATE"), countIf(type=="DELETE")}, by:{tenant, user}

Таблица результатов

tenant user countIf(type=="CREATE") countIf(type=="UPDATE") countIf(type=="DELETE")
def 186b63fc-1516-4b46-9714-ee53dd76c99a 0 34 78
ghi 2aae042c-ab34-4f01-8d46-128971703d5b 19 20 8
jkl 3d4a7ac8-e451-6469-cced-6f4358ef343c 2 17 11

Пример 4: Создание метрики лога

В этом примере вам нужно подсчитать, сколько отклонённых соединений зафиксировано в ваших данных логов. Для этого отфильтруйте нужные логи и превратите количество вхождений в метрику лога. В этом примере вам нужно отслеживать атрибут ваших логов и следить за уровнями ошибок, сообщаемыми в логах из вашего кластера K8s.

Пример 5: Создание оповещения по логам

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

Создание метрики обнаружения аномалий

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