Skip to content

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