[google-genai] Provide a way to attach extra attributes to the operation-details event but not to the span
feature-request
### What problem do you want to solve?
`opentelemetry-instrumentation-google-genai` currently exposes a single channel
for callers to attach extra attributes to `generate_content` telemetry:
[`GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY`][key] (added in #3961, #4103).
Whatever a caller puts there is written to **both**:
- the `generate_content {model}` span (via `span.set_attributes(...)`), and
- the `gen_ai.client.inference.operation.details` log event (via the
`LogRecord` emitted in `_maybe_log_completion_details`).
There is no way to mark a caller-supplied attribute as event-only.
The existing `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` env var
(modes: `NO_CONTENT` / `SPAN_ONLY` / `EVENT_ONLY` / `SPAN_AND_EVENT`) only gates
the standard semconv message-content fields (`gen_ai.input.messages`,
`gen_ai.output.messages`, etc.) — not arbitrary caller-supplied extras.
This matters when callers want to attach attributes that are acceptable for
audit-style log/event consumers but undesirable on broadly-sampled spans —
for example, an end-user identifier (`user.id`). A concrete instance: the
[Google ADK][adk] passes a `common_attributes` dict containing
`user.id` (the `USER_ID` semconv constant from
`opentelemetry.semconv._incubating.attributes.user_attributes`) through this
context key, which causes `user.id` to land on every `generate_content` span
as soon as `opentelemetry-instrumentation-google-genai` is installed.
ADK currently has no way to keep that value off the span without also losing
it from the operation-details event.
[key]: https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/generate_content.py#L100
[adk]: https://github.com/google/adk-python
### Describe the solution you'd like
Add a sibling context key (`GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY`) that is read by all four `generate_content` wrappers
(sync/async × streaming/non-streaming) but is **only** merged into the
`gen_ai.client.inference.operation.details` `LogRecord`, never into
`span.set_attributes(...)`.
Behavior:
- Keys attached under the new context key appear on the
`gen_ai.client.inference.operation.details` event log record.
- Those keys never appear on the `generate_content {model}` span.
- On key collisions with the existing `GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY`,
the event-only value wins on the event; the span carries the existing
extra-attributes value.
- The new constant is re-exported from `opentelemetry.instrumentation.google_genai`
alongside `GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY`.
### Describe alternatives you've considered
1. Have callers strip the attribute before calling the SDK and re-attach it
to log records via a separate path. This is what ADK is being pushed
toward today, but it requires duplicating the operation-details event
construction outside contrib (or post-processing the LogRecord), defeating
the point of having the contrib instrumentation own the event.
2. A new env var (e.g. `OTEL_INSTRUMENTATION_GENAI_DROP_SPAN_ATTRIBUTES`)
listing attribute keys to strip from spans. Rejected because it puts the
policy in deployment config rather than in the code that knows the
attribute's semantics, and because keys are caller-defined there's no
useful default list contrib could ship.
### Additional Context
_No response_
### Would you like to implement a fix?
Yes
### Tip
<sub>[React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
关闭于 2026-05-15 1 条评论