Introduction
Loguru replaces Python's stdlib logging — universally loved for what it does but universally hated for its boilerplate. One import gives you colorized terminal output, structured context, file rotation, retention, compression, and beautiful exception diagnosis with variable values.
With over 20,000 GitHub stars, Loguru is the most popular alternative to stdlib logging and a default choice for new Python projects.
What Loguru Does
Loguru exposes a global logger. Call logger.info()/warning()/error() and it writes to stderr with colors. Add sinks (files, functions, coroutines) via logger.add() with optional rotation, retention, and format strings. Use logger.contextualize() or @logger.catch to capture context and wrap functions.
Architecture Overview
logger.info(message, **context)
|
[Record]
time, level, message,
module, function, line,
exception, extra context
|
[Formatter] --> "[{time}] {level} {message}"
|
[Sinks]
+-- sys.stderr (colorized)
+-- file("app.log", rotation="100 MB", retention="30 days", compression="zip")
+-- custom fn / coroutine / QueueSelf-Hosting & Configuration
from loguru import logger
import sys
logger.remove() # remove default stderr handler
logger.add(
sys.stderr,
level="INFO",
format="<green>{time:HH:mm:ss}</green> <level>{level}</level> {message}",
)
logger.add(
"logs/app_{time}.log",
rotation="50 MB",
retention="14 days",
compression="zip",
level="DEBUG",
enqueue=True, # thread/multiprocess safe
backtrace=True,
diagnose=True,
)
with logger.contextualize(request_id="abc-123", user="alice"):
logger.info("starting request")
do_work()
@logger.catch(reraise=True)
def risky():
return [][0]Key Features
- Zero config — works instantly, no handler/formatter setup
- Colorized output — readable in dev terminals
- File rotation — size, time, or custom function triggers
- Retention & compression — auto-delete old logs, zip/tar archives
- Async safe —
enqueue=Truefor multiprocessing and asyncio - Beautiful tracebacks — show variable values at every frame
- Structured context —
logger.contextualize()propagates fields - Exception catcher —
@logger.catchdecorator wraps functions
Comparison with Similar Tools
| Feature | Loguru | stdlib logging | structlog | Eliot | Logbook |
|---|---|---|---|---|---|
| Setup required | None | Extensive | Moderate | Moderate | Moderate |
| Colorized | Yes | No | Via renderer | No | Yes |
| Structured | Yes | Manual | Yes (focus) | Yes | Partial |
| Rotation | Built-in | Via handler | Via sink | External | Built-in |
| Traceback w/ values | Yes | No | No | Partial | No |
| Best For | Any Python app | Library code | Structured JSON | Causal logs | Legacy |
FAQ
Q: Can I use Loguru with stdlib logging? A: Yes. Add an InterceptHandler that forwards logging records to Loguru, and all library logs flow through Loguru sinks.
Q: Is Loguru production ready? A: Yes. Large companies use it in production. For libraries intended for others, prefer stdlib logging so users can configure it themselves.
Q: How do I emit JSON logs?
A: logger.add(sys.stdout, serialize=True) produces one JSON record per line — perfect for Loki, Datadog, or CloudWatch.
Q: Is the global logger a problem for testing?
A: Use caplog from pytest-loguru, or remove and re-add sinks in fixtures. Tests remain clean.
Sources
- GitHub: https://github.com/Delgan/loguru
- Docs: https://loguru.readthedocs.io
- Author: Delgan
- License: MIT