B20 - logging
import logging
logging.info("information")
log levels
-
debug reports information relevant to developers
-
info gives notifications, not errors
-
warning reports a problem that doesn't interrupt the normal use
-
error reports a noticeable problem
-
critical reports significant issues that crashes the program
-
by default, all levels below warning are supressed
logging.basicCongig(level = logging.INFO)
custom logger
rootis the name of the default logger- to create a custom logger:
- call
getLogger()and pass it a name - set a log level
- create a formatter with a format string. eg:
%(asctime) - %(levelname)s - %(message)s, where%(...)represents a place holder,sthat it is displayed as a string - associate the formatter with a handler
- call
import logging
handler = logging.StreamHandler()
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
custom_logger = logging.getLogger("custom_logger")
custom_logger.setLevel(logging.INFO)
custom_logger.addHandler(handler)
custom_logger.info("information")
exceptions
- the most commonly logged events
- logged using the
exceptionfunction - logs an error message with exception details
- only works in a
try-exceptblock - log exceptions at other levels with the
exc_infokeyword argument
try:
...
except exception as e:
logging.exception("error message")
example usage
logging.basicConfig(
level = logging.INFO,
format = "%(asctime)s - %(levelname)s - %(message)s",
)
- suppose one wants to log errors to a file, and info messages to the terminal
- this can be done using custom loggers for each
error_logger = logging.getLogger("error_logger")
info_logger = logging.getLogger("info_logger")
error_logger.setLevel(logging.ERROR)
info_logger.setLevel(logging.INFO)
error_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
info_formatter = logging.Formatter("%(levelname)s - %(message)s")
file_handler = logging.FileHandler("error.log") # file to log the errors
file_handler.setFormatter(error_formatter)
stream_handler = logging.StreamHandler() # logs in the terminal
stream_handler.setFormatter(info_formatter)
error_logger.addHandler(file_handler)
info_logger.addHandler(stream_handler)
loguru
pip install loguru
- it is a python package that simplifies logging with only a single logger object
- the default message format is much more useful
- log messages are colour-coded based on severity
- it is completely customisable

image: Pluralsight, Douglas Starnes
- trace is hidden by default
import sys
from loguru import logger
a = 10
logger.info(f"the value of a is {a}")
b = 50
a = b
logger.success(f"the value of a has been updated to {b}")
## customising
logger.remove # removes existing handlers
logger.add(
"logs/info_{time:YYYY-MM-DD_HH-mm-ss}.log", # log file
rotation = "5 seconds", # creates a new log file every 5 secs
retention = "30 seconds", # removes log files after 30 secs
sys.stderr,
format = "<yellow>{time: YYYY/MM/DD HH:mm}</yellow> - <b>{level}</b> - <i><green>{message}</i></green>",
serealize = True, # writes logs in JSON format
)
@logger.catch # logs error with detailed traceback
def ...