Basic Setup
Python
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)
logger.debug("Diagnostic info")
logger.info("Normal event")
logger.warning("Unexpected but non-fatal")
logger.error("Something failed")
logger.critical("System cannot continue")File & Rotating Handlers
Python
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)
fmt = logging.Formatter("%(asctime)s | %(levelname)-8s | %(name)s:%(lineno)d | %(message)s")
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(fmt)
# Rotate at 5 MB, keep 3 backups
file_h = RotatingFileHandler("app.log", maxBytes=5_000_000, backupCount=3)
file_h.setLevel(logging.DEBUG)
file_h.setFormatter(fmt)
logger.addHandler(console)
logger.addHandler(file_h)Structured JSON Logging
Python
import json
class JSONFormatter(logging.Formatter):
def format(self, record):
entry = {
"time": self.formatTime(record),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
}
if record.exc_info:
entry["exception"] = self.formatException(record.exc_info)
return json.dumps(entry)
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logging.getLogger("api").addHandler(handler)Logging Exceptions
Python
try:
result = 10 / 0
except ZeroDivisionError:
logger.exception("Division failed") # Auto-includes traceback
logger.info("User login", extra={"user_id": 42, "ip": "127.0.0.1"})Tip: Use logging.getLogger(__name__) in every module β creates a hierarchy so you can control log levels per module.