traceloop / traceloop/openllmetry
๐ Bug Report: Duplicate OpenAI chat completion traces when using httpx instrumentor
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.4k
- Forks
- 1.1k
- Avg merge
- 8d 14h
- Merged PRs (30d)
- 2
Description
Which component is this bug for?
OpenAI Instrumentation
๐ Description
If you use the httpx instrumentor and the openai instrumentor you get duplicated traces recorded.
๐ Reproduction steps
Here is some minimal code to recreate the issue
# install
# "openai>=1.76.0",
# "opentelemetry-api>=1.32.1",
# "opentelemetry-exporter-otlp>=1.32.1",
# "opentelemetry-instrumentation-httpx>=0.53b1",
# "opentelemetry-instrumentation-openai>=0.39.3",
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.httpx import HTTPXClientInstrumentor
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
resource = Resource(attributes={"service.name": "test-service"})
provider = TracerProvider(resource=resource)
trace.set_tracer_provider(provider)
OTEL_ENDPOINT = "http://localhost:4318/v1/traces" # Replace with your OpenTelemetry Collector endpoint
otlp_exporter = OTLPSpanExporter(endpoint=OTEL_ENDPOINT)
span_processor = BatchSpanProcessor(otlp_exporter)
provider.add_span_processor(span_processor)
HTTPXClientInstrumentor().instrument()
OpenAIInstrumentor().instrument()
from openai import AsyncOpenAI
import asyncio
OPENAI_API_KEY = "key"
async def run():
client = AsyncOpenAI(api_key=OPENAI_API_KEY)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("test-span"):
resp = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": "say hello only",
}
],
)
print(resp.choices[0].message.content)
def main():
asyncio.run(run())
if __name__ == "__main__":
main()
๐ Expected behavior
Ideally the openai instrumentor should suppress all traces from httpx.
๐ Actual Behavior with Screenshots
as you can see in the jaeger screenshot there are duplicated spans. These do not follow the typical parent child relationship you would expect from nested spans (which would also mitigate the issue)
๐ค Python Version
3.13
๐ Provide any additional context for the Bug.
No response
๐ Have you spent some time to check if this bug has been raised before?
- I checked and didn't find similar issue
Are you willing to submit PR?
Yes I am willing to submit a PR!
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 by running the provided reproduction with both HTTPXClientInstrumentor and OpenAIInstrumentor enabled, then inspect the OpenAI and HTTPX instrumentation entry points involved in creating spans. Done means the OpenAI request produces one expected trace without duplicate HTTPX spans while the two instrumentors remain enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100