import logging from logging.config import dictConfig import os from logging.handlers import RotatingFileHandler, HTTPHandler def setup_logging(app): """Configure logging: console, optional file and external HTTP handler. Controlled by env vars: - LOG_FILE: path to write rotating logs - LOG_MAX_BYTES: max bytes per file (default 10MB) - LOG_BACKUP_COUNT: number of backups (default 5) - EXTERNAL_LOG_URL: if set, an HTTPHandler will POST logs to this URL """ level = logging.DEBUG if app.config.get("DEBUG") else logging.INFO handlers = { "console": { "class": "logging.StreamHandler", "formatter": "default", "level": level, } } root_handlers = ["console"] log_file = os.getenv("LOG_FILE") if log_file: # ensure parent dirs exist os.makedirs(os.path.dirname(log_file), exist_ok=True) handlers["file"] = { "class": "logging.handlers.RotatingFileHandler", "formatter": "default", "level": level, "filename": log_file, "maxBytes": int(os.getenv("LOG_MAX_BYTES", 10 * 1024 * 1024)), "backupCount": int(os.getenv("LOG_BACKUP_COUNT", 5)), } root_handlers.append("file") external = os.getenv("EXTERNAL_LOG_URL") if external: handlers["external"] = { "class": "logging.handlers.HTTPHandler", "formatter": "default", "level": level, "host": external, "url": "/", "method": "POST", } root_handlers.append("external") config = { "version": 1, "disable_existing_loggers": False, "formatters": { "default": { "format": "%(asctime)s %(levelname)s %(name)s: %(message)s", } }, "handlers": handlers, "root": { "handlers": root_handlers, "level": level, }, } dictConfig(config)