Logging Messages: Using {}- and $-formatting

To set the stage, let’s create a logger object to handle our log messages:

# Import the logging module
import logging

# Create a logger object with the name of the current module
logger = logging.getLogger(__name__)

# The getLogger() function returns a logger object with the specified name
# This allows us to easily identify where the log messages are coming from

# The __name__ variable contains the name of the current module
# This ensures that the logger object is specific to this module and not shared with other modules

# The logger object will be used to handle all log messages within this module

This creates a logger for the current module (which is handy if you have multiple modules in your project). If you want to use a different name or namespace, just replace `__name__` with whatever you’d like.
Now that we have our logger object, let’s configure it using some {}- and $-formatting goodness:

# Creates a logger for the current module and sets the log level to debug
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# Create a formatter for our logs
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')

# Add a handler to the logger object to send log messages to a file
handler = logging.FileHandler("logs/my_logfile.txt") # Change this path to wherever you want your logs to go
handler.setLevel(logging.DEBUG)
handler.setFormatter(formatter)
logger.addHandler(handler)

In the above code, we’re setting our log level to debug (you can change this depending on what you need), creating a formatter for our logs using {}- and $-formatting, adding a handler to send our messages to a file called `my_logfile.txt`, and then attaching that handler to the logger object.
Now let’s see how we can use these loggers in our code:

# Importing the necessary modules
import logging

# Creating a logger object with the name 'my_logger'
my_logger = logging.getLogger('my_logger')

# Setting the logging level to DEBUG
my_logger.setLevel(logging.DEBUG)

# Creating a formatter for our logs using {}- and $-formatting
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# Adding a handler to send our messages to a file called `my_logfile.txt`
file_handler = logging.FileHandler('my_logfile.txt')

# Setting the formatter for the file handler
file_handler.setFormatter(formatter)

# Attaching the file handler to the logger object
my_logger.addHandler(file_handler)

# Defining a function
def my_function():
    # Do some stuff here...

    # Logging a debug message
    my_logger.debug("This is a debug message")

    # Logging an info message
    my_logger.info("This is an info message")

    # Logging a warning message
    my_logger.warning("This is a warning message")

    # Logging an error message
    my_logger.error("This is an error message")

    # Logging a critical message
    my_logger.critical("This is a critical message")

# Calling the function
my_function()

# Output:
# A file named 'my_logfile.txt' will be created and it will contain the following log messages:
# 2021-10-12 12:00:00,000 - DEBUG - This is a debug message
# 2021-10-12 12:00:00,000 - INFO - This is an info message
# 2021-10-12 12:00:00,000 - WARNING - This is a warning message
# 2021-10-12 12:00:00,000 - ERROR - This is an error message
# 2021-10-12 12:00:00,000 - CRITICAL - This is a critical message

In the above code, we’re using our `logger` object to log messages at different levels (debug, info, warning, error, and critical).
And that’s it! You now have logging set up in your Python project using {}- and $-formatting. If you want to learn more about this feature or other ways of configuring the logger, check out the official documentation for the `logging` module.

SICORPS