Skip to content

feat(v3)!: New logging experience#4593

Open
provinzkraut wants to merge 16 commits intomainfrom
fix-logging
Open

feat(v3)!: New logging experience#4593
provinzkraut wants to merge 16 commits intomainfrom
fix-logging

Conversation

@provinzkraut
Copy link
Member

@provinzkraut provinzkraut commented Feb 11, 2026

Still need to clean up some things to reduce unnecessary breaking changes, but feature wise, everything is there.


  • Remove global Litestar logging config; Litestar now only configures its own logging
  • Simplify structlog integration
  • Remove structlog plugin (not necessary anymore)
  • Don't configure structlog globalls
  • Remove picologging
  • Simplify logging configuration
  • Simplify logging middleware configuration
  • Unify logging config / logging middleware config
  • Improve testing integration (behave nicely with caplog / structlogs capture_logs)
  • Better docs

@github-actions github-actions bot added area/connection area/dependencies This PR involves changes to the dependencies area/docs This PR involves changes to the documentation area/logging area/middleware This PR involves changes to the middleware area/plugins This PR involves changes to the plugins area/private-api This PR involves changes to the privatized API area/testing Breaking 🔨 size: large type/feat pr/internal labels Feb 11, 2026
@provinzkraut provinzkraut marked this pull request as ready for review February 11, 2026 20:10
@provinzkraut provinzkraut requested review from a team and JacobCoffee as code owners February 11, 2026 20:10
@provinzkraut provinzkraut requested a review from a team as a code owner February 11, 2026 20:10
@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 93.81443% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.79%. Comparing base (2af0305) to head (c4d3f28).

Files with missing lines Patch % Lines
litestar/logging/config.py 93.05% 1 Missing and 4 partials ⚠️
litestar/logging/structlog.py 94.20% 1 Missing and 3 partials ⚠️
litestar/middleware/logging.py 93.93% 0 Missing and 2 partials ⚠️
litestar/app.py 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4593      +/-   ##
==========================================
- Coverage   97.85%   97.79%   -0.06%     
==========================================
  Files         297      294       -3     
  Lines       15339    15200     -139     
  Branches     1721     1715       -6     
==========================================
- Hits        15010    14865     -145     
- Misses        188      190       +2     
- Partials      141      145       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@Kumzy Kumzy left a comment

Choose a reason for hiding this comment

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

In the test_apps/logging_test_app in main.py line 3, the import is no longer correct too?

I think it's missing some tests on ExtraKeyValueFormatter for the litestar/logging/config.py

"""A list of :class:`EventListener <.events.listener.EventListener>`."""
logging_config: BaseLoggingConfig | None = field(default=None)
"""An instance of :class:`BaseLoggingConfig <.logging.config.BaseLoggingConfig>` subclass."""
logging_config: LoggingConfig = field(default_factory=LoggingConfig)
Copy link
Member

Choose a reason for hiding this comment

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

We can no longer pass None to this to disable the logging config?

Copy link
Contributor

Choose a reason for hiding this comment

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

my app on this branch uses Litestar(logging_config=None) and I didnt have any errors

Copy link
Member Author

Choose a reason for hiding this comment

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

Mhm. I think that's just an oversight in the typing. I'll check on that

Copy link
Member

Choose a reason for hiding this comment

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

I think there are some performance implications here. IIRC, using None here can improve performance in some cases.

We should probably ensure the None remains an option here.

def debug(self) -> bool:
return self._debug

@debug.setter
Copy link
Member

Choose a reason for hiding this comment

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

Is it intended so we can not change the debug status while the app is running or it was never working before?

Copy link
Member Author

Choose a reason for hiding this comment

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

It has never properly worked before

Copy link
Member Author

Choose a reason for hiding this comment

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

It's also very tricky to get right, because not all logging libraries work the same in regards of setting levels dynamically.

return not self.pretty_print_tty
return True

def _get_structlog_config(self) -> dict[str, None]:
Copy link
Member

Choose a reason for hiding this comment

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

Litestar mostly use dict[str, Any] for returns type. It's the only line in the code where the returns is dict[str, None]. Is it intended?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope. Any I'm not sure why mypy isn't complaining about this 😅

exception_logging_handler: ExceptionLoggingHandler | None
"""Handler function for logging exceptions."""
disable_stack_trace: set[Union[int, type[Exception]]] # noqa: UP007
disable_stack_trace: set[int | type[Exception]] = dataclasses.field(default_factory=set)
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to use this opportunity to set a few default exceptions to exclude from the stack trace.

I tend to always add the following default set to every application to cleanup logging output: {404, 401, 403, NotAuthorizedException, PermissionDeniedException}

"""This will be the configuration for the root logger.

Processing of the configuration will be as for any logger, except that the propagate setting will not be applicable.
always_propagate_on_pytest: bool = True
Copy link
Member

Choose a reason for hiding this comment

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

Nice addition!

docs-serve: ## Serve the docs locally
@echo "=> Serving documentation"
uv run --isolated --python 3.12 sphinx-autobuild docs docs/_build/ -j auto --watch litestar --watch docs --watch tests --watch CONTRIBUTING.rst --open-browser --port=0
uv run --isolated sphinx-autobuild docs docs/_build/ -j auto --watch litestar --watch docs --watch tests --watch CONTRIBUTING.rst --open-browser --port=0
Copy link
Member

Choose a reason for hiding this comment

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

I think we should consider leaving these pins in.

When i install the dev env, I typically use the lowest supported version for the library (3.10 in this case), but the latest versions of Sphinx have a minimum version of 3.12. We have been running into similar problems with the Advanced Alchemy docs.

Copy link
Member Author

Choose a reason for hiding this comment

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

I had a reason for unpinning this but I can't remember. I'll find out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/connection area/dependencies This PR involves changes to the dependencies area/docs This PR involves changes to the documentation area/logging area/middleware This PR involves changes to the middleware area/plugins This PR involves changes to the plugins area/private-api This PR involves changes to the privatized API area/testing Breaking 🔨 pr/internal size: large type/feat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments