Examples & Recipes

Real-world usage patterns and practical examples for fapilog.

Overview

These examples show fapilog in action across different use cases and environments:

  • FastAPI Logging - Request/response IDs and middleware

  • CLI Tools - Using runtime() for command-line applications

  • Redacting Secrets - Password and token masking

  • Structured Error Logging - Exception handling with context

  • Kubernetes File Sink - Containerized logging with rotation

  • Prometheus Metrics - Monitoring and observability

  • Sampling Debug Logs - Development vs production logging

  • Size-Limited Destinations - Guardrails for CloudWatch, Loki, and Kafka limits

  • CloudWatch Logging - LocalStack-backed example for AWS CloudWatch Logs

Quick Examples

Basic Logging

from fapilog import get_logger

logger = get_logger()

# Simple logging
logger.info("Application started")

# With structured data
logger.info(
    "User action",
    user_id="123",
    action="login",
    timestamp="2024-01-15T10:30:00Z",
)

Context Binding

from fapilog import get_logger

logger = get_logger()

# Bind context for this request
logger.bind(request_id="req-123", user_id="user-456")

# Context automatically included
logger.info("Processing request")
logger.info("Request completed")

# Output includes request_id and user_id automatically
# Clear when done
logger.clear_context()

File Logging

import os
from fapilog import get_logger

# Configure rotating file logging
os.environ["FAPILOG_SINK_CONFIG__ROTATING_FILE__DIRECTORY"] = "./logs"
os.environ["FAPILOG_SINK_CONFIG__ROTATING_FILE__MAX_BYTES"] = "1048576"  # 1MB
os.environ["FAPILOG_SINK_CONFIG__ROTATING_FILE__MAX_FILES"] = "5"

logger = get_logger()

# Logs go to rotating files
for i in range(1000):
    logger.info(f"Log message {i}")

What You’ll Learn

  1. FastAPI Logging - Request correlation and middleware integration

  2. CLI Tools - Command-line applications with proper cleanup

  3. Redacting Secrets - Data masking and security

  4. Structured Error Logging - Exception handling with context

  5. Kubernetes File Sink - Containerized logging best practices

  6. Prometheus Metrics - Monitoring and observability integration

  7. Sampling Debug Logs - Development vs production strategies

Common Patterns

Request Correlation

from fapilog import get_logger
import uuid

def handle_request(user_id: str):
    # Generate unique request ID
    request_id = str(uuid.uuid4())

    logger = get_logger()

    try:
        logger.bind(request_id=request_id, user_id=user_id)
        logger.info("Request started")

        # Process request
        result = process_request()

        logger.info("Request completed", status="success", duration_ms=45)

        return result

    except Exception as e:
        logger.error(
            "Request failed",
            exc=e,
            error_type=type(e).__name__,
            error_message=str(e),
        )
        raise
    finally:
        # Clean up context
        logger.clear_context()

Batch Processing

from fapilog import runtime_async

async def process_items(items):
    async with runtime_async() as logger:
        await logger.info("Batch processing started", batch_size=len(items))

        processed = 0
        failed = 0

        for item in items:
            try:
                await process_item(item)
                processed += 1

                if processed % 100 == 0:
                    await logger.info(
                        "Progress update",
                        processed=processed,
                        total=len(items),
                        progress_pct=(processed / len(items)) * 100,
                    )

            except Exception as e:
                failed += 1
                await logger.error(
                    "Item processing failed",
                    item_id=item.id,
                    exc=e,
                )

        await logger.info(
            "Batch processing completed",
            total=len(items),
            processed=processed,
            failed=failed,
            success_rate=(processed / len(items)) * 100,
        )

Error Handling

from fapilog import get_logger

logger = get_logger()

async def risky_operation():
    try:
        # Attempt operation
        result = await perform_operation()

        logger.info("Operation successful", operation="risky_operation", result=result)

        return result

    except ValueError as e:
        # Handle specific error type
        logger.warning(
            "Operation failed with invalid input",
            operation="risky_operation",
            error_type="ValueError",
            error_message=str(e),
            input_data=get_input_data(),
        )
        raise

    except Exception as e:
        # Handle unexpected errors
        logger.error(
            "Operation failed unexpectedly",
            exc_info=True,
            operation="risky_operation",
            error_type=type(e).__name__,
            error_message=str(e),
            context=get_operation_context(),
        )
        raise

Environment-Specific Examples

Development

# Development logging - verbose and human-readable
export FAPILOG_CORE__LOG_LEVEL=DEBUG

Production

# Production logging - structured and efficient
export FAPILOG_CORE__LOG_LEVEL=INFO
export FAPILOG_SINK_CONFIG__ROTATING_FILE__DIRECTORY=/var/log/myapp
export FAPILOG_SINK_CONFIG__ROTATING_FILE__MAX_BYTES=10485760
export FAPILOG_SINK_CONFIG__ROTATING_FILE__COMPRESS_ROTATED=true

Testing

# Testing - minimal and fast
export FAPILOG_CORE__LOG_LEVEL=WARNING
export FAPILOG_CORE__ENABLE_METRICS=false
export FAPILOG_CORE__DROP_ON_FULL=true

Next Steps


These examples show you how to use fapilog effectively in real applications.