Python - Logging
Overview
Estimated time: 25–35 minutes
The logging
module provides a flexible framework for application logs. Learn practical configuration, handlers/formatters, and patterns that scale from scripts to services.
Learning Objectives
- Use logger hierarchies and levels effectively.
- Configure handlers and formatters (console/file) without global side-effects.
- Adopt best practices for parameterized logging and structured output.
Prerequisites
- Exceptions and basic modules
Examples
import logging
logger = logging.getLogger("app")
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
fmt = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler.setFormatter(fmt)
logger.addHandler(handler)
logger.info("starting app version=%s", "1.0")
try:
1/0
except ZeroDivisionError:
logger.exception("division failed")
Expected Output: time-stamped lines including level, logger name, and message; stacktrace logged by exception()
.
Common Pitfalls
- Using f-strings for logging: prefers parameterized logging (
logger.info("x=%s", x)
) to avoid formatting when disabled. - Configuring root logger implicitly from a library; instead, configure in the application entry point.
- Duplicate logs from multiple handlers; watch for propagation (
logger.propagate = False
when appropriate).
Best Practices
- Centralize configuration (e.g., in
main
) and expose loggers vialogging.getLogger(__name__)
in modules. - Prefer structured logging (JSON) for services; include request IDs, user IDs, etc.
- Use appropriate levels: DEBUG/INFO/WARNING/ERROR/CRITICAL; keep logs actionable.
Checks for Understanding
- Why is parameterized logging preferred to f-strings?
- How do you prevent a child logger’s messages from being duplicated?
Show answers
- It defers formatting unless the message will be emitted and is often faster and safer.
- Set
logger.propagate = False
or adjust handlers/levels so they aren’t attached multiple times.
Exercises
- Configure rotating file logs using
RotatingFileHandler
with a max size and backups. - Emit JSON-structured logs (use
json.dumps
in a custom Formatter or a library).