[openai] Record cache-write and modality token usage - #681
Conversation
Signed-off-by: 1fanwang <1fannnw@gmail.com>
Pull request dashboard statusWaiting on the author · refreshed 2026-09-13 22:36 UTC Respond to 2 review items (e.g. link a commit, explain why not, ask a follow-up): Status above doesn't look right?
|
Signed-off-by: 1fanwang <1fannnw@gmail.com>
Signed-off-by: 1fanwang <1fannnw@gmail.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Add integer type assertions for exported usage attributes in the regression tests.
Pull request overview
Adds OpenAI Chat Completions cache-write and modality token usage recording for synchronous, asynchronous, and streaming calls.
Changes:
- Extracts detailed usage fields into telemetry.
- Adds local HTTP/SSE regression coverage.
- Adds a changelog entry.
File summaries
| File | Description |
|---|---|
instrumentation/opentelemetry-instrumentation-genai-openai/tests/test_chat_token_usage.py |
Tests usage-detail variants across call modes. |
instrumentation/opentelemetry-instrumentation-genai-openai/src/opentelemetry/instrumentation/genai/openai/utils.py |
Extracts detailed usage fields. |
instrumentation/opentelemetry-instrumentation-genai-openai/src/opentelemetry/instrumentation/genai/openai/patch.py |
Applies extraction to non-streaming responses. |
instrumentation/opentelemetry-instrumentation-genai-openai/src/opentelemetry/instrumentation/genai/openai/chat_wrappers.py |
Applies extraction to streaming responses. |
instrumentation/opentelemetry-instrumentation-genai-openai/.changelog/603.added |
Documents the feature. |
Review details
Suppressed comments (1)
instrumentation/opentelemetry-instrumentation-genai-openai/tests/test_chat_token_usage.py:222
- This only checks equality, so a
boolorfloatusage value would still pass (True == 1and1.0 == 1). The new semconv usage attributes must be integers; assert the types of the exported values here so the regression test catches invalid attribute values.
assert actual == expected
- Files reviewed: 5/5 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
lmolkova
left a comment
There was a problem hiding this comment.
Please make sure to follow existing test practices in this repo
| ) | ||
| invocation.text_input_tokens = get_property_value( | ||
| prompt_details, "text_tokens" | ||
| ) |
There was a problem hiding this comment.
OpenAI Chat Completions does not expose text_tokens or image_tokens in prompt_tokens_details or completion_tokens_details. Only cache_write_tokens and audio_tokens exist on PromptTokensDetails, and audio_tokens on CompletionTokensDetails. Please remove the non-existent modality mappings.
There was a problem hiding this comment.
| self._self_cached_prompt_tokens = get_property_value( | ||
| prompt_tokens_details, "cached_tokens" | ||
| ) | ||
| set_chat_usage_details( |
There was a problem hiding this comment.
Do not mutate invocation directly during chunk processing. Buffer the token details on the wrapper instance with a _self_ prefix and assign them to self._self_invocation in _cleanup().
| "choices": [ | ||
| { | ||
| "index": 0, | ||
| "delta": { |
There was a problem hiding this comment.
Do not spin up a custom ThreadingHTTPServer with synthetic responses. Use standard VCR cassettes or client unit mocks consistent with the rest of the test suite.
Signed-off-by: 1fanwang <1fannnw@gmail.com>
Signed-off-by: 1fanwang <1fannnw@gmail.com>
| return getattr(obj, property_name, None) | ||
|
|
||
|
|
||
| def set_chat_usage_details( |
There was a problem hiding this comment.
The token-detail extraction is duplicated between this helper and the stream wrapper. Please share extraction across both paths, buffering the values until stream cleanup.
Please also wait for #674 to land, then reuse its set_input_tokens() and set_output_tokens() helpers for modality breakdowns. Keep the aggregate cache-write count separate.
Description
Chat Completions drops optional cache-write and modality counts. This exports them, with streaming details applied at cleanup.
OpenAI 3.1.0 defines the text/image fields. Missing and zero values remain omitted.
Fixes #603.
Type of change
How has this been tested?
Client mocks drive real instrumentation with typed SDK responses.
From the configured latest tox environment:
Raw logs
Before:
After:
These runs do not call the provider or exercise Weaver.
Checklist
See CONTRIBUTING.md
for the style guide, changelog guidance, and more.