mrkeyoor.com_
Sat 08 Aug 20:59 UTC
PyPIInfraupdated 08 Aug 2026

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.

Verdict

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.

API stability3/5Core configure, info, span, instrument, metrics, and force-flush calls are coherent, but 4.40.0 exposes a rapidly expanding API across AI providers, web frameworks, databases, managed variables, sampling, and forwarding. The published source contains deprecated configuration arguments and replacements, so pinning and reading release notes matter more than with a narrow logging facade.
Docs5/5The documentation provides a start-to-finish onboarding path plus sections for manual tracing, integrations, scrubbing, sampling, distributed tracing, alternative backends, testing, metrics, the query API, and deployment. Examples match the exported Python API, and the README clearly states the open-source boundary instead of leaving users to discover it after adoption.
Maintenance5/5Logfire 4.40.0 was published on 2026-08-05, and the repository had 4,416 stars, 258 open issues and PRs, and a push on 2026-08-08. Releases and integration additions are frequent, with Pydantic as an active commercial maintainer. That pace is reassuring for compatibility but also explains the API churn reflected in the stability score.
Ecosystem5/5The SDK builds on OpenTelemetry and exports traces, metrics, and logs, while documented integrations cover FastAPI, Django, Flask, HTTPX, requests, SQLAlchemy, PostgreSQL drivers, Redis, MongoDB, Celery, AWS Lambda, Pydantic, and multiple AI frameworks. It can send to any OpenTelemetry-compatible backend, though the polished Logfire UI remains a separate hosted product.

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
Skip it if

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 environment

The 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)
    raise

logfire.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

PackageRegistryPick it when
opentelemetry-sdkPyPIYou want the vendor-neutral primitives directly and can own exporters, resources, processors, and instrumentation
sentry-sdkPyPIYour priority is exception tracking, performance traces, and a mature hosted error workflow
structlogPyPIYou need structured application logs without adopting a tracing and metrics platform