Skip to content

Instantly share code, notes, and snippets.

@cgarbin
Last active June 3, 2023 13:46
Show Gist options
  • Save cgarbin/efd6434c2e251a1a829a0c3721c7d8d4 to your computer and use it in GitHub Desktop.
Save cgarbin/efd6434c2e251a1a829a0c3721c7d8d4 to your computer and use it in GitHub Desktop.
"""A simple logger to share logging configuration across the project.
- Info and debug messages go to stdout.
- Error and warning messages go to stderr.
Note that use a module-level logger is not the best practice. It's enough for hobbyist projects. Use the logging module
configuration file for more complex projects (https://docs.python.org/3/howto/logging.html#configuring-logging).
Usage:
import logger
log = logger.get_logger().info("Hello, world!")
log.info("Hello, world!")
log.error("Something went wrong!")
"""
import logging
import sys
logger = None # pylint: disable=invalid-name
VERBOSE = False
def get_logger():
"""Return the logger, creating it if necessary."""
class InfoAndBelowHandler(logging.StreamHandler):
"""A handler that only emits INFO and below to suppress ERROR messages going to stdout."""
def emit(self, record):
if record.levelno < logging.ERROR:
super().emit(record)
global logger # pylint: disable=global-statement,invalid-name
if logger is None:
logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s %(message)s', datefmt="%H:%M:%S")
# Log to stdout
stdout_handler = InfoAndBelowHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
# Log to stderr
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.ERROR)
stderr_handler.setFormatter(formatter)
logger.addHandler(stderr_handler)
return logger
def set_verbose(on: bool):
"""Set the logger to verbose mode."""
global VERBOSE # pylint: disable=global-statement,invalid-name
VERBOSE = on
level = logging.DEBUG if on else logging.INFO
l = get_logger() # noqa
l.setLevel(level) # Must set at the logger and handler level
for handler in l.handlers:
if isinstance(handler, logging.StreamHandler) and handler.stream == sys.stdout:
handler.setLevel(level)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment