Оголошення про підтримку комплексних типів атрибутів в OTel
У телеметрії зазвичай використовуються прості властивості типу «ключ-значення» як атрибути. Більшість телеметричних бекендів оптимізовані для цього шаблону, що робить зберігання, індексування та отримання даних ефективним.
OpenTelemetry розроблено з урахуванням цього. Семантичні домовленості та інструментування спрямовані на те, щоб надати корисні атрибути, які можна легко фільтрувати та агрегувати.
Але що відбувається, коли самі дані є комплексними? OpenTelemetry також прагне забезпечити спостережуваність для реальних систем, бібліотек та застосунків, спостережувані властивості яких іноді є комплексними.
Нещодавно OpenTelemetry оголосив про майбутню підтримку збирання комплексних даних у всіх сигналах OTel, починаючи з OTLP 1.9.0, а в майбутньому — у версіях OpenTelemetry API та SDK в усій екосистемі.
У цій публікації ми розглянемо, коли і як використовувати комплексні дані, коли їх уникати та як бекенди можуть почати їх підтримувати.
Майбутня підтримка комплексних типів атрибутів в OpenTelemetry
API та SDK OpenTelemetry додають підтримку наступних типів атрибутів для всіх сигналів:
- Асоціативні масиви (Maps) (з рядковими ключами та значеннями будь-якого підтримуваного типу)
- Гетерогенні масиви (що містять елементи будь-якого підтримуваного типу)
- Байтові масиви
- Порожні значення
Донедавна ці типи підтримувалися лише в логах — атрибути в інших сигналах були обмежені примітивами та масивами примітивів.
Відповідно до OTEP 4485: Розширення атрибутів для підтримки комплексних значень та його реалізації в OTLP і специфікації, ця підтримка поширюється на всі сигнали OTel.
Нові типи атрибутів, особливо maps і гетерогенні масиви, слід використовувати з обережністю. Багато бекендів спостережуваності не оптимізовані для запиту, індексації або агрегації комплексних атрибутів. Семантичні домовленості передбачають, що комплексні атрибути не індексуються, і уникають їх використання в метриках або в інших сценаріях, де ефективні запити мають велике значення.
По можливості дотримуйтесь примітивних значень.
Чому ми це робимо?
Працюючи над семантичними домовленостями та інструментами, ми все частіше стикаємося з випадками, коли прості атрибути не можуть адекватно відобразити складність реальних сценаріїв.
Приклади:
- Операції LLM — вхідні параметри, такі як визначення інструментів та вхідні/вихідні повідомлення, мають вбудовану структуру
- GraphQL — відповіді можуть містити списки структурованих помилок
- Операції з базами даних — пакетні операції мають властивості, які прості атрибути не можуть адекватно відобразити
Перш ніж розширити підтримку комплексних атрибутів на всі сигнали, ми розглянули кілька альтернатив:
Обмеження підтримки логами (та відрізками)
Наявність різних типів збору атрибутів для різних сигналів впливає на ергономіку API, роблячи роботу з атрибутами менш зручною та ефективною.
Спрощення
Спрощення добре працює для map примітивних типів, але не працює для масивів. Наприклад, структуровані дані, такі як:
{
"data": [
{
"foo": "bar",
"baz": 42
}
]
}
подається як:
data.0.foo = "bar"
data.0.baz = 42
або:
data.foo = ["bar"]
data.baz = [ 42 ]
Обидва підходи мають обмеження і призводять до погіршення якості роботи користувачів.
Серіалізація рядків
Інший варіант — вимагати від користувачів або інструментів серіалізувати комплексні дані в рядки. Хоча це можливо, але існує ризик виникнення невідповідностей та помилок. Це також обмежує можливості постобробки та призводить до неефективних стратегій обрізання. В решті-решт, рішення про збереження структури або серіалізацію даних має приймати бекенд. Обробка серіалізації на стороні бекенду забезпечує більшу узгодженість та зручність для кінцевих користувачів.
Як бекенди повинні підтримувати комплексні атрибути?
Ми заохочуємо бекенди вибудовувати взаємодію з користувачами, яка використовує структуровані значення атрибутів, дозволяючи користувачам запитувати дані на основі вкладених властивостей.
Тим часом ми рекомендуємо бекендам серіалізувати комплексні атрибути в JSON (або інший відповідний формат) під час збору даних.
Специфікація OTel, семантичні домовленості та документація API чітко повідомлять авторам інструментувань, що підтримка комплексних атрибутів може бути обмеженою, і ми продовжуватимемо рекомендувати використовувати прості атрибути, коли це можливо.
Коли слід використовувати комплексні атрибути?
Якщо дані можна адекватно виразити за допомогою простих атрибутів, використовуйте їх.
Комплексні атрибути слід використовувати лише в тому випадку, якщо дані занадто комплексні, щоб виразити їх за допомогою простих атрибутів, наприклад, під час запису списків комплексних обʼєктів.
Що стосується семантичних домовленостей та бібліотек інструментування, ми не рекомендуємо змінювати будь-що з того, що вже існує, у відповідь на це оголошення. Це повинно вплинути лише на нові функції, які вимагають використання комплексних атрибутів.
Коментарі?
Ми відкрили GitHub issue для обговорення цього допису і будемо раді отримати ваші відгуки.