logfire-instrumentation

Add Pydantic Logfire observability to application code — traces, logs, metrics, and AI/agent spans. Use when the user asks to add or configure Logfire, observability, tracing, logging, or monitoring; maximize useful telemetry; or understand what an app is doing. Supports Python, JavaScript/TypeScript, Rust, and major AI agent frameworks including Pydantic AI, OpenAI Agents SDK, Claude Agent SDK, LangChain, LangGraph, CrewAI, AutoGen, and Google ADK. For infrastructure-only monitoring (hosts, Docker, Kubernetes, databases, or cloud metrics with no app-code changes), use `logfire-infrastructure`. For evaluating AI/agent behavior against test datasets, use `logfire-evals`.

Install
npx skills add 'https://github.com/pydantic/logfire/tree/main/logfire-sdk/logfire/.agents/skills/logfire-instrumentation'
Download bundle ↓
main · 39d1eb4Scanned 2026-09-17

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗
View on GitHub
← Back to SKILL.md

Python Logging Patterns

Log Levels

From lowest to highest severity:

logfire.trace("Detailed trace {detail}", detail=x)
logfire.debug("Debug info {state}", state=s)
logfire.info("Normal operation {event}", event=e)
logfire.notice("Notable event {event}", event=e)
logfire.warn("Warning {issue}", issue=i)
logfire.error("Error occurred {error}", error=err)
logfire.fatal("Fatal error {error}", error=err)

Nested Spans

Spans nest to create a tree visible in the Logfire UI. Use them to show the structure of an operation, not just that it happened:

async def send_request(url: str):
    with logfire.span("HTTP request {method} {url}", method="POST", url=url):
        with logfire.span("Serialize payload"):
            payload = model.model_dump_json()
        with logfire.span("Send request"):
            response = await client.post(url, content=payload)
        logfire.info("Response {status}", status=response.status_code)

Exceptions

Use logfire.exception(), which automatically captures the traceback:

async def handle_order(order_id: int):
    try:
        await process_order(order_id)
    except Exception:
        logfire.exception('Failed to process order {order_id}', order_id=order_id)
        raise

Standard Library Logging Integration

For projects that already use Python's logging module, route existing log calls through Logfire rather than rewriting them all:

from logging import getLogger

import logfire

logfire.configure()
getLogger().addHandler(logfire.LogfireLoggingHandler())

This explicitly adds the Logfire handler even when the application configured other root handlers first. Keep those handlers and the application's existing logging threshold unless the user asks to change them. Python's root logger defaults to WARNING; if the application has not chosen a threshold and should send INFO records, set the root logger to INFO alongside this handler. Do not lower an intentional threshold.

If the application already owns its complete dictConfig, add Logfire to that configuration. The root.handlers list replaces existing root handlers, so include every intended console, file, and Logfire handler there. This minimal example intentionally makes Logfire the only root handler:

from logging.config import dictConfig

import logfire

logfire.configure()
dictConfig({
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'logfire': {'class': 'logfire.LogfireLoggingHandler'},
    },
    'root': {'level': 'INFO', 'handlers': ['logfire']},
})

Suppressing Noisy Libraries

Some libraries emit excessive debug logs. Silence them at the logging level:

import logging

logging.getLogger('httpcore').setLevel(logging.WARNING)
logging.getLogger('httpx').setLevel(logging.WARNING)

Custom Metrics

For dashboards and alerting, create metrics:

counter = logfire.metric_counter("orders_processed", unit="1")
counter.add(1, {"status": "success"})

histogram = logfire.metric_histogram("request_duration", unit="s")
histogram.record(0.123, {"endpoint": "/api/users"})

gauge = logfire.metric_gauge("active_connections")
gauge.set(42)

Testing with capfire

Use the capfire pytest fixture to assert on emitted spans without sending data to production:

from logfire.testing import CaptureLogfire

def test_order_processing(capfire: CaptureLogfire) -> None:
    process_order(order_id=123)

    spans = capfire.exporter.exported_spans_as_dict()
    assert any(
        span['attributes'].get('order_id') == 123
        for span in spans
    )

Configure logfire with send_to_logfire=False in test fixtures to prevent production data leakage.

Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 73.
Use `{key}` placeholders with keyword arguments, never f-strings — `logfire.info('Created user {user_id}', user_id=uid)`, not `logfire.info(f'Created user {uid}')`. The former makes `user_id` a searchable attribute; the latter is a flat string. Full patterns (spans, exceptions, stdlib logging bridge, capfire testing): [Python logging patterns](./references/python/logging-patterns.md).
SKILL.mdView in source ↗
Source excerpt starting at line 184.
Counters, histograms, and gauges power the **Metrics** explorer, dashboard panels, and alerts — create them once and record throughout. Python examples: [logging patterns](./references/python/logging-patterns.md#custom-metrics). Rust: the `logfire` crate has its own counter/histogram/gauge functions (e.g. `logfire::u64_counter()`) and an `ExponentialHistogram` type in its `metrics` module — not yet written up in the [Rust reference](./references/rust/patterns.md), so pull the signatures from the crate's own rustdoc. JS/TS: `@pydantic/logfire-node` has no custom-metrics wrapper of its own — create instruments with the raw OpenTelemetry Metrics API (`@opentelemetry/api`'s `metrics.getMeter(...)`); Logfire ingests them like any other OTLP metric.
SKILL.mdView in source ↗
Source excerpt starting at line 281.
- **Authentication**: [full command sequence, flags, and gotchas](./references/auth.md) — shared by all three Logfire setup skills- **Python**: [logging patterns](./references/python/logging-patterns.md) (log levels, spans, stdlib integration, metrics, capfire testing) and [integrations](./references/python/integrations.md) (full instrumentor table with extras)- **JavaScript/TypeScript**: [patterns](./references/javascript/patterns.md) (log levels, spans, error handling, config) and [frameworks](./references/javascript/frameworks.md) (Node.js, Cloudflare Workers, Next.js, Deno setup)