Зменшення обсягу журналів за допомогою процесора дедуплікації журналів OpenTelemetry

Ваші журнали, ймовірно, на 80% складаються з повторюваного шуму. Повторні спроби підключення, перевірки стану, повідомлення про пульс: один і той самий рядок журналу повторюється тисячі разів на хвилину. Ви платите за зберігання кожного з них, а сигнал губиться в шумі. Процесор дедуплікації журналів OpenTelemetry Collector пропонує елегантне рішення цієї проблеми.
Проблема із повторюваними записами
Сучасні розподілені системи генерують величезні обсяги логів, але значна частина цих записів дає все менший ефект. Розглянемо типовий мікросервіс, який реєструє помилки підключення, коли підлеглий рівень залежності недоступний. Якщо сервіс повторює спробу кожні 100 мілісекунд протягом 30 секунд, це означає 300 майже ідентичних записів у лозі для одного інциденту. Кожен запис споживає памʼять, ресурси мережі та обчислювальну потужність вашого сервера.
Точки перевірки працездатності ускладнюють проблему. Проби Kubernetes, перевірки балансувальника навантаження та системи моніторингу генерують записи в журналі з регулярними інтервалами. Один сервіс може реєструвати тисячі відповідей на перевірку працездатності на годину, жодна з яких не надає значущої інформації, окрім «сервіс працював».
Logdedupprocessor в OpenTelemetry Collector вирішує цю проблему, агрегуючи ідентичні логи протягом настроюваного часового вікна. Замість того, щоб пересилати кожен дублікат запису, він створює один запис з кількістю повторень цього повідомлення.
Як працює дедуплікація журналів
Основна концепція є досить простою. Журнали вважаються ідентичними, якщо вони мають однакові атрибути ресурсу, область дії, тіло, атрибути, рівень важливості та назву події. Варто зазначити, що час створення не враховується під час перевірки ідентичності, оскільки він, природно, відрізняється для кожного запису в журналі. Порядок атрибутів не впливає на ідентичність. Процесор обчислює хеш цих полів і відстежує їх появу протягом заданого інтервалу.
Коли інтервал закінчується, процесор видає один запис журналу з трьома додатковими атрибутами: log_count (кількість дублікатів), first_observed_timestamp та last_observed_timestamp. Ви зберегти повну видимість у патернах частоти без збереження кожного однакового запису.
Цей підхід істотно відрізняється від вибірки. Вибірка остаточно видаляє дані. Дедуплікація зберігає важливу інформацію (що сталося, як часто і коли), одночасно усуваючи збереження надлишкових даних.
Практична конфігурація
Ось конфігурація, яка видаляє дублікати помилок підключення, зберігаючи журнали аудиту:
processors:
logdedup:
interval: 1s
conditions:
- severity_number >= SEVERITY_NUMBER_ERROR
- attributes["log.type"] == "connection"
exclude_fields:
- attributes.request_id
- attributes.timestamp
Поле conditions використовує вирази OpenTelemetry Transformation Language (OTTL) для фільтрування журналів, які підлягають дедуплікації. Журнали, які не відповідають критеріям, проходять без змін. У цьому прикладі тільки журнали рівня ERROR з атрибутом log.type=connection є кандидатами для дедуплікації.
Опція exclude_fields видаляє поля з високою кардинальністю з порівняння. Поля, такі як ідентифікатори запитів і часові мітки, відрізняються між записами, навіть якщо повідомлення журналу семантично ідентичні. Після їх виключення журнали, що відрізняються тільки цими мінливими полями, розглядаються як дублікати.
Повний приклад конвеєра
Щоб використовувати процесор дедуплікації журналів, включіть його до конвеєра Collector:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
logdedup:
interval: 1s
conditions:
- severity_number >= SEVERITY_NUMBER_ERROR
- attributes["log.type"] == "connection"
exclude_fields:
- attributes.request_id
- attributes.timestamp
exporters:
otlp:
endpoint: your-backend:4317
service:
pipelines:
logs:
receivers: [otlp]
processors: [logdedup]
exporters: [otlp]
Тестування за допомогою telemetrygen
Щоб протестувати цю конфігурацію локально, використовуйте telemetrygen для генерації журналів помилок підключення:
telemetrygen logs \
--otlp-insecure \
--logs 100 \
--rate 10 \
--severity-text ERROR \
--severity-number 17 \
--body "Connection refused: failed to connect to database at 10.0.0.5:5432" \
--telemetry-attributes 'log.type="connection"' \
--telemetry-attributes 'service.name="order-service"' \
--telemetry-attributes 'db.system="postgresql"'
В результаті створюється 100 записів журналу зі швидкістю 10 на секунду, всі з рівнем критичності ERROR і атрибутом log.type=connection, який запускає дедуплікацію. Через кілька секунд у вашому бекенді ви побачите кілька записів журналу з log_count: N замість 100 окремих записів.
Компроміси та рекомендації
Процесор дедуплікації журналів вносить затримку, рівну встановленому інтервалу. Журнали зберігаються до закінчення інтервалу, після чого передаються далі. У більшості випадків затримка в 1 секунду є прийнятною, але для систем оповіщення в режимі реального часу може знадобитися коригування.
Для журналів, критичних з точки зору відповідності, де кожна подія повинна зберігатися з оригінальним часовим відбитком, пропустіть дедуплікацію повністю. Журнали аудиту, події безпеки та регуляторні записи часто вимагають повної точності.
Компроміс простий: зменшення обсягу зберігання та чіткіший сигнал за рахунок невеликої затримки та втрати окремих часових відбитків. Для повторюваних журналів з великим обсягом цей компроміс зазвичай є виправданим.
Висновок
Процесор дедуплікації журналів забезпечує практичне рішення проблеми шуму в сучасних конвеєрах журналів. Агрегуючи ідентичні записи та зберігаючи інформацію про частоту, ви можете значно зменшити витрати на зберігання та поліпшити чіткість сигналу без втрати спостережуваності.
У поєднанні з іншими процесорами OpenTelemetry Collector, такими як фільтрування та вибірка, дедуплікація журналів дає вам можливість детально контролювати ваш конвеєр телеметрії. Результатом є система логування, яка фіксує все важливе, відкидаючи шум.