Frequently Asked Questions
Common questions and answers about fapilog.
General Questions
Why JSON lines by default?
fapilog uses JSON lines by default because:
Machine-readable - Easy to parse and analyze with log aggregation tools
Structured data - Preserves field types and relationships
Industry standard - Compatible with ELK, Splunk, and other tools
Performance - Fast serialization and parsing
You can switch the log format for development:
export FAPILOG_OBSERVABILITY__LOGGING__FORMAT=text
How to add custom fields globally?
Use context binding to add fields to all log messages:
from fapilog import get_logger
logger = get_logger()
logger.bind(service_name="user-service", environment="production", version="1.2.3")
logger.info("Application started")
Do I still need log levels?
Yes, log levels are still important for:
Filtering - Show only relevant logs in production
Prioritization - Focus on errors and warnings
Compliance - Meet audit and regulatory requirements
Debugging - Enable detailed logging when needed
# Set appropriate levels for different environments
export FAPILOG_CORE__LOG_LEVEL=DEBUG # Development
export FAPILOG_CORE__LOG_LEVEL=INFO # Production
export FAPILOG_CORE__LOG_LEVEL=WARNING # Testing
How does fapilog compare to logging/structlog?
Feature |
stdlib logging |
structlog |
fapilog |
|---|---|---|---|
Async |
❌ No |
❌ No |
✅ Yes |
Performance |
⚠️ Medium |
⚠️ Medium |
✅ High |
Structured |
❌ No |
✅ Yes |
✅ Yes |
Context |
❌ Manual |
⚠️ Basic |
✅ Advanced |
Redaction |
❌ No |
❌ No |
✅ Yes |
Metrics |
❌ No |
❌ No |
✅ Yes |
Technical Questions
Can I use it with Celery/async jobs?
Yes! fapilog works great with async job systems:
from fapilog import get_async_logger
from celery import Celery
app = Celery('tasks')
@app.task
async def process_data(data):
logger = await get_async_logger("worker")
await logger.info("Processing started", data_id=data.id)
try:
result = await process(data)
await logger.info("Processing completed", result=result)
return result
except Exception as e:
await logger.error("Processing failed", exc_info=True)
raise
How does context inheritance work?
fapilog stores bound context in a ContextVar, which flows to child tasks spawned from the same context. Each request/task should bind its own context:
import asyncio
from fapilog import runtime_async
async def child_task(name, logger):
await logger.info(f"{name} started")
async def main():
async with runtime_async() as logger:
logger.bind(request_id="req-123")
await asyncio.gather(
child_task("task1", logger),
child_task("task2", logger),
)
logger.clear_context() # End-of-request cleanup
What happens if a sink fails?
fapilog handles sink failures gracefully:
Retry logic - Automatic retries for transient failures
Circuit breakers - Prevent cascading failures
Fallback behavior - Continue logging to other sinks
Error reporting - Log sink failures for debugging
# Configure HTTP sink retry behavior
export FAPILOG_HTTP__RETRY_MAX_ATTEMPTS=3
export FAPILOG_HTTP__RETRY_BACKOFF_SECONDS=0.5
Performance Questions
How does fapilog handle high throughput?
fapilog is designed for high-performance logging:
Async processing - Non-blocking operations
Lock-free queues - Maximum concurrency
Batching - Group messages for efficiency
Zero-copy - Minimal memory allocation
# Optimize for high throughput
export FAPILOG_CORE__MAX_QUEUE_SIZE=65536
export FAPILOG_CORE__BATCH_MAX_SIZE=500
export FAPILOG_CORE__BATCH_TIMEOUT_SECONDS=0.1
export FAPILOG_CORE__BACKPRESSURE_WAIT_MS=25
What’s the memory overhead?
fapilog has minimal memory overhead:
Queue size - Configurable (default: 8KB)
Batch processing - Reduces memory pressure
Object pooling - Reuses objects
Garbage collection - Minimal impact
# Monitor internal metrics
export FAPILOG_CORE__ENABLE_METRICS=true
How fast is it?
fapilog is designed for speed:
Microsecond latency - Sub-millisecond logging
High throughput - 100K+ messages/second
Async I/O - Non-blocking operations
Optimized serialization - Fast JSON encoding
Configuration Questions
Can I use configuration files?
Yes, fapilog supports multiple configuration methods:
from fapilog import Settings, get_logger
settings = Settings(
core__log_level="INFO",
core__max_queue_size=10000,
http__endpoint="https://logs.example.com/ingest",
)
logger = get_logger(settings=settings)
How do I configure different environments?
Use environment-specific configuration:
# Development
export FAPILOG_CORE__LOG_LEVEL=DEBUG
export FAPILOG_OBSERVABILITY__LOGGING__FORMAT=text
# Production
export FAPILOG_CORE__LOG_LEVEL=INFO
export FAPILOG_FILE__DIRECTORY=/var/log/myapp
# Testing
export FAPILOG_CORE__LOG_LEVEL=WARNING
export FAPILOG_CORE__DROP_ON_FULL=true
Can I change configuration at runtime?
Configuration is resolved when you create a logger/runtime. To change settings, construct a new Settings object and pass it when you create a new logger; don’t mutate globals in place.
from fapilog import Settings, get_logger
settings = Settings(core__log_level="DEBUG", core__enable_metrics=True)
logger = get_logger(settings=settings)
For running apps that need different behavior, create a new logger/runtime with updated settings rather than mutating an existing one.
Integration Questions
How do I integrate with FastAPI?
fapilog has built-in FastAPI integration:
from fastapi import FastAPI, Depends
from fapilog import get_async_logger
app = FastAPI()
async def logger_dep():
return await get_async_logger("request")
@app.get("/users/{user_id}")
async def get_user(user_id: str, logger = Depends(logger_dep)):
await logger.info("Fetching user", user_id=user_id)
return {"user_id": user_id}
Can I use it with Docker/Kubernetes?
Yes! fapilog works great in containers:
# Dockerfile
FROM python:3.11-slim
# Install fapilog
RUN pip install fapilog
# Configure logging
ENV FAPILOG_CORE__LOG_LEVEL=INFO
ENV FAPILOG_OBSERVABILITY__LOGGING__FORMAT=json
ENV FAPILOG_CORE__ENABLE_METRICS=false
# Your application code
COPY . .
CMD ["python", "app.py"]
# Kubernetes deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: FAPILOG_CORE__LOG_LEVEL
value: "INFO"
- name: FAPILOG_OBSERVABILITY__LOGGING__FORMAT
value: "json"
How do I send logs to external systems?
fapilog supports various external destinations:
# HTTP sink for log aggregation
export FAPILOG_HTTP__URL=https://logs.example.com/api/logs
export FAPILOG_HTTP__AUTH_TOKEN=your-token
# Custom sinks via plugins
export FAPILOG_PLUGINS__SINKS=custom_sink
Support Questions
Where can I get help?
Multiple support channels are available:
Documentation - This site and guides
GitHub Issues - Bug reports and feature requests
Discussions - Community support and questions
Professional Support - Enterprise users (contact sales)
How do I report a bug?
Report bugs on GitHub:
Check existing issues - Search for similar problems
Provide details - Include error messages and logs
Reproduce steps - Clear steps to reproduce the issue
Environment info - Python version, OS, fapilog version
Can I contribute to fapilog?
Yes! fapilog is open source and welcomes contributions:
Code contributions - Bug fixes and new features
Documentation - Improve guides and examples
Testing - Report bugs and test fixes
Community - Help other users
See the Contributing Guide for details.
Can’t find the answer you’re looking for? Check the Troubleshooting guide or ask the community.