tags: python-logging, formatting, datetime

Let’s talk about logging in Python because who doesn’t love staring at walls of text that tell you what went wrong? But seriously, logging is a crucial part of any software development process. It helps us identify and fix issues quickly, and it can also provide valuable insights into how our code performs over time.

So let’s dive in! First things first why should we use Python’s built-in logging module instead of just printing stuff to the console? Well, for starters, logs are more structured than regular output. They typically include a timestamp, log level (e.g., debug, info, warning), and a message that describes what happened. This makes it easier to filter out noise and focus on important events.

Here’s an example of how you might use the logging module in your code:

# Import the logging module
import logging

# Configure the logging module to write to a file named 'myapp.log' and set the logging level to DEBUG
logging.basicConfig(filename='myapp.log', level=logging.DEBUG)

# Define a function named 'my_function'
def my_function():
    # Add a debug log message to indicate the start of the function
    logging.debug('Starting function')
    try:
        # Perform some operations here...
        # Call a function named 'expensive_calculation' and store the result in a variable named 'result'
        result = expensive_calculation()
        # Add an info log message to indicate the successful calculation and include the result in the message
        logging.info(f'Calculated {result}')
    # If an exception occurs, log the error message and include the exception information
    except Exception as e:
        logging.error(str(e), exc_info=True)
    
    # Add a debug log message to indicate the end of the function
    logging.debug('Finished function')

In this example, we first configure the logger to write logs to a file called `myapp.log`. We also set the log level to DEBUG, which means that all messages (including debug-level ones) will be written to the log.

When our function runs, it prints some debug messages and an info message if everything goes well. If there’s an error, we print an error message with the exception stack trace included.

Now formatting! By default, logs are printed in a pretty basic format: ` `. But you can customize this by passing a string to the `format` argument of the logger configuration function (in our example, we used `basicConfig()`). Here’s an example that includes timestamps and log levels:

# Import the logging module
import logging
# Import the datetime module
from datetime import datetime

# Configure the logger to write to a file named 'myapp.log' and set the logging level to DEBUG
logging.basicConfig(filename='myapp.log', level=logging.DEBUG)

# Define a function named 'my_function'
def my_function():
    # Do some stuff here...
    # Get the current datetime
    now = datetime.now()
    # Format the datetime to a string in the format of 'YYYY-MM-DD HH:MM:SS'
    formatted_time = now.strftime('%Y-%m-%d %H:%M:%S')
    # Log a DEBUG message with the current datetime
    logging.debug(f'Starting function at {formatted_time}')
    try:
        # More stuff...
        # Perform an expensive calculation and store the result in a variable named 'result'
        result = expensive_calculation()
        # Convert the result to a string and right-align it for easier reading
        formatted_result = str(result).rjust(10)
        # Log an INFO message with the formatted result and the current datetime
        logging.info(f'Calculated {formatted_result} at {formatted_time}')
    # If an exception occurs, log an ERROR message with the exception and its traceback
    except Exception as e:
        logging.error(str(e), exc_info=True)
    
    # Get the current datetime again
    now = datetime.now()
    # Format the datetime to a string in the format of 'YYYY-MM-DD HH:MM:SS'
    formatted_time = now.strftime('%Y-%m-%d %H:%M:%S')
    # Log a DEBUG message with the current datetime
    logging.debug(f'Finished function at {formatted_time}')

In this example, we format the timestamp using Python’s built-in `datetime` module and then include it in our log messages. We also right-align the results for easier reading (because who doesn’t love a good spreadsheet?).

And that’s all there is to it! Logging may seem like a small detail, but it can make a big difference when you’re trying to debug issues or optimize performance.

SICORPS