OpenTelemetry AsyncPG Instrumentation

0.62b0 · active · verified Thu Apr 09

This library provides OpenTelemetry tracing instrumentation for the `asyncpg` PostgreSQL driver. It allows for automatic capturing of database queries as spans, providing visibility into asynchronous PostgreSQL operations within an OpenTelemetry-instrumented Python application. As part of the `opentelemetry-python-contrib` repository, it often receives frequent beta releases.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up OpenTelemetry to trace `asyncpg` database operations. It initializes a `TracerProvider` with a `ConsoleSpanExporter` to print traces to the console, then instruments the `asyncpg` library. An asynchronous function connects to a PostgreSQL database (using environment variables for credentials) and executes a simple query, generating a trace automatically. A running PostgreSQL instance is required, which can be easily started with Docker.

import asyncio
import os

import asyncpg
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor

# 1. Setup OpenTelemetry TracerProvider
resource = Resource.create({"service.name": "asyncpg-app"})
tracer_provider = TracerProvider(resource=resource)
span_processor = BatchSpanProcessor(ConsoleSpanExporter())
tracer_provider.add_span_processor(span_processor)
trace.set_tracer_provider(tracer_provider)

# 2. Instrument asyncpg
AsyncPGInstrumentor().instrument()

async def main():
    # Database connection details from environment variables or defaults
    user = os.environ.get('POSTGRES_USER', 'user')
    password = os.environ.get('POSTGRES_PASSWORD', 'password')
    database = os.environ.get('POSTGRES_DB', 'database')
    host = os.environ.get('POSTGRES_HOST', 'localhost')
    port = os.environ.get('POSTGRES_PORT', '5432')

    # Ensure asyncpg is available before attempting connection
    try:
        conn = await asyncpg.connect(
            user=user, password=password, database=database, host=host, port=port
        )
        print(f"Connected to PostgreSQL at {host}:{port}/{database}")

        # Perform a database operation that will be traced
        result = await conn.fetchval("SELECT 42 as my_value;")
        print(f"Query result: {result}")

        await conn.close()
        print("Connection closed.")

    except Exception as e:
        print(f"Failed to connect or query PostgreSQL: {e}")
        print("Ensure a PostgreSQL instance is running and accessible (e.g., via Docker):")
        print("docker run -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password -e POSTGRES_DB=database -p 5432:5432 postgres")

if __name__ == "__main__":
    # Run the asynchronous main function
    asyncio.run(main())

# Optional: Flush spans before exiting for console exporter
# For real applications, use a proper exporter like OTLPSpanExporter
# and ensure processes have time to send data.

view raw JSON →