litestar-org / litestar

Production-ready, Light, Flexible and Extensible ASGI API framework | Effortlessly Build Performant APIs
https://litestar.dev/
MIT License
5.36k stars 363 forks source link

Enhancement: allow finer tuning `LoggingConfig` for exception logging #3455

Open LonelyVikingMichael opened 4 months ago

LonelyVikingMichael commented 4 months ago

Summary

Setting LoggingConfig.log_exceptions to "always" is good to get more data about uncaught exceptions in a debug=False environment but can get pretty noisy, since we'll also log some common errors for schema validation, auth, etc when the developer might really only be interested in uncaught internal server errors.

It would be helpful if we could configure this according to HTTP status codes (or perhaps Union[int, type[Exception]] - similar to the keys of ExceptionHandlersMap?) and only log when raising for these status codes/types

Basic Example

Something like LoggingConfig(exceptions={422, 500, MyCustomException})

Drawbacks and Impact

N/A

Unresolved questions

No response


[!NOTE]
While we are open for sponsoring on GitHub Sponsors and OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.

Fund with Polar

jderrien commented 3 months ago

Hello 👋

I plan to set LoggingConfig.log_exceptions to always by default in a future release if everyone agree.

I'm not sure we want to add more features to LoggingConfig. The plan might be to deprecate it in v3 (see https://github.com/litestar-org/litestar/issues/2858#issuecomment-2076300407).

For your use case, you can leverage LoggingConfig.exception_logging_handler and bring your own exception logging handler.

Currently mine looks like that:

def exception_logging_handler(logger: Logger, scope: Scope, tb: list[str]) -> None:
    exception_type = sys.exc_info()[0]
    if exception_type is NotFoundException:
        logger.error("NotFoundException raised (connection_type=%s, path=%s), returning a 404 error",
                     scope["type"], scope["path"])
    else:
        logger.exception("Uncaught exception (connection_type=%s, path=%s, exception_type=%s):",
                         scope["type"], scope["path"], exception_type.__name__)