Repository navigation
Description
Describe your environment
- OS: macOS 15 (arm64)
- Python: 3.13.13
- Package version:
opentelemetry-instrumentation-openai-v22.4b0 - Related:
openai3.0.0,httpx0.28.1,httpx22.10.0
What happened?
Spans produced for OpenAI SDK calls no longer carry the server.address (or server.port) attribute
when the installed openai is 3.x. The same code against openai 2.54.0 records them normally.
The cause is in instrumentation/openai_v2/utils.py:
from httpx import URL # line 23
...
def get_server_address_and_port(client_instance): # line 98
base_client = getattr(client_instance, "_client", None)
base_url = getattr(base_client, "base_url", None)
if not base_url:
return None, None
address = None
port = None
if isinstance(base_url, URL): # httpx.URL
address = base_url.host
port = base_url.port
elif isinstance(base_url, str):
url = urlparse(base_url)
address = url.hostname
port = url.port
...openai 3.x builds on httpx2, so client._client.base_url is an httpx2.URL. It is neither an
httpx.URL nor a str, so both branches are skipped and the function returns (None, None). Because the
values are only set when truthy, the attributes are dropped silently, with no warning and no error.
Steps to reproduce
from openai import OpenAI
from opentelemetry.instrumentation.openai_v2.utils import get_server_address_and_port
client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key="x")
print(type(client._client.base_url)) # <class 'httpx2.URL'>
print(get_server_address_and_port(client.chat.completions))
# openai 2.54.0 -> ('openrouter.ai', None)
# openai 3.0.0 -> (None, None)End to end, with a real request through the instrumentor, the emitted span attributes are:
openai 2.54.0: gen_ai.operation.name, gen_ai.provider.name, gen_ai.request.model,
gen_ai.response.finish_reasons, gen_ai.response.id, gen_ai.response.model,
gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, server.address
openai 3.0.0 : (identical, minus server.address)
Expected result
server.address and server.port are recorded regardless of which URL type the SDK uses internally, as
required by the semantic conventions for client spans.
Actual result
Both attributes are absent on openai 3.x.
Why it matters beyond a missing attribute
gen_ai.provider.name names the SDK, not the operator of the endpoint. For anything reached through
the OpenAI-compatible protocol, such as a router or gateway, an Azure OpenAI deployment, or a self-hosted
vLLM or Ollama server, server.address is the only attribute distinguishing them. Without it, all of these are
indistinguishable from a direct api.openai.com call, so consumers that attribute traffic per provider or
per region will silently misattribute it. It fails quietly, which makes it easy to miss in a version bump.
Suggested fix
Avoid the type check and read the URL structurally, which also covers any future URL implementation:
def get_server_address_and_port(client_instance):
base_client = getattr(client_instance, "_client", None)
base_url = getattr(base_client, "base_url", None)
if not base_url:
return None, None
address = getattr(base_url, "host", None)
port = getattr(base_url, "port", None)
if not address: # plain string base_url
parsed = urlparse(str(base_url))
address, port = parsed.hostname, parsed.port
if port == 443:
port = None
return address, portBoth httpx.URL and httpx2.URL expose .host / .port, so this keeps existing behaviour and fixes
3.x. A regression test asserting server.address is present for a non-default base_url would catch the
next recurrence. The current tests pass with the attribute missing.
I'm happy to open a PR with the fix and the test if that's useful.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
ari-abb commentedon Aug 12, 2026
Two additions after further investigation, one of which makes this more severe than the report above.
The package is unimportable on a clean
openai3.x install, not just missing an attributeopentelemetry-instrumentation-openai-v2declares no dependency onhttpx(Requires-Distlists onlythe
opentelemetry-*packages, plusopenai>=1.26.0under theinstrumentsextra), andopenai3.xrequires
httpx2<3,>=2.7.0rather thanhttpx. So on a clean install ofopenai==3.0.0withopentelemetry-instrumentation-openai-v2==2.4b0,httpxis simply not present, and the module-scopefrom httpx import URLatutils.py:23fails outright:The environment in the original report only got as far as a missing
server.addressbecausehttpxhappened to be installed transitively by unrelated packages. Without that coincidence the instrumentation
does not load at all, so nothing is recorded. Same root cause, more severe symptom, and it fails quietly
from the operator's point of view: auto-instrumentation that never attaches looks identical to an
application that made no calls.
The suggested fix in the report resolves both symptoms, since removing the
isinstancecheck alsoremoves the only use of the import.
URLis referenced in exactly one place, so the import can bedropped rather than made conditional.
Related httpx2 work
This looks like a spot missed by the recent httpx2 migration rather than a separate problem:
Given that,
openai_v2may not be the only instrumentation affected. Anywhere anisinstancecheckagainst an
httpxtype guards attribute extraction will behave the same way once the underlying SDKmoves to
httpx2: the check silently stops matching, and the attributes quietly disappear. Reading theURL structurally with
getattr(base_url, "host", None)avoids the coupling entirely.I am happy to open a PR with the fix, a regression test asserting
server.addressis present for anon-default
base_url, and a test that the package imports withouthttpxinstalled.aabmass commentedon Aug 13, 2026
Hi @ari-abb can thanks for the PR, but development on this has moved to https://github.com/open-telemetry/opentelemetry-python-genai (see #4924). The version in this repo will be deleted from this repo once we make a final release with the deprecation notice.
I'm happy to transfer the issue over if you can reopen the PR?
ari-abb commentedon Aug 14, 2026
Hey @aabmass thanks for the heads up. Feel free to move the issue and I can reopen the PR 👍