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.1.tar.gz (12.0 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.1-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file bugboy-0.0.1.tar.gz.

File metadata

  • Download URL: bugboy-0.0.1.tar.gz
  • Upload date:
  • Size: 12.0 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.1.tar.gz
Algorithm Hash digest
SHA256 bb9b8db7feac7f0ed90731d58473a5b61519908838f47831c2d4f1a6fdaac404
MD5 7c8389d55cc7ded5aee293edcadd08a1
BLAKE2b-256 ca151489b976fd95e0239674e8963c5de78f6c1deb79041dc7cd0fd9e8795a65

See more details on using hashes here.

File details

Details for the file bugboy-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: bugboy-0.0.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e099fc3cbe9aad33427e07681a60079176ac56bfa1c776483de566ca23f33ca1
MD5 d7f50565f3111370d9a40d99b2a6d812
BLAKE2b-256 8e7fbee36915353b7d37d73b7378e2bc1053a66c91feab202be9c15d770713aa

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