Write Python logs to a file

Configure a file handler once, choose an explicit encoding and level, and add rotation and collection checks appropriate to your process model.

Best practices
Python programming and application logging

For a small application, configure logging.basicConfig(filename="app.log", level=logging.INFO). For more control, attach a FileHandler or RotatingFileHandler to a named logger.

Configure a simple file destination

import logging

logging.basicConfig(
    filename="app.log",
    filemode="a",
    encoding="utf-8",
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logging.info("Application started")
logging.warning("Disk space is low")

The encoding argument to basicConfig() requires Python 3.9+. File mode "a" appends; "w" truncates when that handler opens the file. A relative path is resolved from the process's working directory. Ensure the parent directory exists and is writable.

Call this before logging is configured elsewhere. basicConfig() normally does nothing when root already has handlers; a filename argument does not override that behavior.

Give a named logger its own handler

import logging

logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)
logger.propagate = False
handler = logging.FileHandler("app.log", encoding="utf-8")
handler.setFormatter(logging.Formatter(
    "%(asctime)s [%(levelname)s] %(message)s"
))
logger.addHandler(handler)
logger.info("Written to the application log")

This is an alternative configuration, intended to run once. Disabling propagation prevents an additional root handler from writing the same record. If root owns your application-wide logging, let module loggers propagate to it instead of configuring independent destinations everywhere.

Bound file growth

Replace the file-handler construction with:

from logging.handlers import RotatingFileHandler

handler = RotatingFileHandler(
    "app.log",
    maxBytes=10 * 1024 * 1024,
    backupCount=5,
    encoding="utf-8",
)

Attach and format it as in the previous example. Rotation retains numbered backups such as app.log.1 through app.log.5. The threshold is not a hard limit on every possible record: a single oversized record can exceed it.

Verify that collection continues across rollover. With DataKit log collection, check the configured path, read permissions, multiline handling, and record identifiers before and after rotation. Do not blindly collect both live and backup paths if that would duplicate records.

FAQ

Can I also write to the console? Add a StreamHandler with its own level and formatter to the same logger.

How do I avoid encoding problems? Write with an explicit encoding such as UTF-8 and configure the reader to use the same encoding.

Can several processes share a rotating file? Standard file handlers do not coordinate multiprocess rotation. Use a queue/listener, independent process files, or a logging service. A third-party handler such as ConcurrentRotatingFileHandler is another option only after checking its platform and locking requirements.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting