Adding support for .json and .yaml --log-config files

I was about to click “Create pull request” in github with some changes I thought would be well received, but then saw the “Maintainer driven issues” request in the contributing guidelines, so here I am. :slight_smile:

My use case is that I wish to run my app using the uvicorn command line option but also specify a custom logging config. This means --log-config must currently point to a file using the limited and apparently deprecated configparser format as uvicorn uses the fileConfig() function.

It appeared to be pretty trivial to add support for loading a JSON or YAML config so that one could hand it off to dictConfig(), so I went ahead and did that work on my fork here. You can see from the commit message that it addresses a couple of other currently open issues.

The changes should be backwards-compatible with existing installations, as it only attempts to load the json or yaml files if the indicated file has the appropriate filename extension. If not, it falls back to the current behavior where the configparser format is assumed. However, it will now emit a warning letting the client know that they can/should update to the new format so we can hopefully remove the fileConfig() functionality in the future.

Any thoughts?

Hello, I only can offer my good thoughts in agreement.

I am looking for a clean way to do this myself, as I’d prefer us using the YAML (or JSON) instead of the INI. Or if we could programatically set it as we want, that’d be good too.

perhaps the question is should we start uvicorn in that case as
uvicorn or via python command?

Hello!

Guys, what you’re talking about isn’t a uvicorn, but python issue – it doesn’t support anything but INI.

My opinion is:

  • JSON may be worth implementing but its syntax is too complex for config files.
  • YAML – definitely no. Because it’s parser is a pretty heavy dependency. Adding it to the project just to be able to parse one file at a start time is a huge overkill.

Overall: implement your favorite config type and initialize logging in your project, no need to do that inside the uvicorn.

Hi! thanks for your comment :slight_smile: (apologies in advance for the verbose reply)

I think I have to disagree on the point about python not supporting anything but INI. The presence of dictConfig() indicates that Python intends to allow other non-INI configuration options, especially since it provides functionality that fileConfig() does not. I can’t remember explicitly what it was at the moment since it was a year or so ago on another project when I bumped into it, but INI wouldn’t allow you to specify user-defined classes for handlers and loggers. Something about which namespaces were searched for the class name, I think. I just remember a use case that precluded me from using INI.

As for JSON being too complicated, I’m not sure I can follow you there, either. JSON syntax is exceedingly simple. If anything, the logging configuration itself can get pretty complicated, but JSON is more than equipped to handle it, and I don’t think humans generally have a problem with representing fairly generic hierarchy in JSON.

Regarding your YAML concern, I share it to a degree. Which is why in my implementation I’m treating it as an optional dependency. If you prefer YAML, bundle the library with your deployment. If not, no worries, it’s not a hard requirement in uvicorn.

Ultimately, this all stems from a desire to not disable existing loggers when providing one’s own logging configuration. That’s currently impossible without adding a fairly esoteric option to the uvicorn config settings which I think is better expressed as a logging configuration file setting and INI doesn’t allow that. I just figured we could add some flexibility to the logging system while we were at it.

The only other option is to have uvicorn users call dictConfig() from within their application. I think this is a subpar solution as it’s best to initialize logging as early as possible and only once if possible. uvicorn is already in the business of allowing users to provide this configuration, I just think we can improve it.

My personal preference is to use YAML, as my use case is not negatively impacted by a 200k whl file and the convenience of a YAML configuration is worth it (plus it allows comments!).

Thanks for reminding me about this! I need to go update that PR to merge in the latest changes from master.

As for JSON being too complicated, I’m not sure I can follow you there, either. JSON syntax is exceedingly simple. If anything, the logging configuration itself can get pretty complicated, but JSON is more than equipped to handle it, and I don’t think humans generally have a problem with representing fairly generic hierarchy in JSON.

To understand what I mean, try to edit JSON with some simple editor: let’s say nano. Nothing is so easily breakable as JSON syntax.

My personal preference is to use YAML, as my use case is not negatively impacted by a 200k whl file and the convenience of a YAML configuration is worth it (plus it allows comments!).

I like YAML too. But won’t use it anywhere unnecessarily.

And again: if you want YAML configuration – configure logging in your code! It’s as easy as using --log-config option.

Just a heads up that this functionality got merged and should be in a future release.

Thanks, everyone!