LoggingConfig¶
Configure centralized logging for your Ravyn application with flexible backend support.
What You'll Learn¶
- Why Ravyn has LoggingConfig
- Using the global logger
- Creating custom logging backends
- Best practices for logging
Quick Start¶
from ravyn import Ravyn
from ravyn.logging import logger
app = Ravyn() # Uses StandardLoggingConfig by default
# Use logger anywhere
logger.info("Application started")
logger.error("Something went wrong")
Why LoggingConfig?¶
Ravyn introduced LoggingConfig to provide:
-
Consistency - Predictable logging across your app
-
Flexibility - Support for standard logging, Loguru, Structlog, or custom backends
-
Simplicity - One global logger for the entire app
-
Extensibility - Easy to create custom logging configurations
The Global Logger¶
Access the logger anywhere in your application:
from ravyn.logging import logger
# In any file
logger.info("User logged in")
logger.warning("Rate limit approaching")
logger.error("Database connection failed")
logger.debug("Request details: %s", request_data)
The logger automatically uses the configured backend.
Available Backends¶
Standard Python Logging (Default)¶
from ravyn import Ravyn
# Uses StandardLoggingConfig by default
app = Ravyn()
Custom Configuration¶
from ravyn import Ravyn
from ravyn.config import StandardLoggingConfig
app = Ravyn(
logging_config=StandardLoggingConfig(
level="INFO",
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
)
Creating Custom Logging¶
Custom LoggingConfig¶
from ravyn.config import LoggingConfig
import logging
class CustomLoggingConfig(LoggingConfig):
def configure(self) -> None:
"""Configure the logging system."""
logging.basicConfig(
level=logging.INFO,
format='[%(levelname)s] %(name)s: %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('app.log')
]
)
def get_logger(self):
"""Return the logger instance."""
return logging.getLogger("ravyn")
# Use it
app = Ravyn(logging_config=CustomLoggingConfig())
Using Loguru¶
from ravyn.config import LoggingConfig
from loguru import logger as loguru_logger
class LoguruConfig(LoggingConfig):
def configure(self) -> None:
"""Configure Loguru."""
loguru_logger.add(
"app.log",
rotation="500 MB",
retention="10 days",
level="INFO"
)
def get_logger(self):
"""Return Loguru logger."""
return loguru_logger
app = Ravyn(logging_config=LoguruConfig())
Using with Settings¶
from ravyn import RavynSettings
from ravyn.config import StandardLoggingConfig
class AppSettings(RavynSettings):
logging_config: StandardLoggingConfig = StandardLoggingConfig(
level="INFO"
)
app = Ravyn(settings_module=AppSettings)
Logging Levels¶
| Level | When to Use |
|---|---|
DEBUG |
Detailed diagnostic information |
INFO |
General informational messages |
WARNING |
Warning messages for potential issues |
ERROR |
Error messages for failures |
CRITICAL |
Critical failures requiring immediate attention |
Example Usage¶
from ravyn.logging import logger
# Debug - detailed info
logger.debug("Processing request: %s", request_id)
# Info - general events
logger.info("User %s logged in", user_id)
# Warning - potential issues
logger.warning("Cache miss for key: %s", cache_key)
# Error - failures
logger.error("Failed to connect to database: %s", error)
# Critical - severe issues
logger.critical("Out of memory! Shutting down...")
Best Practices¶
1. Use Structured Logging¶
# Good - structured data
logger.info("User login", extra={
"user_id": user.id,
"ip_address": request.client.host,
"timestamp": datetime.utcnow()
})
2. Log at Appropriate Levels¶
# Good - correct levels
logger.debug("Cache lookup for key: %s", key) # Debug details
logger.info("User created: %s", user.id) # Important events
logger.error("Payment failed: %s", error) # Errors
3. Don't Log Sensitive Data¶
# Wrong - logging passwords
logger.info("User login: %s / %s", email, password)
# Correct - no sensitive data
logger.info("User login attempt: %s", email)
Common Patterns¶
Pattern 1: Request Logging¶
from ravyn import get, Request
from ravyn.logging import logger
@get("/api/users")
async def get_users(request: Request) -> list:
logger.info(
"Fetching users",
extra={"path": request.url.path, "method": request.method}
)
users = await fetch_users()
logger.info("Returned %d users", len(users))
return users
Pattern 2: Error Logging¶
from ravyn import post
from ravyn.logging import logger
@post("/api/process")
async def process_data(data: dict) -> dict:
try:
result = await process(data)
return result
except Exception as e:
logger.error(
"Processing failed",
exc_info=True, # Include stack trace
extra={"data_id": data.get("id")}
)
raise
Next Steps¶
- SchedulerConfig - Task scheduling
- SessionConfig - Session management
- Application Settings - Configuration