0Pricing
Python Academy · Lesson

Handlers, Formatters, and Filters

Route log output to files, streams, and custom destinations.

Handlers, Formatters, and Filters is a free Python Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Handlers Route Log Records

A handler sends log records to a destination: console, file, HTTP endpoint, etc. One logger can have multiple handlers.

import logging

logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)

sh = logging.StreamHandler()
logger.addHandler(sh)

logger.info("Goes to console")

StreamHandler

StreamHandler writes to a stream (default sys.stderr). Pass sys.stdout for stdout output.

import logging, sys

logger = logging.getLogger("out")
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
logger.warning("printed to stdout")

FileHandler

FileHandler appends records to a file. Use mode="w" to overwrite on each run.

import logging

logging.basicConfig(
    filename="app.log",
    filemode="a",
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s"
)
logging.info("Persisted to disk")

RotatingFileHandler

Automatically rotate log files when they exceed a size limit, keeping N backup files.

from logging.handlers import RotatingFileHandler
import logging

handler = RotatingFileHandler(
    "app.log", maxBytes=1_000_000, backupCount=5
)
logging.getLogger().addHandler(handler)

TimedRotatingFileHandler

Rotate log files on a time schedule — daily, weekly, or by hour — ideal for long-running services.

from logging.handlers import TimedRotatingFileHandler
import logging

handler = TimedRotatingFileHandler(
    "app.log", when="midnight", backupCount=7
)
logging.getLogger().addHandler(handler)

Formatters

A Formatter controls the text layout of each log record. Attach it to a handler with handler.setFormatter().

import logging

fmt = logging.Formatter(
    fmt="%(asctime)s %(levelname)-8s %(name)s — %(message)s",
    datefmt="%Y-%m-%dT%H:%M:%S"
)
handler = logging.StreamHandler()
handler.setFormatter(fmt)
logging.getLogger().addHandler(handler)

Handler-level Filtering

Each handler has its own level. A record must pass both the logger level and the handler level to be emitted.

import logging

logger = logging.getLogger("app")
logger.setLevel(logging.DEBUG)   # logger passes DEBUG+

err_handler = logging.FileHandler("errors.log")
err_handler.setLevel(logging.ERROR)  # only ERROR+
logger.addHandler(err_handler)

Custom Filters

Subclass logging.Filter and override filter(record) to accept or reject records by any criterion.

import logging

class SensitiveFilter(logging.Filter):
    def filter(self, record):
        return "password" not in record.getMessage().lower()

handler = logging.StreamHandler()
handler.addFilter(SensitiveFilter())
logging.getLogger().addHandler(handler)

Adding Extra Fields with a Filter

Filters can also mutate the record to inject additional fields (e.g., request ID) before formatting.

import logging

class RequestIDFilter(logging.Filter):
    def __init__(self, request_id):
        self.request_id = request_id
    def filter(self, record):
        record.request_id = self.request_id
        return True

# fmt: "%(request_id)s %(message)s"

Multiple Handlers on One Logger

Add several handlers to send the same log records to multiple destinations simultaneously.

import logging

logger = logging.getLogger("multi")
logger.addHandler(logging.StreamHandler())             # console
logger.addHandler(logging.FileHandler("audit.log"))   # file
logger.setLevel(logging.INFO)
logger.info("Both destinations receive this")

Disabling Propagation

Set logger.propagate = False to stop records from bubbling up to the root logger and being double-logged.

import logging

logger = logging.getLogger("mylib")
logger.propagate = False   # stays here, does not reach root
logger.addHandler(logging.StreamHandler())

Quick Check

What method attaches a Formatter to a Handler?

Recap

Handlers route records; formatters style them; filters selectively pass or block them. Use RotatingFileHandler for size-limited logs and TimedRotatingFileHandler for date-based rotation.

Frequently asked questions

Is the “Handlers, Formatters, and Filters” lesson free?

Yes — the full text of “Handlers, Formatters, and Filters” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.

What will I learn in “Handlers, Formatters, and Filters”?

Route log output to files, streams, and custom destinations. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Handlers, Formatters, and Filters” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The logging Module Basics
  2. Handlers, Formatters, and Filters
  3. Structured Logging
  4. Debugging with pdb
← Back to Python Academy