Skip to content

[google-genai] Provide a way to attach extra attributes to the operation-details event but not to the span#4581

Closed
Achuth17 wants to merge 1 commit into
open-telemetry:mainfrom
Achuth17:feature/log-only-attributes
Closed

[google-genai] Provide a way to attach extra attributes to the operation-details event but not to the span#4581
Achuth17 wants to merge 1 commit into
open-telemetry:mainfrom
Achuth17:feature/log-only-attributes

Conversation

@Achuth17
Copy link
Copy Markdown

@Achuth17 Achuth17 commented May 13, 2026

Fixes #4580

Description

Adds a sibling context key,
GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY, to
opentelemetry-instrumentation-google-genai for attaching caller-supplied
attributes that should be emitted only on the
gen_ai.client.inference.operation.details log event and never on the
generate_content {model} span.

The existing GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY (added in #3961
for spans, extended in #4103 for events) writes attributes to both the
span and the event with no opt-out. That makes it unsafe for caller-supplied
attributes that are acceptable on event log records but must not land on
broadly-sampled spans, for example, an end-user identifier (user.id).

Concrete motivating case: the [Google ADK][adk] passes a
common_attributes dict containing the USER_ID semconv constant
(string value "user.id", 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
has no way today to keep that value off the span without also losing it from
the operation-details event.

The new key follows the exact same naming and access pattern as the
existing GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY, keeping the
public API surface uniform. It is read in all four generate_content
wrappers (sync/async × streaming/non-streaming) and merged into the
LogRecord only — never into span.set_attributes(...). On key collisions
with the existing extras channel, the event-only value wins on the event;
the span carries the existing extra-attributes value.

No new semconv keys are introduced, keys remain caller-defined, like the
existing extras channel. No external dependencies added or changed.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Targeted unit tests (8 new test cases — 2 per wrapper, run for sync +
    async × streaming + non-streaming via the existing shared base classes
    in nonstreaming_base.py and streaming_base.py):

    • test_event_only_extra_attributes_not_set_on_span — verifies an
      attribute attached only via GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY
      is absent from generate_content {model} span attributes.
    • test_event_only_extra_attributes_set_on_event_only — verifies the
      same attribute appears on the
      gen_ai.client.inference.operation.details event LogRecord, plus the
      collision-precedence rule (event-only value wins on the event; the
      existing-extras value is what reaches the span).
  • Test commands run:

    # Targeted (event-only and existing extra-attributes tests, all 4 wrappers):
    uv run tox -e py312-test-instrumentation-google-genai-latest -- -k "event_only or extra_genai_attributes"
    # -> 24 passed, 24 skipped (intentional base-class skips), 0 failed
    
    # Full package suite (no regressions in pre-existing tests):
    uv run tox -e py312-test-instrumentation-google-genai-latest
    # -> 204 passed, 114 skipped, 0 failed
    
    # Static analysis:
    uv run tox -e typecheck
    # -> 0 errors, 0 warnings (pyright)
    
    # Lint + format:
    uvx ruff check  <touched files>
    uvx ruff format --check  <touched files>
    # -> All checks passed; 4 files already formatted

Does This PR Require a Core Repo Change?

  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@linux-foundation-easycla
Copy link
Copy Markdown

CLA Not Signed

@github-actions github-actions Bot added the gen-ai Related to generative AI label May 13, 2026
@DylanRussell
Copy link
Copy Markdown
Contributor

This looks good but should be opened in https://github.com/open-telemetry/opentelemetry-python-genai where we recently moved the instrumentations..

Also open-telemetry/opentelemetry-python-genai#10 -- you might wait until this is merged but I can also merge my PR on top of yours so that doesn't matter too much

@Achuth17
Copy link
Copy Markdown
Author

Moved the PR to open-telemetry/opentelemetry-python-genai#24

Achuth17 added a commit to Achuth17/opentelemetry-python-genai that referenced this pull request May 18, 2026
…ion-details event but not to the span

Add GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY for caller-supplied
attributes that should be emitted only on the
gen_ai.client.inference.operation.details log event and never on the
generate_content {model} span. Threaded through all four wrappers
(sync/async x streaming/non-streaming). On key collisions with
GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY, the event-only value wins on
the event; the span carries the existing extra-attributes value.

Originally proposed at open-telemetry/opentelemetry-python-contrib#4581 before
the package moved to this repo.

Assisted-by: opencode agent
Achuth17 added a commit to Achuth17/opentelemetry-python-genai that referenced this pull request May 18, 2026
…ion-details event but not to the span

Add GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY for caller-supplied
attributes that should be emitted only on the
gen_ai.client.inference.operation.details log event and never on the
generate_content {model} span. Threaded through all four wrappers
(sync/async x streaming/non-streaming).

Precedence on the event: caller-supplied extra_attributes, then
event-only extra_attributes (so they win over extra_attributes on
collision), then request_attributes and final_attributes. Putting the
instrumentation-owned semconv fields last ensures callers cannot
accidentally clobber them (e.g. gen_ai.usage.input_tokens) via the
event-only context value. The span continues to carry only
extra_attributes for any collisions; event-only attributes are never set
on the span.

Tests cover sync/async x streaming/non-streaming for: event-only
attributes not appearing on the span, the event-only-vs-extra-attributes
collision on the event, and event-only not overriding semconv fields.

Originally proposed at open-telemetry/opentelemetry-python-contrib#4581 before
the package moved to this repo.

Assisted-by: opencode agent
Achuth17 added a commit to Achuth17/opentelemetry-python-genai that referenced this pull request May 18, 2026
…ion-details event but not to the span

Add GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY for caller-supplied
attributes that should be emitted only on the
gen_ai.client.inference.operation.details log event and never on the
generate_content {model} span. Threaded through all four wrappers
(sync/async x streaming/non-streaming).

Precedence on the event: caller-supplied extra_attributes, then
event-only extra_attributes (so they win over extra_attributes on
collision), then request_attributes and final_attributes. Putting the
instrumentation-owned semconv fields last ensures callers cannot
accidentally clobber them (e.g. gen_ai.usage.input_tokens) via the
event-only context value. The span continues to carry only
extra_attributes for any collisions; event-only attributes are never set
on the span.

Tests cover sync/async x streaming/non-streaming for: event-only
attributes not appearing on the span, the event-only-vs-extra-attributes
collision on the event, and event-only not overriding semconv fields.

Originally proposed at open-telemetry/opentelemetry-python-contrib#4581 before
the package moved to this repo.

Assisted-by: opencode agent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gen-ai Related to generative AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[google-genai] Provide a way to attach extra attributes to the operation-details event but not to the span

2 participants