Телеметрия и наблюдаемость в dbt v2
dbt v2 предоставляет комплексную систему наблюдаемости, которая заменяет структурированное журналирование dbt v1. Эта система основана на соглашениях OpenTelemetry и стабильной схеме protobuf и обеспечивает глубокую интеграцию с оркестраторами, платформами наблюдаемости и пользовательскими инструментами.
Общие настройки журналирования CLI, такие как --log-format и --log-level, описаны в разделе Журналы.
Эта система не связана с анонимной статистикой использования, которую dbt отправляет в dbt Labs. О настройке анонимной статистики использования см. раздел Анонимная статистика использования.
Здесь используется та же интеграция, на которую опирается dbt platform для оркестрации и мониторинга, что обеспечивает проверенные, готовые к промышленной эксплуатации возможности, работающие при больших масштабах.
Доступные форматы вывода
Телеметрия dbt v2 поддерживает три формата вывода, которые можно включать независимо друг от друга:
| Формат | Сценарий использования | Доступность |
|---|---|---|
| JSONL | Мониторинг в реальном времени, потоковая передача в последующие системы. | Записывается по мере возникновения событий. |
| Parquet | Анализ после выполнения, запросы и долгосрочное хранение. | Записывается по завершении запусков. |
| OTLP | Интеграция с платформами наблюдаемости (Datadog, Jaeger и другими). | Передаётся потоком в реальном времени. |
Включение вывода телеметрии
Ниже приведены примеры включения вывода телеметрии (в одном запуске можно объединить несколько вариантов вывода):
Запись JSONL в файл (сохраняется в каталоге logs/):
dbtf build --otel-file-name telemetry.jsonl
Потоковый вывод JSONL в stdout:
dbtf build --log-format otel
Запись файла Parquet (сохраняется в каталоге target/metadata/):
dbtf build --otel-parquet-file-name telemetry.parquet
Запись файла Parquet с полными журналами уровня trace (рекомендуется для отладки):
dbtf build --log-level-file trace --otel-parquet-file-name telemetry.parquet
Экспорт в коллектор OpenTelemetry:
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318" dbtf build --export-to-otlp
Скачивание телеметрии запусков заданий на платформе
На dbt platform запуски заданий dbt v2 сохраняют телеметрию OTel в виде артефактов Parquet для шагов с командами dbt. Откройте вкладку Run summary завершённого запуска, выберите шаг и нажмите Download > Download OTel log. Этот пункт появляется только для запусков dbt v2, в которых шаг создал файл OTel. Пошаговые инструкции приведены в разделе Скачивание журналов.
Получение телеметрии через API
Артефакт OTel в формате Parquet для шага запуска также можно получить через dbt Administrative API v2, который позволяет скачивать артефакты после завершения задания. Используйте эту возможность, чтобы автоматизировать загрузку результатов выполнения узлов и тестов в последующую систему, например во фреймворк контроля качества данных в вашем хранилище.
Каждый шаг с командой dbt v2, который создаёт телеметрию, записывает артефакт telemetry-STEP_NUMBER-otel.parquet. Некоторые шаги, например dbt deps, не создают артефакт Parquet.
Для получения этого артефакта можно использовать конечную точку Retrieve Run Artifact:
GET https://YOUR_ACCESS_URL/api/v2/accounts/ACCOUNT_ID/runs/RUN_ID/artifacts/metadata/telemetry-STEP_NUMBER-otel.parquet?step=STEP_NUMBER
Замените YOUR_ACCESS_URL на URL доступа для вашего региона и тарифного плана, а ACCOUNT_ID, RUN_ID, STEP_NUMBER — на свои значения. Для аутентификации используйте токен служебной учётной записи или персональный токен доступа.
Например, это можно сделать с помощью curl:
curl --request GET \
--url 'https://YOUR_ACCESS_URL/api/v2/accounts/12345/runs/67890/artifacts/metadata/telemetry-4-otel.parquet?step=4' \
--header 'Authorization: Token YOUR_TOKEN' \
--output telemetry-4-otel.parquet
Чтобы определить, какой шаг создал нужный артефакт телеметрии, получите список шагов запуска, включив run_steps в запрос сведений о запуске:
GET https://YOUR_ACCESS_URL/api/v2/accounts/ACCOUNT_ID/runs/RUN_ID/?include_related=["run_steps"]
Этот артефакт можно получить только для шагов dbt v2, которые сформировали журнал OTel.
Данные телеметрии
Телеметрия dbt v2 содержит два типа записей:
- Спаны — операции со временем начала и окончания (например, компиляция модели или выполнение теста).
- Записи журнала — события в определённый момент времени внутри спана.
Иерархия телеметрии
Каждая команда dbt создаёт иерархию спанов:
Invocation (dbtf build)
├── Phase (Parse)
├── Phase (Compile)
│ ├── Node (model.project.customers)
│ └── Node (model.project.orders)
└── Phase (Run)
├── Node (model.project.customers)
└── Node (model.project.orders)
Значение trace_id (также известное как invocation_id) остаётся одинаковым во всех записях телеметрии для одной команды dbt, что упрощает сопоставление событий.
Результат выполнения узла
Каждый узел формирует результат для каждой фазы, в которой он участвует. Некоторые фазы, например parse, не предусматривают выполнение на уровне узлов, поэтому для них не создаются спаны узлов или результаты выполнения узлов.
Поле node_outcome указывает, выполнил ли dbt v2 операцию узла.
| Результат | Описание |
|---|---|
success | Операция узла завершена без ошибок. |
error | Не удалось выполнить операцию узла (например, из-за синтаксической ошибки). |
skipped | Узел не обрабатывался (см. причины пропуска). |
canceled | Выполнение узла прервано (например, пользователь нажал Ctrl+C). |
Причины пропуска
Когда dbt v2 пропускает узел, в телеметрию включается причина:
| Причина пропуска | Описание |
|---|---|
upstream | Ошибка при выполнении зависимости. |
cached | dbt v2 повторно использовал результаты из кеша (изменения не обнаружены с помощью dbt State). |
phase_disabled | Фаза была отключена (например, с помощью --static-analysis off). |
noop | Узел не выполняет работу в этой фазе (например, эфемерные модели). |
Результаты тестов
Когда тест успешно выполняется (node_outcome: success), он сообщает результат проверки:
| Результат теста | Описание |
|---|---|
passed | Нарушений не обнаружено. |
warned | Обнаружены нарушения, но они настроены как предупреждения. |
failed | Обнаружены нарушения (проблема качества данных). |
Тест с node_outcome: success и test_outcome: failed означает, что dbt v2 успешно выполнил тест и тест сообщил о проблемах качества данных. Это отличается от node_outcome: error, который означает, что сам тест не удалось выполнить (например, из-за некорректного SQL).
Запросы к данным телеметрии
Выполняйте запросы к данным телеметрии, чтобы глубже анализировать запуски dbt.
Примеры для JSONL
Ниже приведены примеры запросов к данным телеметрии в формате JSONL.
Отслеживание ошибок в реальном времени:
tail -f telemetry.jsonl | jq 'select(.severity_text == "ERROR")'
Вывод пропущенных узлов, причин пропуска и сведений о предшествующих узлах:
cat telemetry.jsonl | jq 'select(.attributes.node_outcome == "NODE_OUTCOME_SKIPPED") | {node: .attributes.unique_id, reason: .attributes.node_skip_reason, upstream: .attributes.node_skip_upstream_detail.upstream_unique_id }'
Скачивание телеметрии с платформы dbt
Если вы запускали задание на dbt platform, артефакт OpenTelemetry (OTEL) в формате Parquet можно скачать со страницы запуска через раскрывающееся меню Download. В скачиваемые данные входит файл telemetry-<step>-otel.parquet для каждого шага запуска.
Анализ Parquet с помощью DuckDB
Используйте DuckDB, чтобы лучше разобраться в данных телеметрии, хранящихся в файлах Parquet.
Поиск самых медленных узлов по затратам времени на обработку (а не по полному времени существования с учётом ожидания допуска по лимиту подключений):
import duckdb
duckdb.sql("""
SELECT
attributes.unique_id,
attributes.duration_ms,
attributes.idle_time_ms
FROM 'telemetry.parquet'
WHERE event_type LIKE '%NodeProcessed%'
AND attributes.duration_ms IS NOT NULL
ORDER BY attributes.duration_ms DESC
LIMIT 10
""").show()
Телеметрия предоставляет несколько способов измерения производительности узлов:
- Время обработки (
attributes.duration_ms) измеряет время, которое v2 затратил на активную обработку узла, включая вложенную работуNodeEvaluated. Оно не включает время ожидания предшествующих узлов или задержки из-за внутреннего механизма ограничения нагрузки. Используйте эту метрику для поиска узлов, обработка которых занимает больше всего времени. - Время существования узла (
end_time_unix_nano - start_time_unix_nano) измеряет полное время от начала до конца спана, включая ожидание допуска по лимиту подключений. При сборках с полной загрузкой потоков эта метрика может показывать узлы с самым долгим ожиданием в очереди, а не с наибольшим объёмом обработки. - Время простоя (
attributes.idle_time_ms) измеряет, сколько времени узел провёл в ожидании, а не в активной обработке, например в ожидании предшествующего узла или свободных вычислительных ресурсов. Используйте эту метрику, чтобы определить, где ограничения ресурсов вызывают задержки. - Время выполнения в хранилище — это сумма длительностей спанов
QueryExecutedдля каждогоunique_id. Оно не включает работу на стороне v2, такую как компиляция и статический анализ. Используйте эту метрику для сравнения телеметрии с историей запросов в хранилище.
Поиск узлов с наибольшим временем выполнения в хранилище (необязательно):
duckdb.sql("""
SELECT
attributes.unique_id,
SUM((end_time_unix_nano - start_time_unix_nano) / 1e6) AS warehouse_ms
FROM 'telemetry.parquet'
WHERE event_type LIKE '%QueryExecuted%'
GROUP BY attributes.unique_id
ORDER BY warehouse_ms DESC
LIMIT 10
""").show()
Подсчёт результатов по типам:
duckdb.sql("""
SELECT
attributes.node_outcome,
COUNT(*) as count
FROM 'telemetry.parquet'
WHERE attributes.node_outcome IS NOT NULL
GROUP BY attributes.node_outcome
""").show()
Веб-инструменты для просмотра Parquet
Для разового анализа без локальной установки веб-инструменты просмотра Parquet (например, PondPilot) позволяют загрузить файл Parquet и выполнять SQL-запросы в браузере. Некоторые инструменты поддерживают генерацию запросов с помощью LLM, чтобы упростить изучение незнакомой схемы.
Интеграция с OpenTelemetry
Встроенная поддержка OTLP в dbt v2 позволяет отправлять телеметрию напрямую в любой приёмник, совместимый с OpenTelemetry, включая Datadog, Jaeger, Google Cloud Trace, Grafana Tempo и Honeycomb.
Это обеспечивает:
- Интеграцию с существующей системой наблюдаемости — без разработки собственных интеграций.
- Настраиваемые оповещения, отправляющие уведомления при сбоях или медленных сборках.
- Сопоставление данных между системами, связывающее трассировки dbt с последующими сервисами.
- Централизованный мониторинг для наблюдения за dbt вместе с остальной инфраструктурой.
Настройка экспорта OTLP
В следующем примере настраивается экспорт OTLP:
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
dbtf build --export-to-otlp
Соответствие понятиям dbt v1
Если вы знакомы со структурированным журналированием dbt v1, ниже показано, как ему соответствует телеметрия dbt v2:
| dbt v1 | Телеметрия dbt v2 |
|---|---|
invocation_id | trace_id (то же значение, другой формат) |
Статус в run_results.json | node_outcome + skip_reason или test_outcome |
code события (например, Q001) | event_type |
--log-format json | --log-format otel или --otel-file-name |
Соответствие статусов узлов
| Статус dbt v1 | Результат dbt v2 |
|---|---|
success | node_outcome: success |
error | node_outcome: error |
skipped | node_outcome: skipped, skip_reason: upstream |
pass (тесты) | node_outcome: success, test_outcome: passed |
warn (тесты) | node_outcome: success, test_outcome: warned |
fail (тесты) | node_outcome: success, test_outcome: failed |
Обратите внимание: статус fail в dbt v1 соответствует node_outcome: success в dbt v2, поскольку dbt v2 различает ситуации «тест успешно выполнился и обнаружил проблемы с данными» и «тест не удалось выполнить». Такое разделение позволяет точнее настраивать оповещения и логику повторных попыток.
dbt v2 добавляет skip_reason: cached для узлов, результаты которых повторно используются через dbt State; в dbt v1 аналога этому нет.
dbt State работает со всеми движками и средами: dbt v1, dbt platform и dbt v2
Если вы использовали оркестрацию с учетом состояния до 1 июня 2026 года, вы можете продолжать ее использовать. Когда вы начнете бесплатный пробный период dbt State, он будет продлен сверх стандартных 30 дней. Если продление не применено к вашей учетной записи, обратитесь к команде по работе с вашим аккаунтом. Чтобы начать, ознакомьтесь с разделом Переход с оркестрации с учетом состояния.
Структура записи
Каждая запись телеметрии содержит общие поля и специфичные для события attributes:
{
"record_type": "SpanEnd",
"trace_id": "f9a0a9e64c924b878133363ba3515e50",
"span_id": "0000000000000036",
"span_name": "Node(model.project.customers)",
"parent_span_id": "0000000000000017",
"start_time_unix_nano": "1756139116981079652",
"end_time_unix_nano": "1756139117234567890",
"severity_text": "INFO",
"event_type": "v1.public.events.fusion.node.NodeEvaluated",
"attributes": {
"unique_id": "model.project.customers",
"phase": "Run",
"node_outcome": "success"
}
}
| Поле | Описание |
|---|---|
record_type | SpanStart, SpanEnd или LogRecord |
trace_id | Уникальный идентификатор вызова (те же данные, что и в invocation_id, но в формате OTEL). |
span_id / parent_span_id | Для восстановления иерархии спанов. |
event_type | Идентификатор типа для фильтрации и разбора. |
attributes | Данные, специфичные для события (схема зависит от типа события, но, в отличие от соглашений OTEL, строго определяется стабильной схемой protobuf). |
Стабильность схемы
В отличие от структурированного журналирования dbt v1, телеметрия dbt v2 основана на общедоступной схеме protobuf со строгими гарантиями совместимости:
- Только добавления — могут добавляться новые поля и типы событий, но существующие поля никогда не удаляются и не изменяются.
- Совместимость с будущими версиями — ваши интеграции продолжат работать по мере развития схемы.
Это делает телеметрию dbt v2 надёжной основой для интеграций в промышленной эксплуатации, оркестраторов и долгосрочных аналитических конвейеров.
Официальная клиентская библиотека
dbt Labs предоставляет официальную клиентскую библиотеку с открытым исходным кодом. Для высокой производительности она написана на Rust и доступна в виде:
- Отдельного крейта Rust и CLI (
dbt-telemetry-export-cli). - Полностью типизированного пакета Python, оборачивающего ядро на Rust и устанавливаемого с помощью
uv tool install.
Библиотека предоставляет типобезопасный доступ к данным телеметрии с совместимостью с будущими версиями. Обрабатывайте поток JSONL в реальном времени, выполняйте запросы к файлам Parquet и создавайте собственные интеграции, будучи уверенными, что изменения схемы не нарушат работу вашего кода.
Мы объявим о публичном выпуске в ближайшее время.