Context
BigQueryAgentAnalyticsPlugin (current as of ADK 1.34.1) emits internal spans agent, llm_request, tool via its TraceManager. Per the source docstring at google/adk/plugins/bigquery_agent_analytics_plugin.py:642-647, these spans intentionally do NOT attach to ambient OTel context to avoid corrupting framework span hierarchy.
Problem
When a global BatchSpanProcessor is configured for an external exporter (e.g., Cloud Trace), those internal spans STILL get exported — SpanProcessor.on_start / on_end fire for every span the tracer creates, regardless of context attachment.
Result in Cloud Trace UI:
- Generic spans
agent, llm_request, tool (no agent name) appear alongside the readable ADK spans invoke_agent {name} / execute_tool {name}
- Because they don't share OTel parent context, they appear as orphan top-level spans with "(Missing span ID xxxx)" parent references
- Hard to read
Current workarounds
- Subclass
SpanProcessor to drop spans with instrumentation_scope.name == "google.adk.plugins.bigquery_agent_analytics" at export time. Works but burns CPU creating spans we then discard, and requires maintenance across ADK bumps
- Disable the plugin entirely — loses the analytics writes which is the plugin's primary purpose
Proposal
Add a config flag on BigQueryLoggerConfig:
class BigQueryLoggerConfig:
...
export_internal_spans: bool = True
"""If False, plugin's internal spans (agent/llm_request/tool) are recorded for BigQuery row generation
but NOT exported via the global TracerProvider's SpanProcessors. Useful when an external trace
backend like Cloud Trace already receives readable spans from ADK's own _instrumentation.py."""
Implementation: gate the tracer.start_span(...) calls in TraceManager.push_span to use a tracer whose spans bypass external SpanProcessors when the flag is False. One approach: maintain a separate TracerProvider internal to the plugin with no SpanProcessor for export — only feeds the plugin's own _SpanRecord stack.
Related issues
Running ADK 1.34.1 with this plugin active in production. The trace export pollution forces a choice between losing the analytics or fighting trace UI noise.
— @rannn505
Context
BigQueryAgentAnalyticsPlugin(current as of ADK 1.34.1) emits internal spansagent,llm_request,toolvia itsTraceManager. Per the source docstring atgoogle/adk/plugins/bigquery_agent_analytics_plugin.py:642-647, these spans intentionally do NOT attach to ambient OTel context to avoid corrupting framework span hierarchy.Problem
When a global
BatchSpanProcessoris configured for an external exporter (e.g., Cloud Trace), those internal spans STILL get exported —SpanProcessor.on_start/on_endfire for every span the tracer creates, regardless of context attachment.Result in Cloud Trace UI:
agent,llm_request,tool(no agent name) appear alongside the readable ADK spansinvoke_agent {name}/execute_tool {name}Current workarounds
SpanProcessorto drop spans withinstrumentation_scope.name == "google.adk.plugins.bigquery_agent_analytics"at export time. Works but burns CPU creating spans we then discard, and requires maintenance across ADK bumpsProposal
Add a config flag on
BigQueryLoggerConfig:Implementation: gate the
tracer.start_span(...)calls inTraceManager.push_spanto use a tracer whose spans bypass external SpanProcessors when the flag is False. One approach: maintain a separateTracerProviderinternal to the plugin with no SpanProcessor for export — only feeds the plugin's own_SpanRecordstack.Related issues
Running ADK 1.34.1 with this plugin active in production. The trace export pollution forces a choice between losing the analytics or fighting trace UI noise.
— @rannn505