I'm somewhat new to Python, especially in writing modules and functions in several files and not just raw scripts.
I'm writing a command line app and I would like to have a single function (I call it argpconf
) that will parse the command line arguments and set a log level accordingly. Most importantly, I'd like the log level to be set once in this function and to be the same across all modules with minimum overhead when creating their loggers. Additionally, I would like to be able to identify the module from which the message came while using the common formatter:
logging.Formatter("%(levelname)s : %(name)s : %(message)s")
Partially based on a cookiecutter template, I've created the following files:
├── api
│ ├── __init__.py
│ └── some_functionality.py
├── cli.py
├── core
│ ├── argpconf.py
│ ├── __init__.py
│ ├── logger.py
│ └── __version__.py
├── __init__.py
└── __main__.py
core/logger.py
has the following content:
from logging import Formatter, Logger as _Logger, NullHandler, StreamHandler
class Logger(_Logger):
def __init__(self, name=None):
super(Logger, self).__init__(name or __name__.split(".")[0])
self.addHandler(NullHandler()) # default to no output
def start(self, level="WARN", stream=None,
fmt="%(levelname)s : %(name)s : %(message)s"):
handler = StreamHandler(stream)
handler.setFormatter(Formatter(fmt))
self.addHandler(handler)
self.setLevel(level.upper())
def stop(self):
for handler in self.handlers[1:]:
# Remove everything but the NullHandler.
self.removeHandler(handler)
logger = Logger()
Compared to the ideas suggested in the answers to these questions:
- How to share a file between modules for logging in python
- Python logging - multiple modules
- How to use logging.getLogger(__name__) in multiple modules
- Using Python logging in multiple modules
I really like the approach taken in the cookiecutter template with the logger since it allows you just to import logger
and have a logger
object that it's log level is the same across all modules. However, I'm not totally satisfied with it, because in my case the argpconf.py
is the first module that starts the logger
so all log messages from all modules have their %(name)s
substituted with core
since it's argpconf.py
's __name__.split(".")[0]
.
How can I improve the logger
module so it will detect the module that called it and print log messages with module as the %(name)s
and perhaps even the function that prints them?