Как превратить тысячи лог-групп в десятки с помощью Grok-паттернов

от автора

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

User browsing product TSLA   → группа #1User browsing product AAPL   → группа #2User browsing product MSFT   → группа #3

Один и тот же код, одна и та же логика — триста разных групп. Алерты бесполезны, анализ ошибок превращается в ручную работу.

Решение — grouping rules: правила, которые нормализуют сообщения до их группировки и извлекают переменные части как структурированные атрибуты. Никакого изменения кода приложения, никакой реинструментации.

В этой статье разберём синтаксис, все доступные типы и практические кейсы на примере Uptrace — OpenTelemetry-native APM с поддержкой трейсов, метрик и логов.

Синтаксис паттернов

Паттерн — это фиксированные слова вперемешку с плейсхолдерами

Фиксированные слова совпадают как есть:

error connecting to database

Плейсхолдеры находят переменные части по типу:

%{INT:status_code}     → целое число, сохраняется как атрибут "status_code"%{UUID}                → UUID, значение отбрасывается%{IP:remote_addr}      → IP-адрес, сохраняется как "remote_addr"%{LOG_LEVEL:severity}  → INFO / WARN / ERROR и т.д.

Формат: %{TYPE} без захвата, или %{TYPE:имя} с захватом значения в атрибут.

Паттерн для примера выше:

User browsing product %{IDENT:product}

Результат: одна группа вместо трёхсот, атрибут product на каждом событии — доступен для фильтрации, агрегации и алертов.

Доступные типы

Категория

Типы

Текст

IDENT, WORD, QUOTED, ANY, ANY+

Числа

INT, FLOAT, BYTE_SIZE, NUMBER

Сеть

IP, URI, EMAIL, HOST_PORT

Система

LOG_LEVEL, HTTP_STATUS, HTTP_METHOD, UUID

Время

TIMESTAMP, DATE, TIME

Структура

JSON, ATTR (key=value пары)

NUMBER и IP — виртуальные типы, они автоматически расширяются до всех подтипов. ANY+ захватывает один или несколько токенов любого типа, что удобно для переменных хвостов сообщения.

Полный справочник типов: uptrace.dev/features/logs/grouping

Извлечение атрибутов

Захваченные значения становятся структурированными атрибутами на каждом событии группы. Это открывает полноценную аналитику без изменения кода.

Пример лога корзины:

User a3f2c1d4-... adding 12 of product NVDA to cart

Паттерн:

User %{UUID} adding %{INT:num_products} of product %{IDENT:product} to cart

%{UUID} без имени просто поглощает идентификатор пользователя. num_products и product становятся атрибутами — в Uptrace можно сразу строить график max(num_products) по времени или фильтровать по product=NVDA.

Fingerprinting: отдельная группа на каждое уникальное значение

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

Добавьте # перед именем захвата:

%{IDENT:#function_name} failed

Теперь SendEmail failed и ParseConfig failed — две разные группы, каждая с собственным алертом. Без # они были бы одной группой.

Если имя не нужно — то же самое через опцию:

%{IDENT,fingerprint} failed

Практический пример — PostgreSQL unknown column:

%{LOG_LEVEL:log_severity} column %{QUOTED:#column} does not exist %{ATTR:sqlstate}

Исходные логи:

ERROR: column "event.created_at" does not exist (SQLSTATE=42703)ERROR: column "updated_at" does not exist (SQLSTATE=42703)

Результат: две группы, каждая алертируется независимо. Атрибуты log_severity и sqlstate доступны на каждом событии.

Опция unit: нормализация числовых значений

Если разные сервисы логируют длительности в разных единицах, опция unit нормализует значения автоматически:

%{NUMBER:duration,unit=ms}

Uptrace приводит значение к базовой единице и хранит консистентно, агрегации по сервисам работают без ручных конверсий.

Поддерживаемые единицы: ns, us, ms, s, bytes, kb, mb, gb, %, count, celsius и другие.

Опция extract: regex внутри quoted-строки

Когда лог содержит quoted-сообщение со структурированными данными внутри, опция extract позволяет достать их регулярным выражением:

ERROR %{QUOTED:msg,extract=`(?P<name>\w+) is (?P<age>\d+)`}

На строке ERROR "Alice is 25" правило захватит msg=Alice is 25, name=Alice, age=25. Полезно для легаси-логов, где несколько значений упакованы в одну строку.

Необязательные элементы и альтернативы

Паттерны не обязаны быть жёсткими. Чтобы сделать плейсхолдер необязательным, достаточно добавить ?:

error code %{NUMBER:code}? occurred

Совпадёт с error code 500 occurred и с error code occurred.

Альтернативы через |:

(%{LOG_LEVEL:level}|%{WORD:level}) %{WORD:msg}

Если один и тот же тип ошибки формулируется по-разному в разных сервисах — одно правило, несколько паттернов:

can't find item %{NUMBER:item_id}can not find item %{NUMBER:item_id}%{NUMBER:item_id} not found

Любое совпадение активирует правило.

Программная установка fingerprint

Для случаев, когда паттернов недостаточно, grouping.fingerprint можно выставить напрямую при создании события. Это переопределяет автоматически вычисленный fingerprint:

span.AddEvent("exception", trace.WithAttributes(    attribute.String("exception.type", "*exec.ExitError"),    attribute.String("exception.message", "exit status 1"),    attribute.String("grouping.fingerprint", "exec.ExitError"),))

Когда использовать grouping rules

Подходит:

  • Высококардинальные сообщения с ID, именами, числами внутри

  • Нужны числовые агрегации по лог-данным (длительности, счётчики, размеры)

  • Алертинг на значение — отдельный алерт на каждую падающую функцию или неизвестную колонку

  • Легаси или сторонние логи без возможности реинструментации

Не подходит как замена:

  • Структурированному логированию — если можно эмитить product=TSLA как OpenTelemetry атрибут из приложения, лучше сделать это там

  • Парсерам OpenTelemetry Logs и Vector для сложного разбора форматов

Как это выглядит в Uptrace

В Uptrace grouping rules находятся в разделе Logs & Errors → Grouping Rules. Вставляете сырое лог-сообщение, нажимаете Extract Pattern — система генерирует паттерн автоматически, вы только указываете имена для нужных плейсхолдеров.

Uptrace — OpenTelemetry-native APM для трейсов, метрик и логов. Grouping rules работают как в облачной версии, так и в self-hosted.

ссылка на оригинал статьи https://habr.com/ru/articles/1034152/