pythonlogginguvicorn

Dynamically change logs level in uvicorn


I have a Fastapi API running with uvicorn. I use uvicorn logging like so:

if __name__ == "__main__":
    uvicorn.run("main:app", host=host, port=int(port), reload=True, log_level=log_level,
                log_config="config/logging.yaml")

What I would like to achive is beeing able to change the log_level through an endpoint. Something like:

@app.put("/api/log/{level}")
def change_log_level(level):
    #something that changes the log level.

I tried to make a global variable log_level but it didn't work and I'm not sure how to change it as the log_level is in the uvicorn.run instruction. It is as well in the config.yaml file, so I'm not really sure were to change it...
I'm open to try the logging with another library if needed


Solution

  • You could try something like this:

    @app.put("/api/log/{level}")
    def change_log_level(level):
        logging_level = your_function_to_map_url_level_to_logging_level(level)
        logging.getLogger('uvicorn').setLevel(logging_level)
    

    You might want to do this for logger 'uvicorn' as above, or perhaps 'uvicorn.access' or 'uvicorn.error', or any combination of these.

    There's a uvicorn.config.LOG_LEVELS dictionary mapping strings like 'critical' to logging.CRITICAL, etc. You might want to use that in your_function_to_map_url_level_to_logging_level, but you'd need to handle invalid levels passed in via the URL.