Master Multi‑Environment Logging in Python with Loguru

This guide walks you through configuring Loguru for dev, test, and prod environments, adding dynamic log levels, colorized console output, file rotation, JSON serialization, remote extensions, and packaging the logger as a reusable Python module.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Master Multi‑Environment Logging in Python with Loguru

Goal

🧩 Multi‑environment configuration (dev, test, prod)

🔐 Dynamic log level setting

📁 File writing with automatic rotation (size/time)

💻 Colorful console output

📦 Structured logs in JSON format

🌐 Extensible to remote log sinks such as HTTP, Kafka, Sentry

1. Recommended directory layout

project_root/
├── config/
│   └── logging_config.py   # logging configuration per environment
├── utils/
│   └── logger.py           # wrapper around Loguru
├── logs/                  # auto‑generated log files
│   └── app.log
├── main.py                # example entry point
└── requirements.txt       # dependencies

2. Install dependencies

pip install loguru python-dotenv

3. Complete code implementation

3.1 config/logging_config.py

# config/logging_config.py
import os
LOGGING_CONFIG = {
    "dev": {
        "level": "DEBUG",
        "sink": "logs/app.log",
        "rotation": "10 MB",
        "retention": "7 days",
        "colorize": True,
        "serialize": False,
    },
    "test": {
        "level": "INFO",
        "sink": "logs/test_app.log",
        "rotation": "5 MB",
        "retention": "3 days",
        "colorize": True,
        "serialize": True,  # JSON for easier analysis
    },
    "prod": {
        "level": "WARNING",
        "sink": "logs/prod_app.log",
        "rotation": "1 day",
        "retention": "30 days",
        "colorize": False,
        "serialize": True,
    }
}
# Determine current environment (default to dev)
ENV = os.getenv("APP_ENV", "dev")
CONFIG = LOGGING_CONFIG[ENV]

3.2 utils/logger.py

# utils/logger.py
from loguru import logger
import sys, os
from config.logging_config import CONFIG, ENV

def setup_logger():
    # Ensure log directory exists
    log_dir = os.path.dirname(CONFIG["sink"])
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    # Remove default sink
    logger.remove()
    # Console sink (colorized based on environment)
    logger.add(
        sys.stderr,
        level=CONFIG["level"],
        colorize=CONFIG.get("colorize", True),
        format="{time:YYYY-MM-DD HH:mm:ss}|{level}|{message}"
    )
    # File sink
    logger.add(
        CONFIG["sink"],
        rotation=CONFIG["rotation"],
        retention=CONFIG["retention"],
        level="DEBUG",  # write all levels to file
        serialize=CONFIG.get("serialize", False),
        encoding="utf-8"
    )
    logger.info(f"Logger initialized in {ENV.upper()} mode")
    return logger

# Global logger instance
logger = setup_logger()

3.3 main.py

# main.py
from utils.logger import logger

def main():
    logger.debug("This is a DEBUG level log")
    logger.info("This is an INFO level log")
    logger.warning("This is a WARNING level log")
    logger.error("This is an ERROR level log")

if __name__ == "__main__":
    main()

4. Running and switching environments

Set the APP_ENV environment variable to choose the logging behavior.

🟢 Development (dev) APP_ENV=dev python main.py Outputs all logs to the terminal and logs/app.log with colored output.

🟡 Testing (test) APP_ENV=test python main.py Writes JSON logs to logs/test_app.log; console shows INFO and above.

🔴 Production (prod) APP_ENV=prod python main.py Writes JSON logs to logs/prod_app.log; only WARNING and above are recorded, without colors, suitable for log aggregation systems.

5. Example of a serialized JSON log (when serialize=True )

{
  "elapsed": "0:00:00.001234",
  "exception": null,
  "extra": {},
  "file": {"name": "main.py", "path": "/path/to/main.py"},
  "function": "main",
  "level": {"icon": "⚠️", "name": "WARNING", "no": 30},
  "line": 7,
  "message": "This is a WARNING level log",
  "module": "main",
  "thread": {"id": 12345, "name": "MainThread"},
  "time": "2025-04-05T10:34:56.123456Z"
}

6. Optional advanced features

7. Packaging for reuse (optional)

pip install setuptools wheel
# Build the distribution
python setup.py sdist bdist_wheel
# Upload to PyPI or a private repository
 twine upload dist/*

8. Conclusion

The article demonstrates how to build a flexible, multi‑environment logging solution with Loguru, covering configuration, code implementation, runtime switching, JSON serialization, and optional packaging for team-wide reuse.

CLIPythonJSONloggingLoguruMulti-Environment
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.