-
Notifications
You must be signed in to change notification settings - Fork 907
Description
Describe your environment
Python 3.11 on a M2 Mac.
Steps to reproduce
Run the following code (with python -m asyncio to allow top-level async/await):
import asyncpg
from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
from opentelemetry.trace import set_tracer_provider
provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
set_tracer_provider(provider)
dsn = "postgres://postgres:password@localhost:54320/postgres"
AsyncPGInstrumentor().instrument()
AsyncPGInstrumentor()
connection = await asyncpg.connect(dsn)
await connection.execute("SELECT 1")
What is the expected behavior?
The SQL query runs successfully and a span is exported to the console.
What is the actual behavior?
What did you see instead?
AttributeError: 'NoneType' object has no attribute 'start_as_current_span'
Additional context
Each instantiation of AsyncPGInstrumentor runs __init__, which sets self._tracer to None. However, BaseInstrumentor overrides __new__ to implement the singleton pattern, so only one instance of AsyncPGInstrumentor is ever created. Instantiating AsyncPGInstrumentor after instrument has been called (which sets self._tracer) therefore sets self._tracer back to None, which is a state inconsistent with _is_instrumented_by_opentelemetry (which will still be True).
A simple solution is to remove the line self._tracer = None.