Logging¶
Structured logging via structlog with automatic request ID binding.
Overview¶
- Development: human-readable colored console output
- Production: machine-parseable JSON lines to stderr
Logging is configured automatically when you call create_bluefox_app().
Using the logger¶
from bluefox_core import logger
logger.info("user signed up", user_id=42)
logger.warning("rate limit approaching", endpoint="/api/data")
logger.error("payment failed", order_id="abc-123", reason="card declined")
The logger is a structlog BoundLogger — you can attach arbitrary key-value context to every log call.
Request ID context¶
The RequestIDMiddleware automatically binds a request_id to every log message within a request. If the client sends an X-Request-ID header, that value is used; otherwise a UUID is generated.
{"event": "user signed up", "user_id": 42, "request_id": "abc-123", "level": "info", "timestamp": "2024-01-15T10:30:00Z"}
Request IDs use Python's contextvars, so they are correctly scoped across concurrent async tasks.
Manual context binding¶
from bluefox_core.log import bind_request_context, clear_request_context
bind_request_context("custom-id-123")
logger.info("this will include request_id=custom-id-123")
clear_request_context()
configure_logging¶
Called automatically by the app factory. If you need to reconfigure (e.g. in tests):
from bluefox_core import BluefoxSettings, configure_logging
settings = BluefoxSettings(ENVIRONMENT="production", LOG_LEVEL="DEBUG")
configure_logging(settings)
This sets up:
- structlog processors (contextvars merge, log level, ISO timestamps, stack info, exception formatting)
- The appropriate renderer (JSON or console)
- The root Python logger level from
settings.LOG_LEVEL