[draft][VoiceLive] Add built-in OpenTelemetry tracing support#48584
[draft][VoiceLive] Add built-in OpenTelemetry tracing support#48584
Conversation
There was a problem hiding this comment.
Pull request overview
Adds built-in OpenTelemetry-based tracing instrumentation to the azure-ai-voicelive library, emitting spans for WebSocket session lifecycle and message operations, plus samples/tests/docs to demonstrate and validate the behavior.
Changes:
- Introduces
VoiceLiveTracerand wires it intoVoiceLiveSessionAsyncClientforconnect/send/recv/closespans and session counters. - Extends
VoiceLiveClientBuilderwithopenTelemetry(OpenTelemetry)andenableContentRecording(boolean)and plumbs tracing config throughVoiceLiveAsyncClient. - Adds tracing-focused tests, samples, README section, and changelog entry; updates module metadata and dependencies.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveTracer.java | New tracer implementation (span creation, attributes, counters). |
| sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveSessionAsyncClient.java | Starts/ends session span and traces send/recv/close; adds recv payload handling changes. |
| sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveClientBuilder.java | Adds OpenTelemetry + content recording knobs and creates an OTel Tracer. |
| sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveAsyncClient.java | Plumbs tracer/config to session creation. |
| sdk/voicelive/azure-ai-voicelive/src/main/java/module-info.java | Declares module requirements for OTel API/context. |
| sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/VoiceLiveTracerTest.java | New unit tests validating spans/attrs/counters. |
| sdk/voicelive/azure-ai-voicelive/src/test/java/com/azure/ai/voicelive/VoiceLiveClientBuilderTest.java | Adds builder tests for explicit/default OpenTelemetry behavior. |
| sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/TelemetrySample.java | New runnable tracing sample. |
| sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/VoiceAssistantSample.java | Adds optional CLI flag to enable tracing in the sample. |
| sdk/voicelive/azure-ai-voicelive/src/samples/java/com/azure/ai/voicelive/ReadmeSamples.java | Adds README snippet methods for tracing usage. |
| sdk/voicelive/azure-ai-voicelive/pom.xml | Adds OpenTelemetry dependencies and module-level enforcer stanza. |
| sdk/voicelive/azure-ai-voicelive/checkstyle-suppressions.xml | Suppresses illegal import + external-dependency-exposed checks for tracing changes. |
| sdk/voicelive/azure-ai-voicelive/README.md | Adds “Telemetry and tracing” section and code snippets. |
| sdk/voicelive/azure-ai-voicelive/CHANGELOG.md | Documents new tracing feature + sample. |
Comments suppressed due to low confidence (2)
sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveSessionAsyncClient.java:314
- The session "connect" span is never ended on a normal WebSocket completion (remote close). In
connect(...), the lifecycle subscriberonCompletepath logs and cleans up but doesn’t callvoiceLiveTracer.endConnectSpan(null)(or emit aclosespan). This will leave spans open and missing final session-level attributes when the server closes the socket withoutcloseAsync()being called.
Consider ending the connect span (and optionally emitting traceClose()) in the onComplete handler, or in the closeSignal.asMono().doFinally(...) block so it runs for both error and normal completion.
}, () -> {
LOGGER.info("WebSocket handler completed");
connectionCloseSignalRef.compareAndSet(closeSignal, null);
disposeLifecycleSubscription();
});
sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveSessionAsyncClient.java:415
- The send span is created and ended before the actual WebSocket send happens.
traceSend(event, json)runs insidefromCallable, but the real send (and possible failure) occurs later inflatMap(this::send). IfsendSink.tryEmitNext(...)fails (or any downstream send error occurs), the send span will still appear successful and won’t capture the exception/status.
To align with the PR intent (“span per send operation”), consider moving span lifecycle to wrap the actual send Mono, and set span status/recordException when the send fails.
return Mono.fromCallable(() -> {
try {
String json = serializer.serialize(event, SerializerEncoding.JSON);
// Trace the send operation
if (voiceLiveTracer != null) {
voiceLiveTracer.traceSend(event, json);
}
return BinaryData.fromString(json);
} catch (IOException e) {
throw LOGGER.logExceptionAsError(new RuntimeException("Failed to serialize event", e));
}
}).flatMap(this::send);
sdk/voicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveTracer.java
Show resolved
Hide resolved
...ive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveSessionAsyncClient.java
Show resolved
Hide resolved
...oicelive/azure-ai-voicelive/src/main/java/com/azure/ai/voicelive/VoiceLiveClientBuilder.java
Show resolved
Hide resolved
API Change CheckAPIView identified API level changes in this PR and created the following API reviews |
API Change CheckAPIView identified API level changes in this PR and created the following API reviews |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…e-sdk-for-java into xitzhang/telemetrylog
Description
[VoiceLive] Add built-in OpenTelemetry tracing support
Summary
Adds built-in OpenTelemetry tracing to the VoiceLive SDK following GenAI semantic conventions. Tracing is zero-cost by default using GlobalOpenTelemetry.getOrNoop() and activates automatically when a Java agent or explicit OpenTelemetry instance is configured via the builder. The tracer version is derived at runtime from the Maven-filtered properties file so it stays in sync with the shipped library version.
What's included
Core tracing — A new VoiceLiveTracer class manages parent-child span hierarchies for connect, send, receive, and close operations. Session-level counters track turn count, interruption count, audio bytes sent/received, and first-token latency, all stamped on the parent connect span at close.
Builder API — Two new methods on VoiceLiveClientBuilder: openTelemetry(OpenTelemetry) for explicit configuration and enableContentRecording(boolean) for opt-in content capture.
Dependencies — opentelemetry-api at compile scope (approximately 200 KB); SDK, testing, and logging exporter at test scope only. Maven enforcer whitelist updated. Checkstyle suppressions follow the azure-ai-inference pattern.
Samples — A runnable TelemetrySample demonstrates tracing with LoggingSpanExporter. VoiceAssistantSample gains an opt-in --enable-tracing CLI flag.
Documentation — README covers automatic and explicit tracing configuration, span structure, session-level attributes, and content recording. CHANGELOG entry added under 1.0.0-beta.6 (Unreleased).
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines