Logging
Python · Reference cheat sheet
Logging
Python · Reference cheat sheet
📋 Overview
The logging module is the standard way to record program events. Prefer it over print for libraries and services. Configure once at the app entrypoint; modules use logging.getLogger(__name__).
🔧 Core concepts
| Piece | Role |
|---|---|
| Logger | Named channel (getLogger) |
| Level | DEBUG INFO WARNING ERROR CRITICAL |
| Handler | Destination (stderr, file, syslog) |
| Formatter | Message layout |
| Filter | Extra include/exclude rules |
| Propagation | Child → parent loggers |
Root logger defaults to WARNING. Libraries should not call basicConfig; apps should.
💡 Examples
Module logger:
import logging
log = logging.getLogger(__name__)
def work(n: int) -> int:
log.debug("start n=%s", n)
if n < 0:
log.error("invalid n=%s", n)
raise ValueError(n)
log.info("ok")
return n * 2basicConfig for scripts:
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
)
logging.getLogger(__name__).info("boot")File + stderr handlers:
import logging
from pathlib import Path
def setup(log_path: Path) -> None:
root = logging.getLogger()
root.setLevel(logging.DEBUG)
fmt = logging.Formatter("%(levelname)s %(message)s")
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
sh.setFormatter(fmt)
fh = logging.FileHandler(log_path, encoding="utf-8")
fh.setLevel(logging.DEBUG)
fh.setFormatter(fmt)
root.handlers.clear()
root.addHandler(sh)
root.addHandler(fh)exception helper:
import logging
log = logging.getLogger("app")
try:
1 / 0
except ZeroDivisionError:
log.exception("divide failed") # includes traceback⚠️ Pitfalls
- Eager f-strings in log calls allocate even if level is filtered — use
%slazy args. - Multiple
basicConfigcalls are no-ops if handlers already exist. - Catching exceptions without
log.exceptionloses stack traces. - Don't log secrets (tokens, passwords).
- Avoid configuring logging inside importable libraries.