Skip to content

Instantly share code, notes, and snippets.

@norweeg
Created July 27, 2023 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save norweeg/14b089057405a91abce27b360091659e to your computer and use it in GitHub Desktop.
Save norweeg/14b089057405a91abce27b360091659e to your computer and use it in GitHub Desktop.
Setup console logging with Python standard library logging module
import logging
from sys import stderr, stdout
# Handle log messages from only these loggers.
# We will always log messages from "root" logger
# by appending names to this list, we can add additional loggers
# that should be handled
terminal_logger_names = []
# Format for terminal output: only show the log message
terminal_formatter = logging.Formatter("{message}", style="{")
# handler for log message with level < warning, prints to stdout
output_handler = logging.StreamHandler(stdout)
output_handler.setLevel(logging.INFO)
# only log messages INFO <= log record level < WARNING to stdout
output_handler.addFilter(lambda r: r.levelno < logging.WARNING)
# only log messages handled by the root logger (i.e. within __main__) or in a list of names of other log names to handle
output_handler.addFilter(lambda r: any([r.name.startswith(name) for name in terminal_logger_names]) or r.name == "root")
output_handler.setFormatter(terminal_formatter)
# handler for log message with level >= warning, prints to stderr
error_handler = logging.StreamHandler(stderr)
# Only handle log records >= WARNING on stderr
error_handler.setLevel(logging.WARNING)
# Intentionally NOT filtering source of message for log messages > WARNING.
# You proabably want to know these regardless of source so you can fix them
error_handler.setFormatter(terminal_formatter)
# typically, you would only configure in the __main__ module of your code
# with the log output of anything imported by it also configured here if
# if you want to handle it differently. The below config shows configuring
# the root logger i.e. the logger to which all logging messages eventually
# propagate unless handled and not propagated by a child logger
if __name__ == "__main__":
# sets up the root logger to log all messages as terminal output, with
# messages that are warnings or higher going to stderr and the rest to stdout
logging.basicConfig(
handlers=[output_handler, error_handler],
level=logging.INFO
)
# capture any warnings produced with using the warnings module
logging.captureWarnings(True)
try:
# Your code goes here
...
except Exception as e:
# catch and log any unhandled exceptions from your code
logging.exception(str(e))
exit(1)
finally:
# ensures any log data not written to file or terminal is handled before exiting
logging.shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment