Advanced Logging Tutorial

Alright, logging that thing you do when your program is acting up like a spoiled brat in the middle of Target on Black Friday. But instead of screaming at it or throwing it across the room (which we all know can be tempting), we’re going to use some fancy Python code to log its every move and figure out what went wrong.

Before anything else, let’s import our logging library:

# Import the logging library
import logging

# Set the logging level to DEBUG
logging.basicConfig(level=logging.DEBUG)

# Define a function to log the movements of the brat
def log_movements(movements):
    # Loop through each movement in the list
    for movement in movements:
        # Log the movement at the DEBUG level
        logging.debug("The brat moved: %s", movement)

# Create a list of movements for the brat
movements = ["ran in circles", "threw toys", "screamed"]

# Call the log_movements function with the list of movements
log_movements(movements)

# Output:
# DEBUG:root:The brat moved: ran in circles
# DEBUG:root:The brat moved: threw toys
# DEBUG:root:The brat moved: screamed

Now that we have the library loaded up, let’s create a logger object for our program:

# Import the logging library
import logging

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

# The logger object will be used to log messages and errors throughout the program

# Example of logging a message
logger.info("This is a message") # Logs a message with the level of "info"

# Example of logging an error
try:
    # Some code that may raise an error
    result = 1/0
except ZeroDivisionError as e:
    logger.error("An error occurred: {}".format(e)) # Logs the error message with the level of "error"

This line of code creates an instance of the `logging.Logger` class and sets it to the current module name (which is automatically set by Python). This allows us to easily identify which part of our program is causing issues when we look at our logs later on.

Next, let’s add a handler for our logger object:

# Create an instance of the `logging.Logger` class and set it to the current module name
logger = logging.getLogger(__name__) # `__name__` is a special variable that holds the name of the current module

# Add a handler for our logger object
handler = logging.StreamHandler() # `StreamHandler` is a handler that sends log records to a stream (in this case, the console)
logger.addHandler(handler) # `addHandler` adds the specified handler to the logger object, allowing it to handle log records

# Now our logger is ready to use! We can start logging messages using different levels such as `debug`, `info`, `warning`, `error`, `critical`
logger.debug("This is a debug message") # `debug` is the lowest level, used for detailed information for debugging purposes
logger.info("This is an info message") # `info` is used for general information about the program's execution
logger.warning("This is a warning message") # `warning` is used for potential issues that may cause problems in the future
logger.error("This is an error message") # `error` is used for errors that caused the program to fail
logger.critical("This is a critical message") # `critical` is the highest level, used for serious errors that may lead to the program's termination

This line creates an instance of the `logging.StreamHandler` class and sets it as a handler for our logger object. This means that any log messages we send to our logger will be printed out on the console (which is handy for debugging purposes).

Now let’s set up some logging levels:

# Create an instance of the logging.StreamHandler class and set it as a handler for our logger object
handler = logging.StreamHandler()

# Set the logging level for our logger to DEBUG
logger.setLevel(logging.DEBUG)

# Set the logging level for our handler to ERROR
handler.setLevel(logging.ERROR)

This line sets the log level for our logger object to `debug`, which means that we will see all log messages (including debug-level messages). However, since we only want to see error-level messages from our handler, we set its log level to `error`. This allows us to filter out any unnecessary noise in our logs.

Finally, let’s write some code to actually generate some log messages:

# This script is used to generate log messages at different levels using the logger module in python.

# First, we import the logger module from the logging library.
import logging

# Next, we create a logger object and set its name to 'my_logger'.
logger = logging.getLogger('my_logger')

# We then set the log level of the logger to 'DEBUG', which means we will see all log messages (including debug-level messages).
# However, since we only want to see error-level messages from our handler, we set its log level to 'ERROR'.
# This allows us to filter out any unnecessary noise in our logs.
logger.setLevel(logging.ERROR)

# Now, we create a handler object and set its log level to 'DEBUG'.
# This means that it will handle all log messages at the 'DEBUG' level and above.
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)

# We then create a formatter object and set its format to include the log level and the message.
formatter = logging.Formatter('%(levelname)s: %(message)s')

# Next, we add the formatter to the handler.
handler.setFormatter(formatter)

# Finally, we add the handler to the logger.
logger.addHandler(handler)

# Now, let's write some code to actually generate some log messages.
# We define a function called 'my_function' which will be used to generate the log messages.
def my_function():
    # We use the logger object to generate log messages at different levels.
    logger.debug('This is a debug message') # This message will not be displayed since the log level is set to 'ERROR'.
    logger.info('This is an info message') # This message will not be displayed since the log level is set to 'ERROR'.
    logger.warning('This is a warning message') # This message will not be displayed since the log level is set to 'ERROR'.
    logger.error('This is an error message') # This message will be displayed since the log level is set to 'ERROR'.
    logger.critical('This is a critical message') # This message will be displayed since the log level is set to 'ERROR'.

# We call the function to generate the log messages.
my_function()

# Output:
# ERROR: This is an error message
# CRITICAL: This is a critical message

When we run this code, our log messages will be printed out on the console (assuming that `my_function()` was called). Here’s what it might look like:

# This script is used to print out log messages on the console, assuming that `my_function()` was called.

# Import the logging module to enable logging functionality
import logging

# Set the logging level to DEBUG, which will print all log messages
logging.basicConfig(level=logging.DEBUG)

# Define the `my_function()` function
def my_function():
    # Print out different types of log messages using the logging module
    logging.debug("This is a debug message") # Prints a debug message
    logging.info("This is an info message") # Prints an info message
    logging.warning("This is a warning message") # Prints a warning message
    logging.error("This is an error message") # Prints an error message
    logging.critical("This is a critical message") # Prints a critical message

# Call the `my_function()` function
my_function()

# Output:
# DEBUG:root:This is a debug message
# INFO:root:This is an info message
# WARNING:root:This is a warning message
# ERROR:root:This is an error message
# CRITICAL:root:This is a critical message

And that’s it! You now have a basic understanding of how to use Python logging. Of course, there are many more advanced features and options available (such as file handlers, rotating log files, etc.), but this should give you a good starting point for your own projects.

SICORPS