| name | logfire |
| description | Structured observability with Pydantic Logfire and OpenTelemetry. Use when: (1) Adding traces/logs to Python APIs, (2) Instrumenting FastAPI, HTTPX, SQLAlchemy, or LLMs, (3) Setting up service metadata, (4) Configuring sampling or scrubbing sensitive data, (5) Testing observability code.
|
Logfire
Structured observability for Python using Pydantic Logfire - fast setup, powerful features, OpenTelemetry-compatible.
Quick Start
uv pip install logfire
import logfire
logfire.configure(service_name="my-api", service_version="1.0.0")
logfire.info("Application started")
Core Patterns
1. Service Configuration
Always set service metadata at startup:
import logfire
logfire.configure(
service_name="backend",
service_version="1.0.0",
environment="production",
console=False,
send_to_logfire=True,
)
2. Framework Instrumentation
Instrument frameworks before creating clients/apps:
import logfire
from fastapi import FastAPI
logfire.configure(service_name="backend")
logfire.instrument_fastapi()
logfire.instrument_httpx()
logfire.instrument_sqlalchemy()
app = FastAPI()
3. Log Levels and Structured Logging
logfire.trace("Detailed trace", step=1)
logfire.debug("Debug context", variable=locals())
logfire.info("User action", action="login", success=True)
logfire.notice("Important event", event_type="milestone")
logfire.warn("Potential issue", threshold_exceeded=True)
logfire.error("Operation failed", error_code=500)
logfire.fatal("Critical failure", component="database")
user_id = 123
status = "active"
logfire.info(f"User {user_id} status: {status}")
try:
risky_operation()
except Exception:
logfire.exception("Operation failed", context="extra_info")
4. Manual Spans
with logfire.span("Process order {order_id}", order_id="ORD-123"):
logfire.info("Validating cart")
logfire.info("Order complete")
with logfire.span("Database query") as span:
results = execute_query()
span.set_attribute("result_count", len(results))
span.message = f"Query returned {len(results)} results"
5. Custom Metrics
request_counter = logfire.metric_counter("http.requests", unit="1")
request_counter.add(1, {"endpoint": "/api/users", "method": "GET"})
temperature = logfire.metric_gauge("temperature", unit="°C")
temperature.set(23.5)
latency = logfire.metric_histogram("request.duration", unit="ms")
latency.record(45.2, {"endpoint": "/api/data"})
6. LLM Observability
import logfire
from pydantic_ai import Agent
logfire.configure()
logfire.instrument_pydantic_ai()
agent = Agent("openai:gpt-4o", system_prompt="You are helpful.")
result = agent.run_sync("Hello!")
7. Suppress Noisy Instrumentation
logfire.suppress_scopes("google.cloud.bigquery.opentelemetry_tracing")
with logfire.suppress_instrumentation():
client.get("https://internal-healthcheck.local")
8. Sensitive Data Scrubbing
import logfire
logfire.configure(
scrubbing=logfire.ScrubbingOptions(
extra_patterns=["api_key", "secret", "token"]
)
)
def scrubbing_callback(match: logfire.ScrubMatch):
if match.path == ("attributes", "safe_field"):
return match.value
return None
logfire.configure(
scrubbing=logfire.ScrubbingOptions(callback=scrubbing_callback)
)
9. Sampling for High-Traffic Services
import logfire
logfire.configure(sampling=logfire.SamplingOptions(head=0.5))
logfire.configure(metrics=False)
10. Testing
import logfire
from logfire.testing import CaptureLogfire
def test_user_creation(capfire: CaptureLogfire):
create_user("Alice", "alice@example.com")
spans = capfire.exporter.exported_spans
assert len(spans) >= 1
assert spans[0].attributes["user_name"] == "Alice"
capfire.exporter.clear()
Available Integrations
| Category | Integration | Method |
|---|
| Web | FastAPI | logfire.instrument_fastapi(app) |
| Starlette | logfire.instrument_starlette(app) |
| Django | logfire.instrument_django() |
| Flask | logfire.instrument_flask(app) |
| AIOHTTP Server | logfire.instrument_aiohttp_server() |
| ASGI | logfire.instrument_asgi(app) |
| WSGI | logfire.instrument_wsgi(app) |
| HTTP | HTTPX | logfire.instrument_httpx() |
| Requests | logfire.instrument_requests() |
| AIOHTTP Client | logfire.instrument_aiohttp_client() |
| Database | SQLAlchemy | logfire.instrument_sqlalchemy(engine) |
| Asyncpg | logfire.instrument_asyncpg() |
| Psycopg | logfire.instrument_psycopg() |
| Redis | logfire.instrument_redis() |
| PyMongo | logfire.instrument_pymongo() |
| LLM | Pydantic AI | logfire.instrument_pydantic_ai() |
| OpenAI | logfire.instrument_openai() |
| Anthropic | logfire.instrument_anthropic() |
| MCP | logfire.instrument_mcp() |
| Tasks | Celery | logfire.instrument_celery() |
| AWS Lambda | logfire.instrument_aws_lambda() |
| Logging | Standard logging | logfire.instrument_logging() |
| Structlog | logfire.instrument_structlog() |
| Loguru | logfire.instrument_loguru() |
| Print | logfire.instrument_print() |
| Other | Pydantic | logfire.instrument_pydantic() |
| System Metrics | logfire.instrument_system_metrics() |
Common Pitfalls
| Issue | Symptom | Fix |
|---|
| Missing service name | Spans hard to find in UI | Set service_name in configure() |
| Late instrumentation | No spans captured | Call configure() before creating clients |
| High-cardinality attrs | Storage explosion | Use IDs, not full payloads as attributes |
| Console noise | Logs pollute stdout | Set console=False in production |
References