5050from opentelemetry .semconv ._incubating .attributes .gen_ai_attributes import GEN_AI_TOOL_NAME
5151from opentelemetry .semconv ._incubating .attributes .gen_ai_attributes import GEN_AI_TOOL_TYPE
5252from opentelemetry .semconv ._incubating .attributes .gen_ai_attributes import GenAiSystemValues
53- from opentelemetry .semconv ._incubating .attributes .user_attributes import USER_ID
5453from opentelemetry .semconv .attributes .error_attributes import ERROR_TYPE
5554from opentelemetry .semconv .schemas import Schemas
5655from opentelemetry .trace import Span
6362from ._experimental_semconv import maybe_log_completion_details
6463from ._experimental_semconv import set_operation_details_attributes_from_request
6564from ._experimental_semconv import set_operation_details_attributes_from_response
66- from ._experimental_semconv import set_operation_details_common_attributes
6765from ._serialization import safe_json_serialize
6866from ._stable_semconv import choice_body
6967from ._stable_semconv import GEN_AI_CHOICE_EVENT
7472from ._stable_semconv import USER_CONTENT_ELIDED
7573from ._stable_semconv import user_message_body
7674from ._token_usage import TokenUsage
75+ from ._user_id import maybe_propagate_user_id_to_records as _maybe_propagate_user_id_to_records
7776from .context import TelemetryConfig
7877
7978# By default some ADK spans include attributes with potential PII data.
@@ -567,23 +566,19 @@ def use_generate_content_span(
567566 "gcp.vertex.agent.event_id" : model_response_event .id ,
568567 "gcp.vertex.agent.invocation_id" : invocation_context .invocation_id ,
569568 }
570- log_only_common_attributes = {}
571- if invocation_context .session .user_id is not None :
572- log_only_common_attributes [USER_ID ] = invocation_context .session .user_id
573- if _should_emit_native_telemetry (invocation_context .agent ):
574- with _use_native_generate_content_span_stable_semconv (
575- llm_request = llm_request ,
576- common_attributes = common_attributes ,
577- log_only_common_attributes = log_only_common_attributes ,
578- telemetry_config = telemetry_config ,
579- ) as span :
580- yield span .span
581- else :
582- with _use_extra_generate_content_attributes (
583- common_attributes ,
584- log_only_extra_attributes = log_only_common_attributes ,
585- ):
586- yield
569+ with _maybe_propagate_user_id_to_records (
570+ invocation_context .session .user_id , telemetry_config
571+ ):
572+ if _should_emit_native_telemetry (invocation_context .agent ):
573+ with _use_native_generate_content_span_stable_semconv (
574+ llm_request = llm_request ,
575+ common_attributes = common_attributes ,
576+ telemetry_config = telemetry_config ,
577+ ) as span :
578+ yield span .span
579+ else :
580+ with _use_extra_generate_content_attributes (common_attributes ):
581+ yield
587582
588583
589584@asynccontextmanager
@@ -608,39 +603,35 @@ async def use_inference_span(
608603 "gcp.vertex.agent.event_id" : model_response_event .id ,
609604 "gcp.vertex.agent.invocation_id" : invocation_context .invocation_id ,
610605 }
611- log_only_common_attributes = {}
612- if invocation_context .session .user_id is not None :
613- log_only_common_attributes [USER_ID ] = invocation_context .session .user_id
614- if _should_emit_native_telemetry (invocation_context .agent ):
615- async with _use_native_generate_content_span (
616- llm_request = llm_request ,
617- common_attributes = common_attributes ,
618- log_only_common_attributes = log_only_common_attributes ,
619- telemetry_config = telemetry_config ,
620- ) as gc_span :
621- if telemetry_config .should_use_experimental_genai_semconv :
622- set_operation_details_common_attributes (
623- gc_span .operation_details_common_attributes ,
624- telemetry_config ,
625- common_attributes ,
626- log_only_attributes = log_only_common_attributes ,
627- )
628- try :
629- yield gc_span
630- finally :
631- maybe_log_completion_details (
632- gc_span .span ,
633- otel_logger ,
634- gc_span .operation_details_attributes ,
635- gc_span .operation_details_common_attributes ,
636- telemetry_config ,
637- )
638- else :
639- with _use_extra_generate_content_attributes (
640- common_attributes ,
641- log_only_extra_attributes = log_only_common_attributes ,
642- ):
643- yield
606+ # user.id is propagated on the OTel context and copied onto the relevant log
607+ # records by the installed LogRecordProcessor (see ._user_id). This is the
608+ # single mechanism for both the ADK-native and the delegated inference paths;
609+ # on the delegated path the genai instrumentation library owns the records, so
610+ # ADK cannot set the attribute directly.
611+ with _maybe_propagate_user_id_to_records (
612+ invocation_context .session .user_id , telemetry_config
613+ ):
614+ if _should_emit_native_telemetry (invocation_context .agent ):
615+ async with _use_native_generate_content_span (
616+ llm_request = llm_request ,
617+ common_attributes = common_attributes ,
618+ telemetry_config = telemetry_config ,
619+ ) as gc_span :
620+ if telemetry_config .should_use_experimental_genai_semconv :
621+ gc_span .operation_details_common_attributes .update (common_attributes )
622+ try :
623+ yield gc_span
624+ finally :
625+ maybe_log_completion_details (
626+ gc_span .span ,
627+ otel_logger ,
628+ gc_span .operation_details_attributes ,
629+ gc_span .operation_details_common_attributes ,
630+ telemetry_config ,
631+ )
632+ else :
633+ with _use_extra_generate_content_attributes (common_attributes ):
634+ yield
644635
645636
646637def _instrumented_with_opentelemetry_instrumentation_google_genai () -> bool :
@@ -670,7 +661,6 @@ def _should_emit_native_telemetry(agent: BaseAgent) -> bool:
670661@contextmanager
671662def _use_extra_generate_content_attributes (
672663 extra_attributes : Mapping [str , AttributeValue ],
673- log_only_extra_attributes : Mapping [str , AttributeValue ] | None = None ,
674664):
675665 try :
676666 from opentelemetry .instrumentation .google_genai import GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY
@@ -688,18 +678,6 @@ def _use_extra_generate_content_attributes(
688678 ctx = otel_context .set_value (
689679 GENERATE_CONTENT_EXTRA_ATTRIBUTES_CONTEXT_KEY , extra_attributes
690680 )
691- if log_only_extra_attributes :
692- try :
693- from opentelemetry .instrumentation .google_genai import GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY
694-
695- ctx = otel_context .set_value (
696- GENERATE_CONTENT_EVENT_ONLY_EXTRA_ATTRIBUTES_CONTEXT_KEY ,
697- log_only_extra_attributes ,
698- context = ctx ,
699- )
700- except (ImportError , AttributeError ):
701- pass
702-
703681 tok = otel_context .attach (ctx )
704682 try :
705683 yield
@@ -732,7 +710,6 @@ def _set_common_generate_content_attributes(
732710def _use_native_generate_content_span_stable_semconv (
733711 llm_request : LlmRequest ,
734712 common_attributes : Mapping [str , AttributeValue ],
735- log_only_common_attributes : Mapping [str , AttributeValue ] | None = None ,
736713 telemetry_config : TelemetryConfig | None = None ,
737714) -> Iterator [GenerateContentSpan ]:
738715 telemetry_config = telemetry_config or TelemetryConfig ()
@@ -753,13 +730,6 @@ def _use_native_generate_content_span_stable_semconv(
753730 )
754731 )
755732 user_message_attributes = {GEN_AI_SYSTEM : _guess_gemini_system_name ()}
756- if (
757- telemetry_config .should_add_content_to_logs
758- and log_only_common_attributes
759- ):
760- user_id = log_only_common_attributes .get (USER_ID )
761- if user_id is not None :
762- user_message_attributes [USER_ID ] = user_id
763733
764734 for content in llm_request .contents :
765735 otel_logger .emit (
@@ -778,13 +748,11 @@ async def _use_native_generate_content_span(
778748 llm_request : LlmRequest ,
779749 common_attributes : Mapping [str , AttributeValue ],
780750 telemetry_config : TelemetryConfig ,
781- log_only_common_attributes : Mapping [str , AttributeValue ] | None = None ,
782751) -> AsyncIterator [GenerateContentSpan ]:
783752 if not telemetry_config .should_use_experimental_genai_semconv :
784753 with _use_native_generate_content_span_stable_semconv (
785754 llm_request ,
786755 common_attributes ,
787- log_only_common_attributes = log_only_common_attributes ,
788756 telemetry_config = telemetry_config ,
789757 ) as gc_span :
790758 yield gc_span
0 commit comments