patternpythonMinor
Logging module for use in other projects
Viewed 0 times
loggingprojectsmoduleotherforuse
Problem
I'm trying to make a simple module I can paste into my various projects to provide basic logging capabilities. I'm hoping to become less dependent on
Here's the
Here's an example of its usage:
```
import logging
import argparse
from log import parse_log_args, conf_logging
logger = logging.getLogger(__name__)
parser = argparse.ArgumentParser()
parser = parse_
print because:- Using
loggingwill allow me to quickly enable and disable what's being logged
logginghas built-in file and formatting utilities
- The built-in levels of
loggingare helpful
Here's the
log.py module:import argparse
import logging
import sys
def parse_log_args(parser: argparse.ArgumentParser):
default_level = 'INFO'
parser.add_argument("-l", "--log", dest="loglevel",
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
default=default_level,
help=f"Set the logging level (default: {default_level})",
type=str)
parser.add_argument(
'-lf', '--logfile',
help="File for logging",
dest="logfile",
type=str
)
return parser
def conf_logging(logger: logging.Logger, loglevel: str, path=None):
if loglevel.upper() not in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'):
raise ValueError("Invalid logging level")
if path is None:
console_formatter = logging.Formatter('[%(levelname)s] %(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(console_formatter)
else:
file_formatter = logging.Formatter(
('%(asctime)s [%(levelname)s] %(name)s.%(funcName)s'
'@ L%(lineno)d\n %(message)s'))
handler = logging.FileHandler(path, encoding='utf-8')
handler.setFormatter(file_formatter)
l_name = logging.getLevelName(loglevel)
handler.setLevel(l_name)
logger.setLevel(l_name)
logger.addHandler(handler)
return loggerHere's an example of its usage:
```
import logging
import argparse
from log import parse_log_args, conf_logging
logger = logging.getLogger(__name__)
parser = argparse.ArgumentParser()
parser = parse_
Solution
It's more natural to say
Not sure why you need
You're specifying type of
Raising "Invalid logging level" is maybe superfluous, better to let the underlying logging library deal with it. Looks like you're reaching across layers.
Naming your module
In the example, I recommend deleting:
in favor of
Perhaps you'd like to make it more convenient for callers, by defaulting loglevel, and letting a caller just pass in
Overall, it looks like a useful utility.
"--loglevel", ... than "--log", dest="loglevel", .... A log switch suggests that it takes an argument of a logfile output filename.Not sure why you need
dest for the logfile argument.You're specifying type of
str which is already the default, but maybe you did it to help with type annotations?Raising "Invalid logging level" is maybe superfluous, better to let the underlying logging library deal with it. Looks like you're reaching across layers.
Naming your module
log is perhaps a bit adventurous, as sometimes folks concisely write log.info() instead of logger.info().In the example, I recommend deleting:
logger = logging.getLogger(__name__)in favor of
conf_logging(logging.getLogger(__name__), args.loglevel, args.logfile).Perhaps you'd like to make it more convenient for callers, by defaulting loglevel, and letting a caller just pass in
__name__ if that's all that is interesting.Overall, it looks like a useful utility.
Code Snippets
logger = logging.getLogger(__name__)Context
StackExchange Code Review Q#157903, answer score: 3
Revisions (0)
No revisions yet.