Skip to main content
When tracing is enabled, the Apitally SDK captures OpenTelemetry spans during request handling and attaches them to request logs. This allows you to see exactly what happened during each request, including database queries, HTTP calls to external services, and custom operations. If you have an existing OpenTelemetry setup, the SDK automatically registers itself as a span processor with the global TracerProvider. Otherwise, it creates its own. Any spans created using the standard OpenTelemetry API or by instrumentation libraries will be captured.

Enable tracing

To enable tracing, set capture_traces to True in your middleware configuration:
from fastapi import FastAPI
from apitally.fastapi import ApitallyMiddleware

app = FastAPI()
app.add_middleware(
    ApitallyMiddleware,
    client_id="your-client-id",
    env="dev",
    enable_request_logging=True,
    capture_traces=True,
)

Instrument libraries

The SDK provides helper functions in apitally.otel to instrument popular libraries. These are thin wrappers around the official OpenTelemetry instrumentation packages, which need to be installed separately.
LibraryFunctionRequired package
httpxinstrument_httpx()opentelemetry-instrumentation-httpx
requestsinstrument_requests()opentelemetry-instrumentation-requests
SQLAlchemyinstrument_sqlalchemy()opentelemetry-instrumentation-sqlalchemy
psycopg 3instrument_psycopg()opentelemetry-instrumentation-psycopg
psycopg2instrument_psycopg2()opentelemetry-instrumentation-psycopg2
asyncpginstrument_asyncpg()opentelemetry-instrumentation-asyncpg
mysql-connector-pythoninstrument_mysql()opentelemetry-instrumentation-mysql
redis-pyinstrument_redis()opentelemetry-instrumentation-redis
PyMongoinstrument_pymongo()opentelemetry-instrumentation-pymongo
botocore (AWS SDK)instrument_botocore()opentelemetry-instrumentation-botocore
To get started, first install the required packages for the libraries you want to instrument. For example, to instrument httpx and sqlalchemy:
pip install opentelemetry-instrumentation-httpx opentelemetry-instrumentation-sqlalchemy
Then call the instrumentation functions at application startup. Some functions accept an optional client, connection or engine argument to instrument a specific instance instead of all instances globally.
from apitally.otel import instrument_httpx, instrument_sqlalchemy

instrument_httpx()
instrument_sqlalchemy(engine)

Create custom spans

For custom operations that aren’t covered by library instrumentation, you can create spans manually using the helpers provided by the SDK. These are thin wrappers around the standard OpenTelemetry API, which you can also use directly.

@instrument decorator

Use the @instrument decorator to automatically create a span for a function. It works with both sync and async functions:
from apitally.otel import instrument

@instrument
def process_order(order_id: int) -> None:
    ...

span() context manager

Use the span() context manager to trace code blocks within a function:
from apitally.otel import span

def checkout(cart_id: int) -> None:
    with span("validate_cart") as s:
        s.set_attribute("cart_id", cart_id)
        # Validation logic here
        ...

    with span("process_payment"):
        # Payment logic here
        ...