Skip to main content

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.py in project root
  • Add from logger import bug, info, warn, error, success to each file
  • Replace print() with logger functions
  • Replace logger.info() with info()
  • Replace logger.error() with error()
  • Replace logger.warning() with warn()
  • Add exc_info=True to 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bugboy-0.0.2.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bugboy-0.0.2-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

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

Hashes for bugboy-0.0.2.tar.gz
Algorithm Hash digest
SHA256 efb2987d10cc0cfaaca2ab0c21c6b561ea4a7d94eed33d057790097769a503c6
MD5 c4ec11da060872845423742c097ea9a9
BLAKE2b-256 06a6c4f084697d19dfeb3126cab7929b7781e9f402e4ac3817e72568e2507e57

See more details on using hashes here.

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

Hashes for bugboy-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 333aabb3daf5f79d0a5f84a867ed66f1ab3d7d5a10559a24e608044e55dcff1d
MD5 59c91db6684622b685945b4c4555d36f
BLAKE2b-256 ba008c69d8f4d0bef956b78408368b10310bef79daeec5ba0814cf9e919133c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page