Size-Based Log File Rotation

Configure Python logging with a rotating file handler that caps file size, keeps numbered backups, and flushes each record.

PythonData Integrity

Code

snippet
import logging
import shutil
from logging.handlers import RotatingFileHandler
from pathlib import Path


def build_logger(
    path: str, *, max_bytes: int = 1_000_000, backups: int = 3
) -> logging.Logger:
    target = Path(path)
    target.parent.mkdir(parents=True, exist_ok=True)
    logger = logging.getLogger("demo.rotation")
    logger.setLevel(logging.INFO)
    logger.propagate = False
    if not logger.handlers:
        handler = RotatingFileHandler(
            target, maxBytes=max_bytes, backupCount=backups, encoding="utf-8"
        )
        handler.setFormatter(
            logging.Formatter("%(asctime)s %(levelname)s %(message)s")
        )
        logger.addHandler(handler)
    return logger


if __name__ == "__main__":
    log = build_logger("build/logs/app.log", max_bytes=300, backups=2)
    for index in range(12):
        log.info("request %d completed", index)
    for handler in log.handlers:
        handler.flush()
        handler.close()
    log.handlers.clear()
    files = sorted(path.name for path in Path("build/logs").glob("app.log*"))
    print("files:", files)
    print("latest:", Path("build/logs/app.log").read_text(encoding="utf-8").splitlines()[-1])
    shutil.rmtree("build")