Примеры обработки логов
В зависимости от созданных вами правил вы можете настроить входящие данные логов в соответствии с вашими потребностями. Ниже приведены примеры сценариев обработки данных.
- Пример 1 — Исправление нераспознанных таймфреймов и уровня логов, отображаемых в средстве просмотра логов, на основе сопоставленного источника логов.
- Пример 2 — Определение доступного для поиска настраиваемого атрибута с использованием извлеченного идентификатора из совпавшей фразы в содержимом логов.
- Пример 3 — Создание метрики продолжительной оплаты для служб AWS, используя данные логов.
- Пример 4 — Извлечение определенных полей из содержимого JSON.
- Пример 5 — Анализ атрибутов из разных форматов в одном выражении шаблона.
- Пример 6 — Несколько команд PARSE в одном правиле обработки.
- Пример 7 — Использование специализированных соответствий.
- Пример 8 — Манипулирование любым атрибутом лога (не только содержимым).
- Пример 9 — Добавление нового атрибута в текущую структуру событий логов.
- Пример 10 — Базовые математические вычисления по атрибутам.
- Пример 11 — Удаление определенного атрибута из сообщения лога.
- Пример 12 — Удаление всего события лога.
- Пример 13 — Маскировка любого атрибута.
- Пример 14 — Переименование атрибутов.
- Пример 15 — Типы данных поля ввода.
Пример 1: Исправление нераспознанных таймфреймов и уровня логов
Вы можете исправить нераспознанный таймфрейм и уровень лога, видимые в средстве просмотра логов, на основе сопоставленного источника логов. Для этого примера предположим, что вы видите сохраненное событие в средстве просмотра логов из приложения log.source
, которое установлено на /var/log/myapp/application.log.#
Вы замечаете несколько вещей, которые хотите исправить:
- лог содержит нераспознанный формат таймфрейма, который вы хотите рассматривать как таймфрейм события логов.
- Не обнаружено надлежащего уровня лога.
Итак, вы хотите преобразовать данные логов, чтобы они содержали правильные значения в полях timestamp и logLevel, и хотите добавить новый атрибут thread.name
, содержащий правильно извлеченное значение.
Чтобы создать правило обработки
- Скопируйте запрос просмотра лога в буфер обмена (
log.source="/var/log/myapp/application.log.#"
). - Перейдите в Настройки > Мониторинг логов> Обработка и выберите Добавить правило.
- Введите Название правила и скопированный запрос лога из буфера обмена. Название правила :
MyApp log processor
Соответствие :log.source="/var/log/myapp/application.log.#"
- Введите определение процесса для анализа временной метки, имени потока и уровня лога. Определение процесса :
PARSE(content, "TIMESTAMP('MMMMM d, yyyy HH:mm:ss'):timestamp ' [' LD:thread.name '] ' UPPER:loglevel")
где:TIMESTAMP
соответствие используется для поиска определенного формата даты и времени, а совпавшее значение устанавливается как существующий атрибут лога меток времени.LD
(Строковые данные) соответствие используется для сопоставления любых символов между литералами' ['
и'] '
.UPPER
литерал используется для сопоставления заглавных букв.- Остальная часть контента не совпадает.
- Введите следующий фрагмент данных логов вручную в текстовое поле «Образец лога» {| class="wikitable" |{ "event.type":"LOG", "content":"April 24, 2022 09:59:52 [myPool-thread-1] INFO Lorem ipsum dolor sit amet", "status":"NONE", "timestamp":"1650889391528", "log.source":"/var/log/myapp/application.log.#", "loglevel":"NONE" } |}
- Выберите Проверить правило . Отображаются обработанные данные логов. Поля
timestamp
иloglevel
имеют правильные значения. Дополнительный атрибутthread.name
также правильно извлечен {| class="wikitable" |{ "content":"April 24, 2022 09:59:52 [myPool-thread-1] INFO Lorem ipsum dolor sit amet", "timestamp":"1650794392000", "event.type":"LOG", "status":"NONE", "log.source":"/var/log/myapp/application.log.#", "loglevel":"INFO", "thread.name":"myPool-thread-1" } |} - Сохраните правило обработки лога.
По мере поступления новых данных логов вы сможете увидеть обработанные данные логов в средстве просмотра логов.
Пример 2: Определение настраиваемого атрибута для поиска
Вы можете определить доступный для поиска пользовательский атрибут, используя извлеченный идентификатор из совпавшей фразы в содержимом лога.
В этом примере вы видите следующую строку лога в файле лога (еще не сохраненную в Ключ-АСТРОМ), и вы хотите извлечь идентификатор из этой строки лога, чтобы сделать ее доступной для поиска в средстве просмотра логов.
2022-04-26 10:53:01 UTC ERROR Critical error occurred for product ID: 12345678 Lorem ipsum dolor sit amet
- Перейдите в Настройки > Мониторинг логов> Обработка и выберите Добавить правило..
- Введите Название правила и запрос лога. Для запроса лога используйте постоянную фразу из содержимого данных лога (
content="Critical error occurred for product ID"
) Название правила :MyApp product ID with error
Соответствие :content="Critical error occurred for product ID"
- Введите определение процесса для анализа идентификатора. Определение процесса :
PARSE(content, "LD 'product ID:' SPACE? INT:my.product.id")
- Предполагая, что вы наблюдали следующую запись лога в средстве просмотра логов, вы можете выбрать Скачать образец лога и автоматически заполнить текстовое поле Образец лога вашими данными лога.
2022-04-26 10:53:01 UTC ERROR Critical error occurred for product ID: 12345678 Lorem ipsum dolor sit amet
В качестве альтернативы вы можете вручную вставить наблюдаемую запись лога как содержимое записи лога в текстовое поле Образец лога {| class="wikitable" |{ "content": "2022-04-26 10:53:01 UTC ERROR Critical error occurred for product ID: 12345678 Lorem ipsum dolor sit amet" } |} - Выберите Проверить правило . Отображаются обработанные данные лога. Отображаемые обработанные данные лога обогащаются разобранным идентификатором продукта {| class="wikitable" |{ "content": "2022-04-26 10:53:01 UTC ERROR Critical error occurred for product ID: 12345678 Lorem ipsum dolor sit amet", "timestamp": "1650961124832", "my.product.id": "12345678" } |}
- Сохраните правило обработки лога.
- Перейдите в Настройки > Мониторинг логов > Пользовательские атрибуты и выберите Добавить пользовательский атрибут .
- Создайте пользовательский атрибут на основе проанализированного идентификатора продукта (
my.product.id
). Ключ :my.product.id
- Сохраните свой пользовательский атрибут.
- Теперь вы можете искать и фильтровать данные лога по атрибуту
my.product.id
в средстве просмотра логов.
Пример 3. Создание метрики продолжительной оплаты для служб AWS, используя данные логов
В этом примере вы хотите отслеживать фактическую тарифицированную длительность из ваших сервисов AWS. Вы хотите использовать атрибут cloud.provider
со значением в ваших данных лога aws
. В средстве просмотра логов вы видите запись лога, содержащую следующую строку:
REPORT RequestId: 000d000-0e00-0d0b-a00e-aec0aa0000bc Duration: 5033.50 ms Billed Duration: 5034 ms Memory Size: 1024 MB Max Memory Used: 80 MB Init Duration: 488.08 ms
Кроме того, эта запись лога содержит cloud.provider
атрибут со значением aws
.
- Перейдите в Настройки > Мониторинг логов > Обработка и выберите Добавить правило .
- Введите Название правила и запрос лога. Для запроса лога используйте постоянную фразу из содержимого данных лога для
cloud.provider="aws"
иcontent="Billed Duration"
Название правила :AWS services - billed duration
Соответствие :cloud.provider="aws" and content="Billed Duration"
- Введите определение процесса для анализа значения тарифицированной длительности. Определение процесса :
PARSE(content, "LD 'Billed Duration:' SPACE? INT:aws.billed.duration")
- Предполагая, что вы наблюдали следующую запись лога в средстве просмотра логов, вы можете выбрать Скачать образец лога и автоматически заполнить текстовое поле Образец лога вашими данными лога.
REPORT RequestId: 000d000-0e00-0d0b-a00e-aec0aa0000bc Duration: 5033.50 ms Billed Duration: 5034 ms Memory Size: 1024 MB Max Memory Used: 80 MB Init Duration: 488.08 ms
В качестве альтернативы вы можете вручную ввести следующий фрагмент данных лога (содержащий другие дополнительные атрибуты) в текстовое поле Образец лога {| class="wikitable" |{ "event.type": "LOG", "content": "REPORT RequestId: 000d000-0e00-0d0b-a00e-aec0aa0000bc\tDuration: 5033.50 ms\tBilled Duration: 5034 ms\tMemory Size: 1024 MB\tMax Memory Used: 80 MB\t\n", "status": "INFO", "timestamp": "1651062483672", "cloud.provider": "aws", "cloud.account.id": "999999999999", "cloud.region": "eu-central-1", "aws.log_group": "/aws/lambda/aws-dev", "aws.log_stream": "2022/04/27/[$LATEST]0d00000daa0c0c0a0a0e0ea0eccc000f", "aws.region": "central-1", "aws.account.id": "999999999999", "aws.service": "lambda", "aws.resource.id": "aws-dev", "aws.arn": "arn:aws:lambda:central-1:999999999999:function:aws-dev", "cloud.log_forwarder": "999999999999:central-1:astromkey-aws-logs", "loglevel": "INFO" } |} - Выберите Проверить правило . Отображаются обработанные данные лога. Отображаемые обработанные данные лога обогащены новым атрибутом
aws.billed.duration
. - Сохраните правило обработки лога.
- Перейдите в Настройки > Мониторинг логов > Извлечение метрик и выберите Добавить метрику лога .
- Создайте метрику лога на основе проанализированного идентификатора продукта (
aws.billed.duration
). Ключ :log.aws.billed.duration
Запрос :cloud.provider="aws" and content="Billed Duration"
Мера :Attribute value
Атрибут :aws.billed.duration
- Сохраните метрику лога.
- Метрика
log.aws.billed.duration
видна в Визуализации метрик, и вы можете использовать ее в Ключ-АСТРОМ, как и любую другую метрику. Вы можете добавить ее на свой дашборд, включить в анализ и даже использовать ее для создания оповещений.
- Доступность метрики логов в Ключ-АСТРОМ Созданная метрика логов доступна только тогда, когда новые данные лога принимаются и соответствуют запросу лога, определенному во время создания метрики лога. Убедитесь, что новые данные лога приняты, прежде чем использовать метрику лога в других областях Ключ-АСТРОМ.
Пример 4: Извлечение определенных полей из содержимого JSON
В этом примере вы видите строку лога, имеющую следующую структуру JSON:
{"intField": 13, "stringField": "someValue", "nested": {"nestedStringField1": "someNestedValue1", "nestedStringField2": "someNestedValue2"} }
Пример лога будет выглядеть следующим образом
{
"content": "{\"intField\": 13, \"stringField\": \"someValue\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }" } |
- Парсинг поля из JSON в плоском режиме. Вы можете использовать JSON-соответствие и настроить его для извлечения нужных полей в качестве атрибутов лога верхнего уровня. Соответствие в плоском режиме автоматически создает атрибуты и называет их точно так же, как и соответствующие имена полей JSON. Затем вы можете использовать команду
FIELDS_RENAME
, чтобы задать имена, которые вам подходят. Определение правила обработки {| class="wikitable" |PARSE(content, "JSON{STRING:stringField}(flat=true)") | FIELDS_RENAME(better.name: stringField) |}
Результат после преобразования {| class="wikitable" |{ "content": "{\"intField\": 13, \"stringField\": \"someValue\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }", "better.name": "someValue" } |} - Разбор вложенного поля из JSON. Вы также можете разобрать больше полей (включая вложенные) с помощью JSON-соответствия без плоского режима. В результате вы получаете
VariantObject
, который можете обрабатывать дальше. Например, вы можете создать атрибут верхнего уровня из его внутренних полей. Определение правила обработки {| class="wikitable" |PARSE(content, " JSON{ STRING:stringField, JSON {STRING:nestedStringField1}:nested }:parsedJson") | FIELDS_ADD(top_level.attribute1: parsedJson["stringField"], top_level.attribute2: parsedJson["nested"]["nestedStringField1"]) | FIELDS_REMOVE(parsedJson) |}
Результат после преобразования {| class="wikitable" |{ "content": "{\"intField\": 13, \"stringField\": \"someValue\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }", "top_level.attribute1": "someValue", "top_level.attribute2": "someNestedValue1" } |} - Анализ всех полей из JSON в режиме автообнаружения. Иногда вам интересны все поля JSON. Вам не нужно перечислять все атрибуты. Вместо этого можно использовать JSON-соответствие в режиме автообнаружения. В результате вы получаете
VARIANT_OBJECT
, который можно обрабатывать дальше. Например, вы можете создать атрибут верхнего уровня из его внутренних полей. Определение правила обработки {| class="wikitable" |PARSE(content,"JSON:parsedJson") | FIELDS_ADD(f1: parsedJson["intField"], f2:parsedJson["stringField"], f3:parsedJson["nested"]["nestedStringField1"], f4:parsedJson["nested"]["nestedStringField2"]) | FIELDS_REMOVE(parsedJson) |}
Результат после преобразования {| class="wikitable" |{ "content": "{\"intField\": 13, \"stringField\": \"someValue\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }", "f1": "13", "f2": "someValue", "f3": "someNestedValue1", "f4": "someNestedValue2" } |} - Анализ любого поля из JSON, обработка контента как обычного текста. При таком подходе вы можете назвать атрибут как вам угодно, но правило обработки становится более сложным. Определение правила обработки {| class="wikitable" |PARSE(content, "LD '\"stringField\"' SPACE? ':' SPACE? DQS:newAttribute ") |}
Результат после преобразования {| class="wikitable" |{ "content": "{\"intField\": 13, \"stringField\": \"someValue\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }", "newAttribute": "someValue" } |}
Пример 5: Анализ атрибутов из разных форматов
Вы можете анализировать атрибуты из разных форматов в рамках одного выражения шаблона.
В этом примере одно или несколько приложений регистрируют идентификатор пользователя, который вы хотите извлечь как отдельный атрибут лога. Формат лога не является однообразным, поскольку он включает в себя различные схемы для регистрации идентификатора пользователя:
user ID=
userId=
userId:
user ID =
С помощью необязательного модификатора (вопрос ?
) и Alternative Groups
вы можете охватить все такие случаи одним шаблонным выражением
PARSE(content, "
LD //matches any text within a single line ('user'| 'User') //user or User literal SPACE? //optional space ('id'|'Id'|'ID') //matches any of these SPACE? //optional space PUNCT? //optional punctuation SPACE? //optional space INT:my.user.id ") |
Используя такое правило, вы можете извлечь идентификатор пользователя из множества различных нотаций. Например:
03/22 08:52:51 INFO user ID=1234567 Call = 0319 Result = 0
03/22 08:52:51 INFO UserId = 1234567 Call = 0319 Result = 0
03/22 08:52:51 INFO user id=1234567 Call = 0319 Result = 0
03/22 08:52:51 INFO user ID:1234567 Call = 0319 Result = 0
03/22 08:52:51 INFO User ID: 1234567 Call = 0319 Result = 0
03/22 08:52:51 INFO userid: 1234567 Call = 0319 Result = 0
Пример 6: Несколько команд PARSE в одном правиле обработки
Вы можете обрабатывать различные форматы или выполнять дополнительный анализ уже проанализированных атрибутов с помощью нескольких команд PARSE
, соединенных с помощью каналов (|
).
Например, с помощью следующего лога
{
"content": "{\"intField\": 13, \"message\": \"Error occurred for user 12345: Missing permissions\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }" } |
Во-первых, вы можете проанализировать поле сообщения, идентификатор пользователя и сообщение об ошибке
PARSE(content, "JSON{STRING:message}(flat=true)") | PARSE(message, "LD 'user ' INT:user.id ': ' LD:error.message") |
Результат
{
"content": "{\"intField\": 13, \"message\": \"Error occurred for user 12345: Missing permissions\", \"nested\": {\"nestedStringField1\": \"someNestedValue1\", \"nestedStringField2\": \"someNestedValue2\"} }", "message": "Error occurred for user 12345: Missing permissions", "user.id": "12345", "error.message": "Missing permissions" } |
Пример 7: использование специализированных соответствий
Мы предоставляем полный список соответствий, которые облегчают построение шаблонов.
Например, вы можете проанализировать следующий пример события лога
{
"content":"2022-05-11T13:23:45Z INFO 192.168.33.1 \"GET /api/v2/logs/ingest HTTP/1.0\" 200" } |
с использованием специализированных соответствий
PARSE(content, "ISO8601:timestamp SPACE UPPER:loglevel SPACE IPADDR:ip SPACE DQS:request SPACE INTEGER:code") |
и результат
{
"content": "2022-05-11T13:23:45Z INFO 192.168.33.1 \"GET /api/v2/logs/ingest HTTP/1.0\" 200", "timestamp": "1652275425000", "loglevel": "INFO", "ip": "192.168.33.1", "request": "GET /api/v2/logs/ingest HTTP/1.0", "code": "200" } |
Пример 8: Манипулирование любым атрибутом из лога (не только содержимым)
Если не указано иное, правило обработки работает только с полем содержимого только для чтения. Чтобы оно работало с различными атрибутами событий лога, необходимо использовать команду USING
.
Например, следующее правило объявляет два входных атрибута: статус записи и содержимое только для чтения. Затем оно проверяет, является ли статус WARN
и содержит ли содержимое текст error
. Если оба условия истинны, правило перезаписывает status
значением ERROR
.
Определение правила обработки
USING(INOUT status:STRING, content)
| FIELDS_ADD(status:IF_THEN(status == 'WARN' AND content CONTAINS('error'), "ERROR")) |
Пример данных лога
{
"log.source": "using", "timestamp": "1656011002196", "status": "WARN", "content":"Some error message" } |
Результат после преобразования
{
"log.source": "using", "timestamp": "1656011002196", "status": "ERROR", "content":"Some error message" } |
Пример 9: Добавить новый атрибут в текущую структуру событий лога
Команда FIELDS_ADD может использоваться для введения дополнительных атрибутов лога верхнего уровня. Следующий скрипт добавляет два атрибута: первый сохраняет длину, а второй — количество слов в поле содержимого.
Определение правила обработки
FIELDS_ADD(content.length: STRLEN(content), content.words: ARRAY_COUNT(SPLIT(content,"' '"))) |
Пример данных лога
{
"log.source": "new_attributes", "timestamp": "1656010654603", "content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis." } |
Результат после преобразования
{
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis.", "timestamp": "1656010654603", "log.source": "new_attribute", "content.length": "62", "content.words": "9" } |
Пример 10: Базовые математические вычисления по атрибутам
Благодаря всем доступным функциям и операторам выполнять вычисления легко.
В следующем примере мы анализируем значения total
и failed
, вычисляем процент неудач и объединяем значение со знаком процента. Затем мы сохраняем его в новом атрибуте с именем failed.percentage
и удаляем временные поля.
Определение правила обработки
PARSE(content,"LD 'total: ' INT:total '; failed: ' INT:failed")
| FIELDS_ADD(failed.percentage: 100.0 * failed / total + '%') | FIELDS_REMOVE(total, failed) |
Пример данных лога
{
"timestamp": "1656011338522", "content":"Lorem ipsum total: 1000; failed: 250" } |
Результат после преобразования
{
"content": "Lorem ipsum total: 1000; failed: 250", "timestamp": "1656011338522", "failed.percentage": "25.0%" } |
Пример 11: Удаление определенного атрибута из сообщения лога
Чтобы удалить атрибут события, являющийся частью исходной записи, нам сначала нужно объявить его как INOUT
поле ввода с возможностью записи (опция) с помощью команды USING
, а затем явно удалить его с помощью команды FIELDS_REMOVE
, чтобы он не присутствовал в выходных данных преобразования.
В следующем примере мы объявляем тип redundant.attribute
обязательным записываемым атрибутом STRING
, а затем удаляем его.
Определение правила обработки
USING(INOUT redundant.attribute:STRING)
| FIELDS_REMOVE(redundant.attribute) |
Пример данных лога
{
"redundant.attribute": "value", "timestamp": "1656011525708", "content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac neque nisi. Nunc accumsan sollicitudin lacus." } |
Результат после преобразования
{
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac neque nisi. Nunc accumsan sollicitudin lacus.", "timestamp": "1656011525708" } |
Мы могли бы использовать этот ?
символ, чтобы пометить атрибут как необязательный, чтобы преобразование все равно выполнялось и было успешным, даже если атрибут отсутствует в исходном событии.
В этом случае определение будет выглядеть так
USING(INOUT redundant.attribute:STRING?)
| FIELDS_REMOVE(redundant.attribute) |
Пример 12: Удалить все событие лога
Все событие лога может быть удалено с помощью команды FILTER_OUT
. Событие удаляется, когда выполняется условие, переданное в качестве параметра команды.
- Отбрасывание на основе прематчера - В большинстве случаев достаточно отбросить каждое событие, которое было предварительно сопоставлено. Например, если мы хотим удалить все события
DEBUG
иTRACE
, мы можем настроить запрос сопоставления на соответствие любому из этих статусов, а затем использовать командуFILTER_OUT
для перехвата всего. Соответствие {| class="wikitable" |status="DEBUG" or status="TRACE" |}
Определение правила обработки {| class="wikitable" |FILTER_OUT(true) |}
Пример данных лога {| class="wikitable" |{ "content":"2022-06-23 06:52:35.280 UTC INFO My monitored service call took 97ms" } |}
Таким образом, все логи со статусомDEBUG
илиTRACE
удаляются. - Расширенное условие отбрасывания Также можно использовать дополнительную логику и не отбрасывать все предварительно сопоставленные события. В следующем примере мы отбрасываем входящие события, время выполнения которых составляет менее 100 мс. Пример данных лога {| class="wikitable" |{ "content":"2022-06-23 06:52:35.280 UTC INFO My monitored service call took 97ms" } |}
Определение правила обработки {| class="wikitable" |PARSE(content, "LD 'My monitored service call took ' INT:took 'ms'") | FILTER_OUT(took < 100) | FIELDS_REMOVE(took) |}
Пример 13: Маскировка любого атрибута
Всякий раз, когда содержимое или любой другой атрибут должен быть изменен, он должен быть объявлен как INOUT
(записываемый) с помощью команды USING
. REPLACE_PATTERN
- Это очень мощная функция, которая может быть полезна, когда мы хотим замаскировать некоторую часть атрибута.
- В следующем примере мы маскируем IP-адрес, устанавливая значение 0 для последнего октета. Определение правила обработки {| class="wikitable" |USING(INOUT ip) | FIELDS_ADD(ip: IPADDR(ip) & 0xFFFFFF00l) |}
Пример данных лога {| class="wikitable" |{ "content":"Lorem ipsum", "timestamp": "1656009021053", "ip": "192.168.0.12" } |}
Результат после преобразования {| class="wikitable" |{ "content": "Lorem ipsum", "timestamp": "1656009021053", "ip": "192.168.0.0" } |} - В следующем примере мы маскируем IP-адрес, устанавливая значение
xxx
последнего отчета. Определение правила обработки {| class="wikitable" |USING(INOUT ip) | FIELDS_ADD(ip: REPLACE_PATTERN(ip, "(INT'.'INT'.'INT'.'):not_masked INT", "${not_masked}xxx")) |}
Пример данных лога {| class="wikitable" |{ "content":"Lorem ipsum", "timestamp": "1656009021053", "ip": "192.168.0.12" } |}
Результат после преобразования {| class="wikitable" |{ "content": "Lorem ipsum", "timestamp": "1656009021053", "ip": "192.168.0.xxx" } |} - В следующем примере мы маскируем весь адрес электронной почты, используя
sha1
(алгоритм защищенного хэширования) Определение правила обработки {| class="wikitable" |USING(INOUT email) | FIELDS_ADD(email: REPLACE_PATTERN(email, "LD:email_to_be_masked", "${email_to_be_masked|sha1}")) |}
Пример данных лога {| class="wikitable" |{ "content":"Lorem ipsum", "timestamp": "1656009924312", "email": "john.doe@astromkey.com" } |}
Результат после преобразования {| class="wikitable" |{ "content": "Lorem ipsum", "timestamp": "1656009924312", "email": "9940e79e41cbf7cc452b137d49fab61e386c602d" } |} - В следующем примере мы скрываем IP-адрес, адрес электронной почты и номер кредитной карты из поля содержимого. Определение правила обработки {| class="wikitable" |USING(INOUT content) | FIELDS_ADD(content: REPLACE_PATTERN(content, " (LD 'ip: '):p1 // Lorem ipsum ip: (INT'.'INT'.'INT'.'):ip_not_masked // 192.168.0. INT // 12 ' email: ':p2 // email: LD:email_name '@' LD:email_domain // john.doe@astromkey.com ' card number: ': p3 // card number: CREDITCARD:card // 4012888888881881 ", "${p1}${ip_not_masked}xxx${p2}${email_name|md5}@${email_domain}${p3}${card|sha1}")) |}
Пример данных лога {| class="wikitable" |{ "timestamp": "1656010291511", "content": "Lorem ipsum ip: 192.168.0.12 email: john.doe@astromkey.com card number: 4012888888881881 dolor sit amet" } |}
Результат после преобразования {| class="wikitable" |{ "content": "Lorem ipsum ip: 192.168.0.xxx email: abba0b6ff456806bab66baed93e6d9c4@astromkey.com card number: 62163a017b168ad4a229c64ae1bed6ffd5e8fb2d dolor sit amet", "timestamp": "1656010291511" } |}
Пример 14: Переименование атрибутов
С помощью команды FIELDS_RENAME
мы можем переименовывать атрибуты, которые были частью исходного события лога, и атрибуты, созданные в процессоре. Всякий раз, когда мы хотим изменить любой атрибут исходного события, нам нужно объявить его как INOUT
(записываемый).
В следующем примере мы переименовываем существующий атрибут. Кроме того, мы извлекаем поле из JSON в плоском режиме и переименовываем новый атрибут, который был создан автоматически с именем поля JSON.
Определение правила обработки
USING(INOUT to_be_renamed, content)
| FIELDS_RENAME(better_name: to_be_renamed) | PARSE(content,"JSON{STRING:json_field_to_be_renamed}(flat=true)") | FIELDS_RENAME(another_better_name: json_field_to_be_renamed) |
Пример данных лога
{
"timestamp": "1656061626073", "content":"{\"json_field_to_be_renamed\": \"dolor sit amet\", \"field2\": \"consectetur adipiscing elit\"}", "to_be_renamed": "Lorem ipsum" } |
Результат после преобразования
{
"content": "{\"json_field_to_be_renamed\": \"dolor sit amet\", \"field2\": \"consectetur adipiscing elit\"}", "timestamp": "1656061626073", "better_name": "Lorem ipsum", "another_better_name": "dolor sit amet" } |
Пример 15: Типы данных поля ввода
Скрипт в определении процессора работает со строго типизированными данными: функции и операторы принимают только объявленные типы данных. Тип назначается всем входным полям, определенным в команде USING
, а также переменным, созданным при разборе или использовании функций приведения.
Определение правила обработки
USING(number:INTEGER, avg:DOUBLE, addr:IPADDR, arr:INTEGER[],bool:BOOLEAN, ts:TIMESTAMP)
| FIELDS_ADD(multi:number*10) | FIELDS_ADD(avgPlus1:avg+1) | FIELDS_ADD(isIP: IS_IPV6(addr)) | FIELDS_ADD(arrAvg: ARRAY_AVG(arr)) | FIELDS_ADD(negation: NOT(bool)) | FIELDS_ADD(tsAddYear: TIME_ADD_YEAR(ts,1)) |
Пример данных лога
{
"content":"Lorem ipsum", "number":"5", "avg":"123.5", "addr":"2a00:1450:4010:c05::69", "arr": ["1","2"], "bool":"false", "ts":"1984-11-30 22:19:59.789 +0000" } |
Результат после преобразования
{
"content": "Lorem ipsum", "number": "5", "avg": "123.5", "addr": "2a00:1450:4010:c05::69", "arr": [ "1", "2" ], "bool": "false", "ts": "1984-11-30 22:19:59.789 +0000", "tsAddYear": "1985-11-30T22:19:59.789000000 +0000", "negation": "true", "arrAvg": "1.5", "isIP": "true", "avgPlus1": "124.5", "multi": "50" } |