Shift-Left Your Log Quality
loly is a Python logging linter that catches logging anti-patterns. Think of it as a very opinionated friend who cares deeply about your logs.
The Problem
You know that feeling at 3 AM when production is on fire? Your logs will definitely bite you at the worst possible hour. Here's what inevitably breaks:
- Missing stack traces: Exception logs without
exc_info=True? Congratulations, you've written the equivalent of "something went wrong" in Comic Sans. - Performance degradation: Unconditional logging in hot loops. Yes, logging 10,000 times per second is technically possible. Just because you can, does not mean you should.
- Inconsistent logging: Different logging patterns across services means your team spends quality time as amateur log archaeologists.
- No emojis or special chars in logs: Machine-parsable logs are non-negotiable. Stop trying to be cute in production logs.
The Solution
loly catches these annoyances before they happen—in your editor, during CI, before production melts down.
# Install the salvation device
uv pip install loly
# Run it like your life depends on it
loly path/to/code
# Make it mandatory in CI (it should be)
loly . --config=loly.yml
The Philosophy: Catch It Early (Or Else)
loly's approach: Stop logging problems before they become 3 AM horror stories.
- Fast feedback: See violations as you type—no waiting for production to explode
- Zero runtime cost: Static analysis only—we're not evil
- Team consistency: Stop fighting about logging patterns, start enjoying them
- Scale-friendly: Prevent the performance disaster before it bankrupts your AWS bill
Current Policies
| Code | Policy | What Happens If You Ignore It |
|---|---|---|
| LY001 | Exception exc_info | Ensure your logs in exception blocks have exc_info |
| LY002 | Log Loop | Ensure logging in loops is with conditional checks |
Quick Example
# LY001 violation
try:
connect_db()
except Exception:
logger.error("Connection failed")
# This is what heroes do
try:
connect_db()
except Exception:
logger.error("Connection failed", exc_info=True)
Why loly?
Zero config: Works out of the box.
Extensible: Add custom policies for your team's specific ways of shooting yourselves in the foot.
Complementary: Works beautifully with structlog, loguru, and friends. Doesn't compete with them
Python-native: Built with libcst for precision AST analysis.
Your future 3 AM self will thank you.