logfire
Logfire is Pydantic's Python observability SDK and hosted telemetry product. The open-source SDK wraps OpenTelemetry with structured logs, spans, metrics, argument inspection, scrubbing, and one-call instrumentation for web frameworks, databases, HTTP clients, queues, and AI libraries. The default experience sends data to Pydantic's hosted Logfire service; the repository is explicit that the hosted UI and backend are closed source.
Logfire is one of the quickest ways to get coherent Python telemetry, especially in Pydantic and FastAPI stacks. Adopt it with a clear answer about data capture and backend ownership, because the attractive hosted experience is not an open-source server.
Use it if
- You want logs, traces, and metrics in one Python-first API with less OpenTelemetry setup code
- Your stack includes FastAPI, Pydantic, HTTPX, requests, SQLAlchemy, Redis, Celery, or supported AI clients and automatic instrumentation is valuable
- You are comfortable using the hosted Logfire product or wiring the open-source SDK to another OpenTelemetry-compatible backend
- You want rich local console telemetry during development and the same instrumentation path in production
- You require a fully open-source, self-hosted observability stack: the README states that the Logfire UI and backend are closed source and self-hosting requires an enterprise license
- Your organization already has a disciplined OpenTelemetry SDK and collector setup: Logfire adds an opinionated layer and another set of configuration and instrumentation APIs
- You need plain application logging only: the base install brings the OpenTelemetry SDK, OTLP HTTP exporter, protobuf, Rich, and related packages when structlog or standard logging would be much smaller
- Your data policy forbids telemetry leaving the environment and you cannot audit every captured argument, header, database statement, and integration; scrubbing helps but instrumentation scope still needs review
- You cannot tolerate frequent surface growth: version 4.40.0 exposes a very broad set of integrations, variables, sampling, forwarding, AI instrumentation, and configuration objects that evolve faster than the OpenTelemetry core
Setup reality
pip install logfire installs the SDK plus OpenTelemetry SDK and OTLP-over-HTTP exporter dependencies; 4.40.0 requires Python 3.10 or newer. The hosted path needs an account and project write token. The CLI can authenticate a developer and select a project, while deployments normally receive LOGFIRE_TOKEN as a secret. Call logfire.configure() before instrumenting libraries. By default send_to_logfire is true, so local scripts can try to export unless you explicitly use send_to_logfire=False or if-token-present. Set service_name, service_version, and environment early because they become resource attributes used to separate telemetry. Framework integrations are optional extras, and each can add the corresponding OpenTelemetry instrumentation package; for example, FastAPI instrumentation is not provided by the base dependency alone. Automatic instrumentation can capture request values, headers when enabled, SQL parameters in some integrations, function arguments, exceptions, and AI content, so configure scrubbing and decide what not to record before production traffic. The SDK's default scrubbing is a safety net, not proof of compliance. Distributed tracing also propagates context across services and can accidentally join traces from untrusted callers; the configuration has an explicit distributed_tracing policy because this is not always harmless. Short-lived jobs should force-flush or shut down so batched exports are not lost. If you do not use the hosted service, set send_to_logfire=False and provide OpenTelemetry span processors or metric readers for your backend; merely installing Logfire does not create a collector. The local console is useful for setup, but success there does not verify network egress, token permissions, collector limits, sampling, or production data volume.
Patterns
Configure a named production serviceconfigure-hosted-logfire
import logfire
logfire.configure(
service_name='checkout-api',
service_version='2026.08.08',
environment='production',
) # reads LOGFIRE_TOKEN from the environmentThe default is to send to Logfire; provide the project write token as a deployment secret before calling configure.
Use Logfire locally without hosted exportconfigure-console-only
import logfire
logfire.configure(
service_name='checkout-api',
send_to_logfire=False,
)This keeps the default console output but does not send data to another OpenTelemetry backend unless you configure processors or readers.
Write a message with queryable attributeswrite-structured-log
logfire.info(
'Checkout created for {user_id}',
user_id='usr_42',
checkout_id='chk_17',
total_cents=2599,
)Attribute names beginning with an underscore are reserved and rejected; use stable low-cardinality keys where practical.
Wrap an operation in a spantrace-code-block
with logfire.span('Charge order {order_id}', order_id=order.id):
result = gateway.charge(order.total)
logfire.info('Gateway accepted charge', transaction_id=result.id)Logs created inside the context are attached to the active span; do not put secrets into span attributes.
Create a span for every function callinstrument-function
@logfire.instrument('Calculate quote for {destination}', record_return=False)
def calculate_quote(destination: str, weight_kg: float) -> int:
return pricing.lookup(destination, weight_kg)Argument extraction can capture sensitive or large values; select arguments or disable extraction when the defaults are too broad.
Record the active exception and tracebackrecord-exception
try:
process_payment()
except PaymentError:
logfire.exception('Payment processing failed', order_id=order.id)
raiselogfire.exception uses the currently handled exception by default; call it inside the except block and preserve application error behavior.
Trace FastAPI requestsinstrument-fastapi
import logfire
from fastapi import FastAPI
logfire.configure(service_name='orders-api')
app = FastAPI()
logfire.instrument_fastapi(app, excluded_urls='health|metrics')Install the fastapi extra or its OpenTelemetry instrumentation dependency; header capture is off by default and should stay deliberate.
Trace outgoing HTTPX callsinstrument-httpx
import httpx
import logfire
logfire.instrument_httpx()
response = httpx.get('https://inventory.example.com/items/42')Call instrumentation once during startup, before creating long-lived clients; duplicate instrumentation can produce duplicate spans.
Record Pydantic validation activityinstrument-pydantic
import logfire
logfire.configure()
logfire.instrument_pydantic(record='failure')
# Define and use Pydantic models after instrumentation is enabled.failure is a lower-volume starting point; recording successful validations can expose model contents and produce much more telemetry.
Send standard logging records to Logfirebridge-standard-logging
import logging
import logfire
logging.basicConfig(handlers=[logfire.LogfireLoggingHandler()])
logging.getLogger('worker').warning('retrying delivery', extra={'order_id': 'ord_9'})Review existing handlers and propagation first or the same record can appear in both console and Logfire more than once.
Increment an OpenTelemetry counterrecord-counter-metric
orders = logfire.metric_counter(
'orders.processed', unit='1', description='Processed orders'
)
orders.add(1, {'result': 'accepted'})Metric attribute combinations create time series; avoid user IDs, request IDs, and other unbounded labels.
Flush telemetry before a worker exitsflush-short-job
try:
run_batch()
finally:
if not logfire.force_flush(timeout_millis=5000):
print('telemetry flush timed out')Batch exporters buffer records, so a short-lived command can exit successfully while losing its final telemetry unless it flushes.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| opentelemetry-sdk | PyPI | You want the vendor-neutral primitives directly and can own exporters, resources, processors, and instrumentation |
| sentry-sdk | PyPI | Your priority is exception tracking, performance traces, and a mature hosted error workflow |
| structlog | PyPI | You need structured application logs without adopting a tracing and metrics platform |