Starlette
See every request your Starlette app handles (the route, how long it took, the response status, and any errors) as a trace (the full journey of one request, made of nested spans, where each span is one unit of work with a name, a start, and a duration) in Logfire.
- Each request as a span, with its HTTP status and duration
- The matched route and method
- Any errors raised while handling the request
You’ll need a Logfire project. Open Add data in your project (top navigation) and follow the
setup for your language: it signs your machine in with logfire auth (a browser sign-in, no token
to copy) and, for production or other languages, creates a write token (the credential your app
uses to send data). New to Logfire? Start with Getting Started.
Install logfire with the starlette extra:
pip install 'logfire[starlette]'
uv add 'logfire[starlette]'
Add two lines to your app: logfire.configure() to connect to your project, and
logfire.instrument_starlette() to record every request.
To run the example below, also install Uvicorn, the server that runs the app:
pip install uvicorn
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import PlainTextResponse
from starlette.routing import Route
import logfire
logfire.configure()
async def home(request: Request) -> PlainTextResponse:
return PlainTextResponse('Hello, world!')
app = Starlette(routes=[Route('/', home)])
logfire.instrument_starlette(app)
if __name__ == '__main__':
import uvicorn
uvicorn.run(app)
Run it with python main.py.
With the app running, open http://localhost:8000/ in your browser.
Then open your project in the Logfire web app and go to the Live view. Within a few seconds you should see a span for the request. Click it to see its duration, the matched route, and the response status.
Not seeing your requests in Logfire? Check these first:
logfire.configure()runs beforelogfire.instrument_starlette(). Configure the connection first, then instrument the app.- You call
instrument_starlette(app)exactly once, on the sameappobject you serve. - Your write token is set. In local development, run
logfire projects use <your-project>; in production, set theLOGFIRE_TOKENenvironment variable. See Getting Started. - You actually sent a request. Spans appear only after a route is hit; reload the URL above.
logfire.instrument_starlette() accepts additional keyword
arguments and passes them to the OpenTelemetry StarletteInstrumentor.instrument_app() method. See
their documentation for the full list.
If you’re a more experienced user, you might wonder why we don’t use the
OpenTelemetry ASGI middleware directly. The reason is that the
StarletteInstrumentor wraps that middleware and adds extra information about the matched routes.
If your frontend sends telemetry from the browser, never expose your Logfire write token in frontend code: anyone who loads the page could read it and send data to your project.
Instead, use an experimental proxy handler to forward OpenTelemetry Protocol (OTLP) data (the standard wire format Logfire uses to receive telemetry) through your Starlette backend, where the token stays secret. See the Logfire JS browser package docs for setup.
- API reference:
logfire.instrument_starlette() - Underlying OpenTelemetry package: Starlette instrumentation