Tutorial

Getting Started with Python's Logging Module

Learn why and how to use Python's built-in logging module instead of print statements. This guide covers log levels, formatting, real-world examples, and common pitfalls.

August 2026 7 min read 10 views 0 hearts

Getting Started with Python's Logging Module: A Practical Guide

If you've ever spent hours trying to debug a Python script by scattering print() statements everywhere, you know the pain. At PythonSkillset, we believe that understanding logging early can save you countless headaches and make your code truly production-ready.

Logging in Python isn't just about printing messages—it's about controlling what gets printed, where it goes, and when. The built-in logging module is incredibly powerful once you get past the initial learning curve.

Why Not Just Use print()?

Let's face it—we've all done it. Adding a quick print() to see what's happening in our code feels natural. But here's the problem: you eventually have to remove or comment out all those print statements. And when your application runs in production, you need different information than during development.

Logging gives you: - Different severity levels (debug, info, warning, error, critical) - Control over output (console, files, network) - Format control (timestamps, line numbers, module names) - Runtime configuration (change log levels without modifying code)

Setting Up Your First Logger

Let's start with the simplest possible setup. At PythonSkillset, we recommend beginning with a basic configuration and then building up from there.

import logging

# Basic configuration
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Create a logger
logger = logging.getLogger(__name__)

# Log some messages
logger.debug("This is a debug message")  # Won't appear because level is INFO
logger.info("Application started successfully")
logger.warning("Disk space is running low")
logger.error("Failed to connect to database")
logger.critical("System is shutting down")

When you run this, you'll see only the INFO, WARNING, ERROR, and CRITICAL messages. The DEBUG message is silenced because we set the level to INFO.

Understanding Log Levels

Python's logging has five standard levels, each with a numeric value:

Level Numeric Value When to Use
DEBUG 10 Detailed diagnostic information
INFO 20 Confirmation that things are working
WARNING 30 Something unexpected happened, but application continues
ERROR 40 A serious problem, but application continues
CRITICAL 50 A serious error, application may stop

The rule is simple: only messages at level >= the configured level will appear. This lets you filter noise during development and switch to more verbose logging when troubleshooting.

Adding Logging to a Real Application

Let's build something practical. Imagine you're working on a data processing pipeline for PythonSkillset's analytics system:

import logging
from datetime import datetime

# Configure logging for our application
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    filename='app.log'  # Write to file
)

logger = logging.getLogger('DataProcessor')

def process_user_data(user_data):
    logger.info(f"Processing data for user {user_data.get('id')}")

    try:
        # Simulate processing
        if not user_data.get('email'):
            logger.warning(f"User {user_data.get('id')} has no email address")

        # More processing...
        logger.debug(f"User data: {user_data}")  # Won't show in file

        return True
    except Exception as e:
        logger.error(f"Failed to process user {user_data.get('id')}: {str(e)}")
        return False

# Test it
users = [
    {"id": 1, "email": "user1@example.com"},
    {"id": 2, "email": None},
    {"id": 3, "email": "user3@example.com"}
]

for user in users:
    process_user_data(user)

Now check app.log—you'll see a clean, timestamped record of what happened. No more hunting through terminal output.

Formatting Your Logs

Good formatting makes logs readable and searchable. Here's what each format placeholder means:

  • %(asctime)s - Human-readable time
  • %(name)s - Logger name (usually __name__)
  • %(levelname)s - Log level (INFO, ERROR, etc.)
  • %(message)s - The actual message
  • %(filename)s - File where log was called
  • %(lineno)d - Line number
  • %(funcName)s - Function name

A practical format for production might be:

logging.basicConfig(
    format='%(asctime)s | %(levelname)-8s | %(filename)s:%(lineno)d | %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

Common Pitfalls to Avoid

After working with many Python developers at PythonSkillset, here are the mistakes we see most often:

  1. Using the root logger directly - Don't call logging.info(). Create your own logger with getLogger(__name__).
  2. Forgetting to set log levels - Without configuration, logging defaults to WARNING, so your INFO messages vanish.
  3. Logging sensitive information - Passwords, API keys, and personal data should never appear in logs.
  4. Over-logging in loops - Inside tight loops, use DEBUG level instead of INFO to avoid bloating your logs.

When to Use Each Level

Here's a rule of thumb that we follow at PythonSkillset:

  • DEBUG: Variable values, function entry/exit points, API call details
  • INFO: Application start/stop, successful operations, user actions
  • WARNING: Deprecated functions, low disk space, temporary failures
  • ERROR: Failed database connections, API errors, corrupted data
  • CRITICAL: System out of memory, security breaches, unrecoverable errors

Moving Forward

Once you've mastered basic logging, you can explore advanced features like: - Multiple handlers (console + file simultaneously) - Log rotation (automatically archive old logs) - Custom formatters - Child loggers for different modules

The key takeaway? Start small. Add logging to one module today. Tomorrow, you'll wonder how you ever lived without it. At PythonSkillset, we've seen this simple practice transform debugging from a frustrating chore into a straightforward process.

Your future self—the one trying to figure out why production code failed at 3 AM—will thank you.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.