For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.
Логирование
Установите OTEL_EXPORT_ENABLED=true для каждого процесса Dynamo. Без этого логи не покинут процесс, и Loki будет молчать независимо от OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.
Обзор
Dynamo поддерживает структурированное логирование как в текстовом формате, так и в JSONL. Когда JSONL включен, логи поддерживают поля trace_id и span_id для распределённой трассировки. События создания и завершения span можно дополнительно включить через переменную окружения DYN_LOGGING_SPAN_EVENTS.
Переменные окружения
| Переменная | Описание | Значение по умолчанию | Пример |
|---|---|---|---|
DYN_LOGGING_JSONL | Включить формат логирования JSONL | false | true |
DYN_LOGGING_SPAN_EVENTS | Включить логирование событий входа и закрытия span (SPAN_FIRST_ENTRY, SPAN_CLOSED) | false | true |
DYN_LOG | Уровни логов для каждого target <default_level>,<module_path>=<level>,<module_path>=<level> | info | DYN_LOG=info,dynamo_runtime::system_status_server:trace |
DYN_LOG_USE_LOCAL_TZ | Использовать локальный часовой пояс для временных меток (по умолчанию UTC) | false | true |
DYN_LOGGING_CONFIG_PATH | Путь к пользовательской TOML-конфигурации логирования | none | /path/to/config.toml |
VLLM_LOGGING_LEVEL | Уровень логирования backend vLLM (независим от DYN_LOG) | INFO | DEBUG |
TLLM_LOG_LEVEL | Уровень логирования backend TensorRT-LLM (независим от DYN_LOG) | INFO | DEBUG |
DYN_SKIP_SGLANG_LOG_FORMATTING | Отключить конфигурацию логирования SGLang в Dynamo | false | true |
OTEL_SERVICE_NAME | Имя сервиса для информации о trace и span | dynamo | dynamo-frontend |
OTEL_EXPORT_ENABLED | Включить экспорт OTLP для трассировок и логов | false | true |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | OTLP gRPC endpoint для трассировок | http://localhost:4317 | http://tempo:4317 |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | OTLP gRPC endpoint для логов (если не задан, используется OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) | как у endpoint трассировок | http://localhost:4317 |
Экспорт OTLP-логов
Когда OTEL_EXPORT_ENABLED=true, Dynamo экспортирует через OTLP и трассировки, и логи. Логи отправляются в OpenTelemetry Collector, который направляет их в Grafana Loki для агрегации и поиска.
По умолчанию логи экспортируются в тот же endpoint, что и трассировки (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT). Чтобы отправлять логи в другой endpoint, задайте OTEL_EXPORTER_OTLP_LOGS_ENDPOINT:
export OTEL_EXPORT_ENABLED=true
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317
# Необязательно: отправлять логи в другой endpoint
# export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4317
Локальный стек наблюдаемости (см. Быстрый старт) включает OpenTelemetry Collector, который принимает OTLP на localhost:4317 и направляет трассировки в Tempo, а логи в Loki. В Grafana источник данных Loki уже предварительно настроен с derived field, который связывает labels trace_id с Tempo, так что можно сразу перейти от строки лога к соответствующей трассировке.
Быстрый старт
Запуск стека наблюдаемости
Чтобы собирать и визуализировать логи с помощью Grafana Loki или смотреть контекст трассировки в логах вместе с Grafana Tempo, запустите стек наблюдаемости. Инструкции приведены в разделе Быстрый старт по наблюдаемости. В стек входят Loki, OpenTelemetry Collector и Tempo, уже настроенные для совместной работы.
Включение структурированного логирования
Включите структурированное логирование JSONL:
export DYN_LOGGING_JSONL=true
export DYN_LOG=debug
# Start your Dynamo components (default port 8000, override with --http-port or DYN_HTTP_PORT env var)
python -m dynamo.frontend &
python -m dynamo.vllm --model Qwen/Qwen3-0.6B --enforce-eager &
Логи будут записываться в stderr в формате JSONL вместе с контекстом трассировки.
Доступные уровни логирования
| Уровни логирования (от наименее до наиболее подробного) | Описание |
|---|---|
| ERROR | Критические ошибки (например, невосстановимые сбои, исчерпание ресурсов) |
| WARN | Неожиданные или ухудшенные состояния (например, повторы, восстанавливаемые ошибки) |
| INFO | Операционная информация (например, запуск/остановка, ключевые события) |
| DEBUG | Общая отладочная информация (например, значения переменных, управление потоком) |
| TRACE | Очень подробная, низкоуровневая информация (например, шаги внутренних алгоритмов) |
Пример человекочитаемого формата
Параметры окружения:
export DYN_LOG="info,dynamo_runtime::system_status_server:trace"
export DYN_LOGGING_JSONL="false"
Итоговый формат логов:
2025-09-02T15:50:01.770028Z INFO main.init: VllmWorker for Qwen/Qwen3-0.6B has been initialized
2025-09-02T15:50:01.770195Z INFO main.init: Reading Events from tcp://127.0.0.1:21555
2025-09-02T15:50:01.770265Z INFO main.init: Getting engine runtime configuration metadata from vLLM engine...
2025-09-02T15:50:01.770316Z INFO main.get_engine_cache_info: Cache config values: {'num_gpu_blocks': 24064}
2025-09-02T15:50:01.770358Z INFO main.get_engine_cache_info: Scheduler config values: {'max_num_seqs': 256, 'max_num_batched_tokens': 2048}
Пример формата JSONL
Параметры окружения:
export DYN_LOG="info,dynamo_runtime::system_status_server:trace"
export DYN_LOGGING_JSONL="true"
Итоговый формат логов:
{"time":"2025-09-02T15:53:31.943377Z","level":"INFO","target":"log","message":"VllmWorker for Qwen/Qwen3-0.6B has been initialized","log.file":"/opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/main.py","log.line":191,"log.target":"main.init"}
{"time":"2025-09-02T15:53:31.943550Z","level":"INFO","target":"log","message":"Reading Events from tcp://127.0.0.1:26771","log.file":"/opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/main.py","log.line":212,"log.target":"main.init"}
{"time":"2025-09-02T15:53:31.943636Z","level":"INFO","target":"log","message":"Getting engine runtime configuration metadata from vLLM engine...","log.file":"/opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/main.py","log.line":220,"log.target":"main.init"}
{"time":"2025-09-02T15:53:31.943701Z","level":"INFO","target":"log","message":"Cache config values: {'num_gpu_blocks': 24064}","log.file":"/opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/main.py","log.line":267,"log.target":"main.get_engine_cache_info"}
{"time":"2025-09-02T15:53:31.943747Z","level":"INFO","target":"log","message":"Scheduler config values: {'max_num_seqs': 256, 'max_num_batched_tokens': 2048}","log.file":"/opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/main.py","log.line":268,"log.target":"main.get_engine_cache_info"}
Логирование идентификаторов trace и span
Когда включён DYN_LOGGING_JSONL, все логи содержат поля trace_id и span_id, а для запросов автоматически создаются span. Это удобно для коротких отладочных сессий, когда нужно посмотреть контекст трассировки в логах без развёртывания полноценного backend для трассировки, а также для сопоставления сообщений логов с трассировками.
Информация о trace и span использует формат и библиотеки OpenTelemetry, поэтому идентификаторы совместимы с backend трассировки на базе OpenTelemetry, такими как Tempo или Jaeger, если позже вы решите включить экспорт трассировок.
Примечание: этот раздел частично пересекается с Распределённой трассировкой с Tempo. Для визуализации трассировок в Grafana Tempo и длительного анализа трассировок см. Распределённая трассировка с Tempo.
Настройка логирования
Чтобы видеть информацию о trace в логах:
export DYN_LOGGING_JSONL=true
export DYN_LOG=debug # Set to debug to see detailed trace logs
# Start your Dynamo components (e.g., frontend and worker) (default port 8000, override with --http-port or DYN_HTTP_PORT env var)
python -m dynamo.frontend &
python -m dynamo.vllm --model Qwen/Qwen3-0.6B --enforce-eager &
Это включает логирование JSONL с полями trace_id и span_id. Трассировки будут отображаться в логах, но не будут экспортироваться в какой-либо backend.
Пример запроса
Отправьте запрос, чтобы сгенерировать логи с контекстом трассировки:
curl -H 'Content-Type: application/json' \
-H 'x-request-id: test-trace-001' \
-d '{
"model": "Qwen/Qwen3-0.6B",
"max_completion_tokens": 100,
"messages": [
{"role": "user", "content": "What is the capital of France?"}
]
}' \
http://localhost:8000/v1/chat/completions
Проверьте логи в stderr: в JSONL-выводе будут поля trace_id, span_id и x_request_id.
Информация о trace и span в логах
В этом разделе показано, как информация о trace и span выглядит в JSONL-логах. Эти логи можно использовать, чтобы понимать поток запросов даже без backend для визуализации трассировок.
Пример disaggregated-трассировки в Grafana
При просмотре соответствующей трассировки в Grafana вы должны увидеть примерно следующее:

Обзор трассировки
Dynamo создаёт распределённые трассировки, охватывающие несколько сервисов в разнесённой схеме обслуживания. В следующих разделах описаны ключевые span, которые вы увидите в Grafana при просмотре трассировок запросов на генерацию ответа в чате.
Доступные span в disaggregated-режиме
При запуске Dynamo в disaggregated-режиме типичный запрос создаёт следующие span:
1. http-request (Frontend - корневой span)
Корневой span для всего жизненного цикла запроса, создаваемый в сервисе dynamo-frontend.
Ключевые атрибуты:
- Сервис:
dynamo-frontend - Операция: Обрабатывает HTTP-запрос от клиента до завершения
- Длительность: Общее сквозное время запроса (включает prefill + decode)
- Метод: HTTP-метод (обычно
POST) - URI: Конечная точка запроса (например,
/v1/chat/completions) - Статус: Статус завершения запроса
- Дочерние span: Обычно 2-3 дочерних span (span маршрутизации + span воркеров)
Этот span представляет полный поток запроса от момента, когда frontend получает HTTP-запрос, до отправки финального ответа клиенту.
2. prefill_routing (Frontend - span маршрутизации)
Дочерний span http-request, создаваемый в сервисе dynamo-frontend на этапе маршрутизации.
Ключевые атрибуты:
- Сервис:
dynamo-frontend - Операция: Направляет prefill-запрос подходящему prefill-воркеру
- Длительность: Время, затраченное на выбор и span prefill
- Родитель:
http-requestspan
Этот span фиксирует логику маршрутизации и принятия решения, а также запрос, отправленный prefill-воркеру.
3. handle_payload (span prefill-воркера)
Дочерний span http-request, создаваемый в сервисе dynamo-worker-vllm-prefill.
Ключевые атрибуты:
- Сервис:
dynamo-worker-vllm-prefill(илиdynamo-worker-sglang-prefillдля SGLang) - Операция: Обрабатывает фазу prefill при генерации
- Длительность: Время вычисления prefill (обычно от миллисекунд до секунд)
- Компонент:
prefill - Конечная точка:
generate - Родитель:
http-requestspan
Этот span представляет фактическое вычисление prefill на специализированном prefill-воркере, включая обработку prompt и начальную генерацию KV cache.
4. handle_payload (span decode-воркера)
Дочерний span http-request, создаваемый в сервисе dynamo-worker-vllm-decode.
Ключевые атрибуты:
- Сервис:
dynamo-worker-vllm-decode(илиdynamo-worker-sglang-decodeдля SGLang) - Операция: Обрабатывает фазу decode при генерации
- Длительность: Время генерации всех выходных токенов (обычно секунды)
- Компонент:
decodeилиbackend - Конечная точка:
generate - Родитель:
http-requestspan
Этот span представляет итеративную фазу генерации токенов на специализированном decode-воркере, который использует KV cache из prefill и формирует выходные токены.
Понимание метрик span
Каждый span предоставляет несколько полезных метрик:
| Метрика | Описание |
|---|---|
| Длительность | Общее время от начала span до его завершения |
| Время активности | Время активной обработки (без ожидания) |
| Время ожидания | Время ожидания (например, сети или других сервисов) |
| Время начала | Время начала span |
| Количество дочерних span | Количество прямых дочерних span |
Соотношение Длительность = Время активности + Время ожидания помогает понять, на что тратится время, и выявить потенциальные узкие места.
Пользовательские request ID в логах
Вы можете передать пользовательский request ID с помощью заголовка x-request-id. Этот ID будет прикреплён ко всем span и логам для данного запроса, что упрощает сопоставление трассировок с отслеживанием запросов на уровне приложения.
Пример запроса с пользовательским request ID
curl -X POST http://localhost:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'x-request-id: 8372eac7-5f43-4d76-beca-0a94cfb311d0' \
-d '{
"model": "Qwen/Qwen3-0.6B",
"messages": [
{
"role": "user",
"content": "Explain why Roger Federer is considered one of the greatest tennis players of all time"
}
],
"stream": false,
"max_tokens": 1000
}'
Все span и логи для этого запроса будут содержать атрибут x_request_id со значением 8372eac7-5f43-4d76-beca-0a94cfb311d0.
Логи frontend с пользовательским request ID
Обратите внимание, что поле x_request_id присутствует во всех записях лога вместе с trace_id (80196f3e3a6fdf06d23bb9ada3788518) и span_id:
{"time":"2025-10-31T21:06:45.397194Z","level":"DEBUG","file":"/opt/dynamo/lib/runtime/src/pipeline/network/tcp/server.rs","line":230,"target":"dynamo_runtime::pipeline::network::tcp::server","message":"Registering new TcpStream on 10.0.4.65:41959","method":"POST","span_id":"f7e487a9d2a6bf38","span_name":"http-request","trace_id":"80196f3e3a6fdf06d23bb9ada3788518","uri":"/v1/chat/completions","version":"HTTP/1.1","x_request_id":"8372eac7-5f43-4d76-beca-0a94cfb311d0"}
{"time":"2025-10-31T21:06:45.418584Z","level":"DEBUG","file":"/opt/dynamo/lib/llm/src/kv_router/prefill_router.rs","line":232,"target":"dynamo_llm::kv_router::prefill_router","message":"Prefill succeeded, using disaggregated params for decode","method":"POST","span_id":"f7e487a9d2a6bf38","span_name":"http-request","trace_id":"80196f3e3a6fdf06d23bb9ada3788518","uri":"/v1/chat/completions","version":"HTTP/1.1","x_request_id":"8372eac7-5f43-4d76-beca-0a94cfb311d0"}
{"time":"2025-10-31T21:06:45.418854Z","level":"DEBUG","file":"/opt/dynamo/lib/runtime/src/pipeline/network/tcp/server.rs","line":230,"target":"dynamo_runtime::pipeline::network::tcp::server","message":"Registering new TcpStream on 10.0.4.65:41959","method":"POST","span_id":"f7e487a9d2a6bf38","span_name":"http-request","trace_id":"80196f3e3a6fdf06d23bb9ada3788518","uri":"/v1/chat/completions","version":"HTTP/1.1","x_request_id":"8372eac7-5f43-4d76-beca-0a94cfb311d0"}
Уровни логирования backend-движков
Переменная окружения Dynamo DYN_LOG управляет собственным логированием Dynamo. У каждого inference backend есть собственный контроль уровня логирования, который независим от DYN_LOG.
vLLM
Уровень логирования vLLM управляется переменной окружения VLLM_LOGGING_LEVEL.
По умолчанию он равен INFO и полностью независим от DYN_LOG.
# Set vLLM to debug while keeping Dynamo at info
export DYN_LOG=info
export VLLM_LOGGING_LEVEL=DEBUG
Допустимые значения: DEBUG, INFO, WARNING, ERROR, CRITICAL.
TensorRT-LLM
Уровень логирования TensorRT-LLM управляется переменной окружения TLLM_LOG_LEVEL.
По умолчанию он равен INFO и полностью независим от DYN_LOG.
# Set TRT-LLM to info while keeping Dynamo at warn
export DYN_LOG=warn
export TLLM_LOG_LEVEL=INFO
Допустимые значения: TRACE, DEBUG, INFO, WARNING, ERROR, INTERNAL_ERROR.
Примечание: TLLM_LOG_LEVEL считывается только один раз во время импорта TensorRT-LLM. Его нужно задать до запуска процесса.
SGLang
Логирование SGLang сейчас настраивается через Dynamo и по умолчанию следует уровню DYN_LOG. Чтобы отключить конфигурацию логирования SGLang в Dynamo и управлять ею независимо, задайте:
export DYN_SKIP_SGLANG_LOG_FORMATTING=true
Кроме того, можно передать аргумент --log-level команде воркера SGLang, чтобы задать уровень логирования движка SGLang напрямую (например, --log-level DEBUG). Это независимо от DYN_LOG.