Python Loguru Modern Logging — Core Concepts
Loguru is a third-party logging library that replaces Python’s standard logging module with a friendlier API. It became popular because it eliminates the boilerplate that trips up beginners and annoys experienced developers alike.
Why developers switch to Loguru
The standard library requires you to create a logger, attach a handler, assign a formatter, and set levels — four separate concepts before you see a single log line. Loguru collapses this into one pre-configured logger object.
| Standard library | Loguru |
|---|---|
logging.getLogger(__name__) | from loguru import logger |
Create StreamHandler, set level, add formatter | Defaults to colorized stderr |
RotatingFileHandler with 3 parameters | logger.add("file.log", rotation="10 MB") |
| Custom exception formatting | Automatic full traceback with variable values |
Adding sinks
In Loguru, destinations are called sinks. A sink can be a file path, a function, a coroutine, or anything with a write() method.
from loguru import logger
# File with rotation and retention
logger.add("app.log", rotation="500 MB", retention="10 days")
# JSON format for log aggregation
logger.add("structured.log", serialize=True)
# Filter by level
logger.add("errors.log", level="ERROR")
Each add() call returns an ID you can use to remove the sink later with logger.remove(id).
Structured logging
Passing serialize=True to a sink converts every log record to a JSON object. This is critical for production systems where logs feed into Elasticsearch, Datadog, or Loki.
You can also bind extra fields:
order_logger = logger.bind(order_id="ORD-1234")
order_logger.info("Payment processed")
# JSON output includes {"order_id": "ORD-1234", ...}
Bound fields propagate through the logger context, so downstream code automatically includes them.
Exception catching
Loguru’s killer feature is @logger.catch:
@logger.catch
def process_order(order):
total = order["items"] * order["price"]
return total
If order["items"] raises a KeyError, Loguru logs the full traceback including the values of local variables at each frame. Standard logging only gives you the exception message and line numbers — Loguru shows you what order actually contained.
Context managers and patching
For request-scoped context (web servers, task queues), use logger.contextualize():
with logger.contextualize(request_id="abc-123"):
logger.info("Handling request")
do_work()
# All log lines inside this block include request_id
This replaces the standard library’s LoggerAdapter and filter patterns with a cleaner context manager.
Lazy evaluation
Expensive log messages can skip computation when the level is disabled:
logger.debug("User data: {data}", data=lambda: expensive_serialize(user))
The lambda only runs if DEBUG is active. The standard library requires if logger.isEnabledFor(logging.DEBUG) guards.
Compatibility with standard logging
Loguru can intercept standard library log records, so third-party libraries that use logging.getLogger() still route through Loguru:
import logging
class InterceptHandler(logging.Handler):
def emit(self, record):
level = logger.level(record.levelname).name
logger.opt(depth=6, exception=record.exc_info).log(level, record.getMessage())
logging.basicConfig(handlers=[InterceptHandler()], level=0)
This lets you adopt Loguru incrementally without rewriting every dependency.
Common misconception
“Loguru is only for small projects.” Companies like Robinhood and several YC startups use Loguru in production. The library handles millions of log lines per day. The real consideration isn’t scale but ecosystem lock-in: if you need fine-grained handler control (syslog integration, custom filters per module), the standard library’s explicit configuration may be more appropriate.
One thing to remember: Loguru trades explicit configuration for sensible defaults. For most applications, those defaults are better than what developers configure manually — making Loguru a genuine productivity win, not just syntactic sugar.
See Also
- Python Alerting Patterns Alerting is a smoke detector for your code — it wakes you up when something is burning, not when someone is cooking.
- Python Correlation Ids Correlation IDs are name tags for requests — they let you follow one visitor's journey through a crowded theme park of services.
- Python Grafana Dashboards Python Grafana turns boring numbers from your Python app into colorful, real-time dashboards — like a car's dashboard but for your code.
- Python Log Aggregation Elk ELK collects scattered log files from all your services into one searchable place — like gathering every sticky note in the office into a single filing cabinet.
- Python Logging Best Practices Treat logs like a flight recorder so you can understand failures after they happen, not just during development.