Перейти к основному содержимому

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Включить формат логирования JSONLfalsetrue
DYN_LOGGING_SPAN_EVENTSВключить логирование событий входа и закрытия span (SPAN_FIRST_ENTRY, SPAN_CLOSED)falsetrue
DYN_LOGУровни логов для каждого target <default_level>,<module_path>=<level>,<module_path>=<level>infoDYN_LOG=info,dynamo_runtime::system_status_server:trace
DYN_LOG_USE_LOCAL_TZИспользовать локальный часовой пояс для временных меток (по умолчанию UTC)falsetrue
DYN_LOGGING_CONFIG_PATHПуть к пользовательской TOML-конфигурации логированияnone/path/to/config.toml
VLLM_LOGGING_LEVELУровень логирования backend vLLM (независим от DYN_LOG)INFODEBUG
TLLM_LOG_LEVELУровень логирования backend TensorRT-LLM (независим от DYN_LOG)INFODEBUG
DYN_SKIP_SGLANG_LOG_FORMATTINGОтключить конфигурацию логирования SGLang в Dynamofalsetrue
OTEL_SERVICE_NAMEИмя сервиса для информации о trace и spandynamodynamo-frontend
OTEL_EXPORT_ENABLEDВключить экспорт OTLP для трассировок и логовfalsetrue
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTLP gRPC endpoint для трассировокhttp://localhost:4317http://tempo:4317
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTOTLP 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 вы должны увидеть примерно следующее:

Пример disaggregated-трассировки

Обзор трассировки

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-request span

Этот 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-request span

Этот 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-request span

Этот 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.

Связанная документация