Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Add example for gunicorn with uvicorn workers #2876

Open
byte-bot-app bot opened this issue Dec 11, 2023 · 16 comments
Open

Docs: Add example for gunicorn with uvicorn workers #2876

byte-bot-app bot opened this issue Dec 11, 2023 · 16 comments
Labels
Documentation 📚 This is related to documentation

Comments

@byte-bot-app
Copy link

byte-bot-app bot commented Dec 11, 2023

Add documentation examples for gunicorn w/ uvicorn workers. See the X post below for a user asking a question on this topic.

Ref:

Bad Messages:

Anyone doing gunicorn w/ unicorn workers?
https://x.com/greeduan/status/1732048433408627005?s=46&t=p4oNoKNiN6WSSW5RCWU7_w
@greeduan
@LitestarAPI
do you have any guide for logging when using gunicorn with uvicorn? Spent a few hours and I still can't figure out how to get the app logs out to the gunicorn logs. Meanwhile with Django it's plug-n-play. Not good for prod.

Reported by peter in Discord: <#919193495690936353>:
no but it would be nice to have an example for that


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
@JacobCoffee JacobCoffee changed the title Issue from Discord Docs: Add example for gunicorn with uvicorn workers Dec 11, 2023
@JacobCoffee JacobCoffee added the Documentation 📚 This is related to documentation label Dec 11, 2023
@JacobCoffee
Copy link
Member

JacobCoffee commented Dec 11, 2023

This relates to #2609, partially

@peterschutt
Copy link
Contributor

We were specifically talking about logging with gunicorn workers - great to have a full example, but just want to make sure that the logging topic doesn't get lost.

@provinzkraut
Copy link
Member

Thinking about this, I'm not sure if this is actually Litestar specific? The logging setup of gunicorn with uvicorn workers will be exactly the same as for any other ASGI apps. Maybe we don't need to re-invent the wheel here and could just link to existing documentation?

@winstxnhdw
Copy link

Thinking about this, I'm not sure if this is actually Litestar specific? The logging setup of gunicorn with uvicorn workers will be exactly the same as for any other ASGI apps. Maybe we don't need to re-invent the wheel here and could just link to existing documentation?

Tried doing it the same way as I did it with FastAPI, but any stray exceptions aren't being logged out.

@provinzkraut
Copy link
Member

Litestar's logging behaviour of exception is different than FastAPI's, but this is independent of the server being used. Exceptions aren't logged by default if you're not in debug mode. You can configure this by setting log_exceptions="always" in the logging config: https://docs.litestar.dev/latest/reference/logging/config.html#litestar.logging.config.LoggingConfig.log_exceptions

@winstxnhdw
Copy link

winstxnhdw commented Jul 8, 2024

Litestar's logging behaviour of exception is different than FastAPI's, but this is independent of the server being used. Exceptions aren't logged by default if you're not in debug mode. You can configure this by setting log_exceptions="always" in the logging config: https://docs.litestar.dev/latest/reference/logging/config.html#litestar.logging.config.LoggingConfig.log_exceptions

It still doesn't log anything out.

class TranscribeController(Controller):
    path = '/transcribe'

    @post()
    async def transcribe(self, data: Annotated[UploadFile, Body(media_type=RequestEncodingType.MULTI_PART)]) -> bytes:
        content = await data.read()
        raise Exception(content)
        return content

def initialise() -> Litestar:
    return Litestar(
        logging_config=LoggingConfig(log_exceptions='always'),
        route_handlers=[TranscribeController],
    )

It works fine on Uvicorn though, but with Gunicorn, it disappears.

@provinzkraut
Copy link
Member

How are you running gunicorn? I tested it and it works just fine.


In any case, as I mentioned before, this isn't unique to Litestar. It has to do with how gunicorn handles logging. See for example this issue which describes the same behaviour you're experiencing, but with FastAPI.

@winstxnhdw
Copy link

How are you running gunicorn? I tested it and it works just fine.

In any case, as I mentioned before, this isn't unique to Litestar. It has to do with how gunicorn handles logging. See for example this issue which describes the same behaviour you're experiencing, but with FastAPI.

I am well familiar with that issue and I have worked around it and still managed to get my exceptions printed.

# gunicorn.conf.py

from server import initialise
from server.config import Config

wsgi_app = f'{initialise.__module__}:{initialise.__name__}()'
reload = False
preload_app = True
bind = f'0.0.0.0:{Config.server_port}'
workers = Config.worker_count
worker_class = 'uvicorn.workers.UvicornWorker'
timeout = 300

@provinzkraut
Copy link
Member

provinzkraut commented Jul 8, 2024

That's your config but how are you running it? Is it perhaps inside a container (the bind to 0.0.0.0 suggests that)?

@winstxnhdw
Copy link

Nope, it's not containerised. Running it in a poetry venv with poetry run gunicorn and that's it.

@provinzkraut
Copy link
Member

What platform are you on?

@provinzkraut
Copy link
Member

I don't know why but it seems to be the preload_app = True in your gunicorn config. Adding that causes the logs to disappear.

I've found this issue which seems to describe this exact behaviour, but apparently it has been fixed since.

@winstxnhdw
Copy link

winstxnhdw commented Jul 8, 2024

I have tested on my personal Windows laptop and within a Linux VPS. I'll try disabling preload_app tomorrow but preload_app is quite important IIRC.

@winstxnhdw
Copy link

Yeah, I have confirmed that it is indeed preload_app that's causing this issue, and I believe this is on Litestar's end because all my FastAPI applications are completely fine with this setting.

@JacobCoffee
Copy link
Member

JacobCoffee commented Jul 9, 2024

not familiar with the issue - just interjecting here quickly - but with the advent of process management in Uvicorn, it may help your particular situation? (to swap from Gunicorn)

@provinzkraut
Copy link
Member

Yeah, I have confirmed that it is indeed preload_app that's causing this issue, and I believe this is on Litestar's end because all my FastAPI applications are completely fine with this setting.

This seems odd. I'm still not 100% convinced this is a bug on our end, but would you mind opening a separate issue for this? It's not really a documentation thing in any case, because this should work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation 📚 This is related to documentation
Projects
Status: Ideas
Development

No branches or pull requests

4 participants