Simple logger helper
Project description
🚀 Logger Migration Guide - 5 Minutes
Quick Setup
Step 1: Save logger.py
Save the logger.py file in your project root.
Step 2: Replace print() statements
Find & Replace in your entire project:
# OLD → NEW
print(f"✅ {message}") → success(message)
print(f"❌ {message}") → error(message)
print(f"⚠️ {message}") → warn(message)
print(f"ℹ️ {message}") → info(message)
print(f"🐛 {message}") → bug(message)
print(f"DEBUG: {message}") → bug(message)
Step 3: Add import at top of each file
from logger import bug, info, warn, error, success
That's it! ✅
Real Example: Update main.py
BEFORE (your current code):
@app.get("/auth/callback")
async def callback(request: Request):
print(f"\n{'='*60}")
print(f"🔄 OAuth Callback Received")
print(f" Query params: {dict(request.query_params)}")
try:
result = await auth.handle_callback(request)
print(f" ✅ Auth successful!")
print(f" User: {result.get('user', {}).get('email')}")
print(f"{'='*60}\n")
return create_auth_response(result, provider)
except Exception as e:
print(f" ❌ Callback error: {e}")
traceback.print_exc()
print(f"{'='*60}\n")
raise
AFTER (with logger):
from logger import info, error, success
@app.get("/auth/callback")
async def callback(request: Request):
info("OAuth callback received", params=dict(request.query_params))
try:
result = await auth.handle_callback(request)
success("Auth successful", user=result.get('user', {}).get('email'))
return create_auth_response(result, provider)
except Exception as e:
error("Callback error", exc_info=True)
raise
Benefits:
- ✅ Cleaner code (50% less lines)
- ✅ Automatic file/line detection
- ✅ Structured data (JSON in production)
- ✅ Color coding in development
- ✅ Exception tracing with
exc_info=True
Common Patterns
Pattern 1: Simple Message
# OLD
print("User logged in")
# NEW
info("User logged in")
Pattern 2: Message with Data
# OLD
print(f"User {user_id} logged in from {ip}")
# NEW
info("User logged in", user_id=user_id, ip=ip)
Pattern 3: Error with Stack Trace
# OLD
try:
something()
except Exception as e:
print(f"Error: {e}")
traceback.print_exc()
# NEW
try:
something()
except Exception as e:
error("Operation failed", exc_info=True)
Pattern 4: Debug Info
# OLD
print(f"DEBUG: Processing {len(items)} items")
# NEW
bug("Processing items", count=len(items))
Pattern 5: Success Messages
# OLD
print("✅ Payment processed successfully")
# NEW
success("Payment processed", order_id=order_id, amount=amount)
Update Your Files
main.py
# Add at top
from logger import bug, info, warn, error, success, log_request, Timer
# Replace all print() statements
# Use @log_request decorator on endpoints
Auth.py
# Add at top
from logger import bug, info, warn, error, success
# Replace logger.info() with info()
# Replace logger.error() with error()
# Replace logger.warning() with warn()
oauth.py
# Add at top
from logger import bug, info, warn, error, success
# Same replacements as Auth.py
google_auth.py
# Add at top
from logger import bug, info, warn, error, success
# Replace logger.info() with info()
# etc.
Advanced Features
1. Timing Operations
from logger import Timer
timer = Timer()
# ... do something ...
timer.log("Database query completed") # Logs with elapsed time
2. Log Code Blocks
from logger import log_block
with log_block("Processing payment"):
validate_payment()
charge_card()
send_confirmation()
# Automatically logs start/end with timing
3. Decorate Functions
from logger import log_function_call
@log_function_call
def calculate_total(items):
return sum(item.price for item in items)
# Automatically logs input/output
4. Decorate API Endpoints
from logger import log_request
@app.get("/api/users")
@log_request("API")
async def get_users():
return users
# Automatically logs request/response
Configuration
Development Mode (default)
# .env
ENVIRONMENT=development
Output:
- Colored console
- Emojis
- Shows DEBUG logs
- Pretty format
Production Mode
# .env
ENVIRONMENT=production
LOG_FILE=/var/log/app.log # Optional: log to file
Output:
- JSON format
- No DEBUG logs
- Machine readable
- Optimized performance
Change Level Dynamically
from logger import set_level
# In development, show everything
set_level('DEBUG')
# In staging, hide debug
set_level('INFO')
# In production, only warnings+
set_level('WARNING')
Migration Checklist
- Save
logger.pyin project root - Add
from logger import bug, info, warn, error, successto each file - Replace
print()with logger functions - Replace
logger.info()withinfo() - Replace
logger.error()witherror() - Replace
logger.warning()withwarn() - Add
exc_info=Trueto error() calls where you want stack traces - Test in development mode
- Test in production mode
Comparison
Without Logger (Current)
print(f"\n{'='*60}")
print(f"📝 Profile Request")
print(f" Cookies: {list(request.cookies.keys())}")
print(f" Has token: {'access_token' in request.cookies}")
try:
user = await get_user(request)
print(f" ✅ User: {user.get('email')}")
print(f"{'='*60}\n")
return user
except Exception as e:
print(f" ❌ Error: {e}")
print(traceback.format_exc())
print(f"{'='*60}\n")
raise
Issues:
- ❌ Manual formatting
- ❌ No structure
- ❌ Can't filter by level
- ❌ No machine-readable format
- ❌ Hard to search logs
- ❌ Verbose code
With Logger (New)
info("Profile request",
cookies=list(request.cookies.keys()),
has_token='access_token' in request.cookies)
try:
user = await get_user(request)
success("User retrieved", email=user.get('email'))
return user
except Exception as e:
error("Profile fetch failed", exc_info=True)
raise
Benefits:
- ✅ Clean code
- ✅ Structured data
- ✅ Filterable logs
- ✅ JSON output in prod
- ✅ Searchable logs
- ✅ Concise
Log Levels Guide
| Function | Level | Use For | Production |
|---|---|---|---|
bug() |
DEBUG | Development debugging | Hidden |
info() |
INFO | Normal operations | Shown |
success() |
SUCCESS | Positive outcomes | Shown |
warn() |
WARNING | Potential issues | Shown |
error() |
ERROR | Errors | Shown |
critical() |
CRITICAL | System failures | Shown |
Pro Tips
1. Use bug() for Development
bug("User data", user=user.__dict__) # Only shows in dev
2. Use Structured Data
# BAD
info(f"User {user_id} from {country} bought {item}")
# GOOD
info("Purchase", user_id=user_id, country=country, item=item)
3. Add Context
info("API call",
endpoint="/api/users",
method="GET",
user_id=current_user.id,
duration_ms=123)
4. Use exc_info for Errors
try:
risky_operation()
except Exception:
error("Operation failed", exc_info=True) # Includes full stack trace
5. Time Long Operations
from logger import Timer
timer = Timer()
result = long_database_query()
timer.log("Query completed", rows=len(result))
Testing
Run your app:
python main.py
You'll see (development mode):
12:34:56.789 │ ℹ️ │ INFO │ main.py:42 │ Server starting │ {"port": 9000}
12:34:56.890 │ ✅ │ SUCCESS │ auth.py:156 │ Auth initialized
12:34:57.123 │ ℹ️ │ INFO │ main.py:50 │ Server ready
In production (JSON):
{"timestamp":"2025-01-15T12:34:56.789","level":"INFO","message":"Server starting","file":"main.py","line":42,"data":{"port":9000}}
{"timestamp":"2025-01-15T12:34:56.890","level":"SUCCESS","message":"Auth initialized","file":"auth.py","line":156}
Summary
Before:
- Using
print() - 500+ lines of formatting code
- Unstructured logs
- Hard to debug in production
After:
- Using
bug(),info(),error(), etc. - Clean, readable code
- Structured JSON logs
- Easy debugging everywhere
Effort: 10 minutes
Impact: Huge! 🚀
Need Help?
Q: Will this break my existing code?
A: No! You can gradually migrate. Old print() still works.
Q: What about existing logger.info()?
A: Just replace with info() - same functionality, better output.
Q: Performance impact?
A: Minimal. Actually faster in production (optimized JSON output).
Q: Can I use both print() and logger?
A: Yes, but better to stick with logger for consistency.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bugboy-0.0.2.tar.gz.
File metadata
- Download URL: bugboy-0.0.2.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efb2987d10cc0cfaaca2ab0c21c6b561ea4a7d94eed33d057790097769a503c6
|
|
| MD5 |
c4ec11da060872845423742c097ea9a9
|
|
| BLAKE2b-256 |
06a6c4f084697d19dfeb3126cab7929b7781e9f402e4ac3817e72568e2507e57
|
File details
Details for the file bugboy-0.0.2-py3-none-any.whl.
File metadata
- Download URL: bugboy-0.0.2-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
333aabb3daf5f79d0a5f84a867ed66f1ab3d7d5a10559a24e608044e55dcff1d
|
|
| MD5 |
59c91db6684622b685945b4c4555d36f
|
|
| BLAKE2b-256 |
ba008c69d8f4d0bef956b78408368b10310bef79daeec5ba0814cf9e919133c7
|