Skip to content

fix(logging): parse DYN_LOG filter directives when deriving engine log level - #13326

Open
azrabano23 wants to merge 5 commits into
ai-dynamo:mainfrom
azrabano23:fix-dyn-log-parsing
Open

fix(logging): parse DYN_LOG filter directives when deriving engine log level#13326
azrabano23 wants to merge 5 commits into
ai-dynamo:mainfrom
azrabano23:fix-dyn-log-parsing

Conversation

@azrabano23

@azrabano23 azrabano23 commented Aug 16, 2026

Copy link
Copy Markdown

Overview

configure_dynamo_logging() derives the level for the engine (sglang) loggers from DYN_LOG, but passed the raw filter string to log_level_mapping(), which only exact-matches lowercase whole-string level names and mapped "trace" to INFO. This PR factors the directive parsing already used by python_log_level_mapping() into a shared filter_level_mapping() helper and uses it for the engine path.

What was broken

Engine log level derived from DYN_LOG before → after this change:

DYN_LOG Before After
debug,dynamo=debug (documented form, e.g. writing-unified-backends.md) INFO DEBUG
DEBUG INFO DEBUG
trace INFO (less verbose than debug!) DEBUG (Python has no TRACE)
dynamo_runtime=debug INFO DEBUG
debug DEBUG DEBUG (unchanged)
unset / info INFO INFO (unchanged)
warn / error / critical WARNING / ERROR / CRITICAL unchanged

python_log_level_mapping() now delegates to the shared helper; its behavior is unchanged for every input, including the DYN_LOGGING_CONFIG_PATH / default-TOML short-circuit, which is intentionally not applied to the engine path (Rust merges TOML filters after DYN_LOG, so preserving DEBUG there is only correct for the Python bridge level, not for engine logger config).

Verification

  • Extended components/src/dynamo/vllm/tests/test_vllm_logging.py: parametrized unit tests for log_level_mapping (case/whitespace normalization, trace, unknown values) and filter_level_mapping (bare, scoped, and mixed directives), plus end-to-end tests asserting the generated sglang logging config is DEBUG for debug / DEBUG / trace / debug,dynamo=debug and INFO when DYN_LOG is unset — the four DEBUG cases fail on main.
  • All 37 tests in the file pass; the 13 pre-existing tests pass unchanged.
  • ruff check, black --check, and isort --check-only clean on both files at the pre-commit pinned versions.

Open in Devin Review

Summary by CodeRabbit

  • Bug Fixes

    • Improved logging configuration to correctly interpret case-insensitive levels, whitespace, aliases, and comma-separated filters.
    • Ensured engine logging reflects the most verbose enabled level from DYN_LOG settings.
    • Preserved expected debug logging behavior for file-based configurations.
  • Tests

    • Added coverage for valid, invalid, default, and verbose logging configurations.

…g level

configure_dynamo_logging() passed the raw DYN_LOG string to
log_level_mapping(), which only exact-matched lowercase whole-string
level names and mapped "trace" to INFO. As a result, documented filter
forms such as DYN_LOG=debug,dynamo=debug, uppercase values such as
DYN_LOG=DEBUG, and DYN_LOG=trace all silently degraded the engine
(sglang) loggers to INFO.

Factor the per-directive parsing already used by
python_log_level_mapping() into a shared filter_level_mapping() helper:
split the filter on commas, take the level after the last "=" in each
directive, normalize case/whitespace, and use the lowest enabled level.
log_level_mapping() now maps "trace" to DEBUG (Python has no TRACE
level). The logging-config-file short-circuit in
python_log_level_mapping() is preserved and intentionally not applied
to the engine path.

Extend test_vllm_logging.py with coverage for both mapping helpers and
for the sglang logging config produced for directive-style, uppercase,
trace, and default DYN_LOG values.

Signed-off-by: Azra Bano <azrabano.work@gmail.com>
@azrabano23
azrabano23 requested review from a team as code owners August 16, 2026 06:23
@copy-pr-bot

copy-pr-bot Bot commented Aug 16, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@azrabano23
azrabano23 temporarily deployed to external_collaborator August 16, 2026 06:23 — with GitHub Actions Inactive
@azrabano23
azrabano23 temporarily deployed to external_collaborator August 16, 2026 06:23 — with GitHub Actions Inactive
@github-actions

Copy link
Copy Markdown
Contributor

👋 Hi azrabano23! Thank you for contributing to ai-dynamo/dynamo.

Just a reminder: The NVIDIA Test Github Validation CI runs an essential subset of the testing framework to quickly catch errors.Your PR reviewers may elect to test the changes comprehensively before approving your changes.

🚀

@github-actions github-actions Bot added external-contribution Pull request is from an external contributor fix backend::vllm Relates to the vllm backend labels Aug 16, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 68af60dd-9764-48c5-96f4-68f980fa669a

📥 Commits

Reviewing files that changed from the base of the PR and between c13fdce and 9d619dc.

📒 Files selected for processing (2)
  • components/src/dynamo/vllm/tests/test_vllm_logging.py
  • lib/bindings/python/src/dynamo/runtime/logging.py

Included review availability: Your plan includes up to 12 reviews per rolling hour; 11 remain after this review.


Walkthrough

Changes

Logging filter mapping

Layer / File(s) Summary
Runtime filter parsing and logging integration
lib/bindings/python/src/dynamo/runtime/logging.py
DYN_LOG values now support normalized levels and comma-separated bare or target-scoped directives. Runtime logging uses the mapped threshold for engine and Python logging.
Mapping and generated configuration tests
components/src/dynamo/vllm/tests/test_vllm_logging.py
Tests cover aliases, whitespace, trace handling, invalid values, directive filters, and generated SGLang logging levels.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 9d619

The change makes engine logging honor documented DYN_LOG directives while preserving existing behavior for unchanged inputs, with targeted tests and formatting checks reported as passing; no actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the problem, implementation, affected behavior, and verification, but it omits the required Related Issues section and reviewer-start guidance. Add the required Related Issues section and identify where reviewers should start, such as the logging implementation and test file.
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: parsing DYN_LOG filter directives to derive the engine log level.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@datadog-official

datadog-official Bot commented Aug 16, 2026

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

🚦 3 Pipeline jobs failed

Docs link check | lychee   View in Datadog   GitHub Actions

See error 404 Not Found errors when accessing the API at 'https://xgrammar.mlc.ai/docs/structural_tag/structural_tag_api.html'.

Pre Merge | Docs Website Composition Check   View in Datadog   GitHub Actions

See error 2 errors during fern check: Path does not exist and failed to parse frontmatter for '/tmp/tmp.bU2mezoXNk/docs-checkout/fern/pages-dev/reference/general/sim-test-page.mdx'.

Pre Merge | pre-merge-status-check   View in Datadog   GitHub Actions

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: dcbdf2c | Docs | Datadog PR Page | Give us feedback!

Signed-off-by: Azra Bano <azrabano.work@gmail.com>
@azrabano23
azrabano23 requested a review from a team as a code owner August 16, 2026 06:58
@azrabano23
azrabano23 temporarily deployed to external_collaborator August 16, 2026 06:58 — with GitHub Actions Inactive
@azrabano23

Copy link
Copy Markdown
Author

CI status: the Generated API References check flagged that this PR's new filter_level_mapping symbol wasn't reflected in the generated reference pages — fixed by regenerating with gen_python_api.py (dcbdf2c). The remaining lychee failure is the pre-existing external 404s on xgrammar.mlc.ai in structural-tag.md, a file this PR doesn't touch — same situation as #13318, and #13314 already repoints those links.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 16, 2026
"""
return min(
log_level_mapping(directive.rsplit("=", 1)[-1])
for directive in filters.split(",")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid Rust env_filter target-only directives like DYN_LOG=dynamo_llm are treated as an unknown level and mapped to INFO, so DEBUG/TRACE engine logs can still be filtered out. Fix: recognize non-empty directives without = that are not bare level names as target-only TRACE-equivalent directives and map them to logging.DEBUG.

🤖 AI Fix

Update filter_level_mapping in lib/bindings/python/src/dynamo/runtime/logging.py to strip each comma-separated directive, skip empty directives, use the text after the final = when present, use log_level_mapping for recognized bare level tokens, and map any remaining non-empty target-only directive without = to logging.DEBUG; keep logging.INFO as the default when no directives remain.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that was a real gap: DYN_LOG=dynamo_llm is a valid env_filter directive meaning "target dynamo_llm at TRACE", but filter_level_mapping handed the whole token to log_level_mapping, which returned INFO for anything it did not recognise, so the engine loggers still dropped DEBUG.

Fixed in 7b7b3ca. filter_level_mapping now strips each comma-separated directive, skips empty ones, uses the text after the final = when present, maps recognised bare level names through log_level_mapping, and maps any other bare token to logging.DEBUG (Python has no TRACE). INFO remains the default when nothing is left. log_level_mapping is now a table lookup so the set of level names is defined once; that also adds off, which env_filter accepts and which previously would have become INFO (or DEBUG, once bare targets map to DEBUG) — it maps to CRITICAL, the most restrictive level configure_sglang_logging can name in its dictConfig.

Before/after on the old code: dynamo_llm -> INFO, dynamo_llm,warn -> INFO, off -> INFO; now DEBUG, DEBUG, CRITICAL.

Tests added to test_filter_level_mapping: dynamo_llm, dynamo_llm,warn, tokio=trace, Dynamo_LLM=Debug, WARN, off, error,off, "", " ", warn,,; and off in test_log_level_mapping.

python -m pytest components/src/dynamo/vllm/tests/test_vllm_logging.py   # 48 passed
isort / black / flake8 (pre-commit args) / ruff 0.5.2 / codespell on the two files: clean

I ran the test file with a stub for dynamo._core.log_message since I do not have the compiled bindings locally; nothing in the file needs the extension beyond that import. The branch is merged with current main; the generated Python API pages are no longer committed since #13556, so there is nothing to regenerate for the docstring change.

Signed-off-by: Azra Bano <azrabano.work@gmail.com>

# Conflicts:
#	docs/fern/pages/reference/api/python/README.mdx
#	docs/fern/pages/reference/api/python/runtime.mdx
@azrabano23
azrabano23 temporarily deployed to external_collaborator August 24, 2026 02:45 — with GitHub Actions Inactive
azrabano23 and others added 2 commits September 4, 2026 10:46
…ping

A Rust env_filter directive without a level, e.g. DYN_LOG=dynamo_llm,
enables TRACE for that target. filter_level_mapping() fed the whole
directive to log_level_mapping(), which did not recognize it and fell
back to INFO, so the engine loggers still discarded DEBUG records that
the user had asked for.

Parse each directive as env_filter does: strip whitespace, skip empty
entries, take the text after the final "=" when present, map bare level
names (now including "off", which has no Python equivalent and maps to
CRITICAL) and map any other bare token to DEBUG because it names a
target at TRACE. INFO remains the default when nothing is left.

Signed-off-by: Azra Bano <azrabano.work@gmail.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@azrabano23
azrabano23 temporarily deployed to external_collaborator September 4, 2026 14:54 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend::vllm Relates to the vllm backend documentation Improvements or additions to documentation external-contribution Pull request is from an external contributor fix size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant