Skip to content

Commit e6aea5a

Browse files
authored
feat: use GenAI util for Google ADK spans (#199)
1 parent 9618e0c commit e6aea5a

7 files changed

Lines changed: 1406 additions & 205 deletions

File tree

instrumentation-loongsuite/loongsuite-instrumentation-google-adk/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Changed
11+
12+
- Route Google ADK `AGENT`, `LLM`, and `TOOL` spans through
13+
`opentelemetry-util-genai`, emitting current GenAI attributes such as
14+
`gen_ai.input.messages`, `gen_ai.output.messages`,
15+
`gen_ai.tool.call.arguments`, `gen_ai.tool.call.result`,
16+
`gen_ai.span.kind`, and `gen_ai.provider.name=google_adk`.
17+
([#199](https://github.com/alibaba/loongsuite-python-agent/pull/199))
18+
19+
### Fixed
20+
21+
- Keep Google ADK streaming model spans open until the final response and
22+
protect same-session concurrent invocations from cross-finishing spans.
23+
- Ensure Google ADK spans include LoongSuite `gen_ai.span.kind` values such as
24+
`AGENT`.
25+
1026
## Version 0.5.0 (2026-05-11)
1127

1228
There are no changelog entries for this release.

instrumentation-loongsuite/loongsuite-instrumentation-google-adk/README.md

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ Here's a simple demonstration of Google ADK instrumentation. The demo uses:
7171
export DASHSCOPE_API_KEY=your-dashscope-api-key
7272

7373
# Enable content capture (optional, for debugging)
74-
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
74+
export OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
75+
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY
7576

7677
# Run with loongsuite instrumentation
7778
loongsuite-instrument \
@@ -87,7 +88,8 @@ loongsuite-instrument \
8788
export DASHSCOPE_API_KEY=your-dashscope-api-key
8889

8990
# Configure OTLP exporter
90-
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
91+
export OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
92+
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY
9193
export OTEL_TRACES_EXPORTER=otlp
9294
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
9395
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
@@ -98,6 +100,51 @@ loongsuite-instrument \
98100
python examples/main.py
99101
```
100102

103+
#### Option 3: Local otel-gui smoke scenarios
104+
105+
`examples/otelgui_smoke.py` produces real non-streaming, SSE streaming, and
106+
concurrent Google ADK calls for local trace validation.
107+
108+
```bash
109+
export DASHSCOPE_API_KEY=your-dashscope-api-key
110+
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:5173
111+
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
112+
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:5173/v1/traces
113+
export OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
114+
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLY
115+
export OTEL_SERVICE_NAME=loongsuite-google-adk-smoke
116+
export GOOGLE_ADK_SMOKE_CONFIGURE_OTLP=1
117+
export GOOGLE_ADK_SMOKE_DISABLE_NATIVE_AGENT_SPAN=1
118+
119+
python examples/otelgui_smoke.py --scenario all
120+
```
121+
122+
`GOOGLE_ADK_SMOKE_DISABLE_NATIVE_AGENT_SPAN=1` uses a private ADK telemetry
123+
monkey-patch during smoke validation to remove ADK's native wrapper span, making
124+
the LoongSuite GenAI span tree easier to inspect in otel-gui. Keep it limited to
125+
local smoke tests because private ADK internals may change.
126+
127+
When using the local `loongsuite-otelgui-plugin-verify` helper, select the
128+
GenAI util agent trace explicitly because Google ADK also emits an `invocation`
129+
trace:
130+
131+
```bash
132+
python /path/to/run_loongsuite_plugin_smoke.py \
133+
--repo-root /path/to/loongsuite-python-agent \
134+
--base-url http://127.0.0.1:5173 \
135+
--service-name loongsuite-google-adk-non-stream \
136+
--root-span-contains invoke_agent \
137+
--capture-message-content SPAN_ONLY \
138+
--expect-span-kind AGENT \
139+
--expect-span-kind LLM \
140+
--expect-span-kind TOOL \
141+
--expect-content \
142+
--env GOOGLE_ADK_SMOKE_CONFIGURE_OTLP=1 \
143+
--env GOOGLE_ADK_SMOKE_DISABLE_NATIVE_AGENT_SPAN=1 \
144+
--env OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:5173/v1/traces \
145+
--run "python examples/otelgui_smoke.py --scenario non-stream"
146+
```
147+
101148
### Expected Results
102149

103150
The instrumentation will generate traces showing the Google ADK operations:
@@ -121,10 +168,11 @@ The instrumentation will generate traces showing the Google ADK operations:
121168
},
122169
"attributes": {
123170
"gen_ai.operation.name": "execute_tool",
171+
"gen_ai.span.kind": "TOOL",
124172
"gen_ai.tool.name": "get_current_time",
125173
"gen_ai.tool.description": "xxx",
126-
"input.value": "{xxx}",
127-
"output.value": "{xxx}"
174+
"gen_ai.tool.call.arguments": "{xxx}",
175+
"gen_ai.tool.call.result": "{xxx}"
128176
},
129177
"events": [],
130178
"links": [],
@@ -148,6 +196,7 @@ The instrumentation will generate traces showing the Google ADK operations:
148196
"kind": "SpanKind.CLIENT",
149197
"attributes": {
150198
"gen_ai.operation.name": "chat",
199+
"gen_ai.span.kind": "LLM",
151200
"gen_ai.request.model": "qwen-max",
152201
"gen_ai.response.model": "qwen-max",
153202
"gen_ai.usage.input_tokens": 150,
@@ -164,9 +213,10 @@ The instrumentation will generate traces showing the Google ADK operations:
164213
"kind": "SpanKind.CLIENT",
165214
"attributes": {
166215
"gen_ai.operation.name": "invoke_agent",
216+
"gen_ai.span.kind": "AGENT",
167217
"gen_ai.agent.name": "ToolAgent",
168-
"input.value": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"现在几点了?\"}]}]",
169-
"output.value": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"当前时间是 2025-11-27 14:36:33\"}]}]"
218+
"gen_ai.input.messages": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"What time is it?\"}]}]",
219+
"gen_ai.output.messages": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"The current time is 2025-11-27 14:36:33\"}]}]"
170220
}
171221
}
172222
```
@@ -183,7 +233,8 @@ The following environment variables can be used to configure the Google ADK inst
183233

184234
| Variable | Description | Default |
185235
|----------|-------------|---------|
186-
| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | Capture message content in traces | `false` |
236+
| `OTEL_SEMCONV_STABILITY_OPT_IN` | Enable latest experimental GenAI semantic conventions | - |
237+
| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | Capture message content in traces (`NO_CONTENT`, `SPAN_ONLY`, `SPAN_AND_EVENT`) | `NO_CONTENT` |
187238
| `DASHSCOPE_API_KEY` | DashScope API key (required for demo) | - |
188239

189240
### Programmatic Configuration

0 commit comments

Comments
 (0)