open-telemetry / open-telemetry/opentelemetry-python-contrib
psycopg2 instrumentation with cursor argument doesn't work
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 1.1k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 16
Description
Environment
python3.10
opentelemetry-instrumentation-psycopg2: 0.35b2
Steps to reproduce
import psycopg2
import psycopg2.extras
import opentelemetry.instrumentation.psycopg2
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider, sampling
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def main():
tracer_provider = TracerProvider(
sampler=sampling.ALWAYS_ON,
resource=Resource.create(
{
"service.name": "test-postgresql-instrumentation",
"service.version": "1.0.0",
}
),
)
trace.set_tracer_provider(tracer_provider)
tracer_provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://<url>/e/<id>/api/v2/otlp/v1/traces",
headers={
"Authorization": "Api-Token <token>"
},
)
)
)
tracer = trace.get_tracer("test-postgresql-instrumentation-tracer")
opentelemetry.instrumentation.psycopg2.Psycopg2Instrumentor().instrument()
cnx = psycopg2.connect(database="test_db_name")
cursor = cnx.cursor(cursor_factory=psycopg2.extras.DictCursor)
with tracer.start_as_current_span("main-test-span"):
cursor.execute("SELECT * FROM test")
cursor.close()
cnx.close()
if __name__ == "__main__":
main()
What is the expected behavior?
SELECT instrumentation record in main-test-span
What is the actual behavior?
No SELECT record
Additional context
This works (cursor_factory attribute moved to connect method):
import psycopg2
import psycopg2.extras
import opentelemetry.instrumentation.psycopg2
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider, sampling
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def main():
tracer_provider = TracerProvider(
sampler=sampling.ALWAYS_ON,
resource=Resource.create(
{
"service.name": "test-postgresql-instrumentation",
"service.version": "1.0.0",
}
),
)
trace.set_tracer_provider(tracer_provider)
tracer_provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://<url>/e/<id>/api/v2/otlp/v1/traces",
headers={
"Authorization": "Api-Token <token>"
},
)
)
)
tracer = trace.get_tracer("test-postgresql-instrumentation-tracer")
opentelemetry.instrumentation.psycopg2.Psycopg2Instrumentor().instrument()
cnx = psycopg2.connect(database="test_db_name", cursor_factory=psycopg2.extras.DictCursor)
cursor = cnx.cursor()
with tracer.start_as_current_span("main-test-span"):
cursor.execute("SELECT * FROM test")
cursor.close()
cnx.close()
if __name__ == "__main__":
main()
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at Psycopg2Instrumentor and trace how cursor_factory is handled when passed to cnx.cursor(), comparing it with the working connect(..., cursor_factory=...) case. Reproduce both examples, then verify that cursor.execute("SELECT * FROM test") creates a SELECT record inside main-test-span in each case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, python
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100