Add project-wide configuration for the Python logging module, create guideline on how to use it (when to use which logging level), and use it instead of our own logging wrapper.
I have spent quite some effort on trying to use the loggingmodule the right way in in-toto over the years. Maybe we can revisit related issues/prs to see if this is applicable for TUF and for a general guideline document. See e.g.
https://github.com/in-toto/in-toto/issues/6#issuecomment-263988714, https://github.com/in-toto/in-toto/pull/183, https://github.com/in-toto/in-toto/pull/240.
cc @MVrachev and https://github.com/theupdateframework/tuf/pull/1104
Some good advice on _when_ to log in #1145
The important rules that I think work are:
warnings.warn(), not the log level) should be used to communicate with application developer (e.g. about deprecation). Warnings are not shown to end users by defaultAfter wrestling with the current log module a few times I'll document my understanding of it's contents:
python
logger = logging.getLogger('tuf')
logger.addHandler(logging.NullHandler())
In my opinion the log module is not needed:
I think we should use a log module as a central place to configure a base logger, from which all other module loggers inherit automatically by name:
# In log.py (configure base logger handler, format, default level, etc. eg. based on 'tuf.settings')
import logging
logger = logging.getLogger("tuf")
logger.addHandler(...
...
```python
import tuf.log
```python
# In any other tuf.<module>.py we inherit just by name
import logging
logger = logging.getLogger(__name__) # __name__ == 'tuf.<module>' and thus inherits from 'tuf' base logger.
...
This also allows application developers to just grab the base handler via logging.getLogger('tuf') and customize all of TUF's logging, e.g. silence or make more verbose (see in-toto.log for how this is done in practice).
# In __init__.py (initialize base handler before anything else) # This is the only place where 'tuf.log' needs to be imported import tuf.log # Alternatively, we could just configure the base logger here and # omit the 'log.py' module.
__init__.py would need a single line logging.getLogger("tuf").addHandler(logging.NullHandler()) so that seems reasonable if tuf modules are expected to do "import tuf" anyway.
Yes, if we don't need any other customization then it's enough to just add it to __init__.py (IIRC, that's what the tuf fork uptane does). In in-toto we do have a separate log.py-module, because we do quite a bit of logger customization for the in-toto command lines tools, which can probably be seen as in-toto applications. TUF OTOH should be a pure library, so configuring a default NullHandler and having application developers customize logging as suited seems like a good idea.
Regarding
... if tuf modules are expected to do "import tuf" anyway.
AFAIK that isn't even necessary. __init__.py is automatically executed if a module of the package is executed.