Skip to main content

Fast API

Implement OpenTelemetry instrumentation for FastAPI applications to collect traces and metrics; monitor HTTP requests using the Python OTel SDK.

Note: This guide provides a concise overview based on the official OpenTelemetry documentation. For complete information, please consult the official OpenTelemetry documentation.

Overview

This guide demonstrates how to:

  • Set up OpenTelemetry instrumentation for FastAPI
  • Configure automatic request and response tracing
  • Implement custom instrumentation
  • Collect HTTP metrics
  • Export telemetry data to OpenTelemetry Collector

Prerequisites

Before starting, ensure you have:

  • Python 3.7 or later installed
  • FastAPI application set up
  • Access to package installation (pip)

Required Packages

opentelemetry-api defines the API interfaces for tracing, metrics and logging; opentelemetry-sdk provides the implementation for these APIs.

Install the following necessary packages or add it to requirements.txt and install it.

opentelemetry-instrumentation-fastapi
opentelemetry-sdk
opentelemetry-exporter-otlp
opentelemetry-api

# Optional
opentelemetry-instrumentation-requests
requests

Traces

Traces give us the big picture of what happens when a request is made to an application. Whether your application is a monolith with a single database or a sophisticated mesh of services, traces are essential to understanding the full “path” a request takes in your application.

Auto Instrumentation of Traces

from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
)
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.requests import RequestsInstrumentor

# Configure trace provider with service name
resource = Resource.create({"service.name": "custom-fastapi-service"})
trace.set_tracer_provider(
TracerProvider(
resource=resource
)
)

# Set up trace exporter
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://0.0.0.0:4318/v1/traces"))
)

app = FastAPI()

FastAPIInstrumentor.instrument_app(app)

# Optional: Instrument HTTP client requests
RequestsInstrumentor().instrument()

Key tracing features:

  • Automatic HTTP request/response tracking
  • Error and exception capturing
  • Request context propagation
  • Custom attribute support
  • Distributed tracing capabilities

View these metrics in base14 Scout observability backend.

Reference

Official Traces Documentation

Adding Custom Instrumentation

def do_work():
tracer = trace.get_tracer(__name__)
parent_span = trace.get_current_span()
ctx_with_parent_span = trace.set_span_in_context(parent_span)

with tracer.start_as_current_span("span", context=ctx_with_parent_span) as span:
span.set_attribute("key", "value")
# do some work ...

Metrics

OpenTelemetry metrics capture runtime measurements of your FastAPI application, including:

  • HTTP request counts and latencies
  • Response status codes
  • Resource utilization
  • Custom business metrics

Auto Instrumentation of Metrics

main.py

from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry import metrics
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.metrics import MeterProvider
from .MetricsMiddleware import MetricsMiddleware

from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter

# Configure metrics with service name
resource = Resource.create({"service.name": "custom-fastapi-service"})

# Set up metrics export
metric_reader = PeriodicExportingMetricReader(
OTLPMetricExporter(endpoint="http://0.0.0.0:4318/v1/metrics"),
export_interval_millis=1000
)
metrics.set_meter_provider(
MeterProvider(resource=resource, metric_readers=[metric_reader])
)

app = FastAPI()

app.add_middleware(MetricsMiddleware)
FastAPIInstrumentor.instrument_app(app)
MetricsMiddleware.py
from starlette.middleware.base import BaseHTTPMiddleware
from opentelemetry.metrics import get_meter

class MetricsMiddleware(BaseHTTPMiddleware):
def __init__(self, app):
super().__init__(app)
self.meter = get_meter("custom-fastapi-service")
self.http_requests_counter = self.meter.create_counter(
name="http_requests_total",
unit="1",
description="Number of HTTP requests per route"
)

async def dispatch(self, request, call_next):
response = await call_next(request)
self.http_requests_counter.add(
1,
{
"method": request.method,
"path": request.url.path,
"status_code": str(response.status_code),
}
)
return response

Metrics will be automatically exported to the OpenTelemetry Collector at the configured interval. MetricsMiddleware captures each HTTP request, including the method, path, and status code, and tracks the total request count.

View these metrics in base14 Scout observability backend.

Reference

Official Metrics Documentation

Sample Application

A sample application with OpenTelemetry instrumentation can be found at this GitHub repository