Skip to content

[draft][VoiceLive] Add built-in OpenTelemetry tracing support#48584

Open
xitzhang wants to merge 4 commits intomainfrom
xitzhang/telemetrylog
Open

[draft][VoiceLive] Add built-in OpenTelemetry tracing support#48584
xitzhang wants to merge 4 commits intomainfrom
xitzhang/telemetrylog

Conversation

@xitzhang
Copy link
Copy Markdown
Member

@xitzhang xitzhang commented Mar 25, 2026

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:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

Copilot AI review requested due to automatic review settings March 25, 2026 22:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 VoiceLiveTracer and wires it into VoiceLiveSessionAsyncClient for connect/send/recv/close spans and session counters.
  • Extends VoiceLiveClientBuilder with openTelemetry(OpenTelemetry) and enableContentRecording(boolean) and plumbs tracing config through VoiceLiveAsyncClient.
  • 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 subscriber onComplete path logs and cleans up but doesn’t call voiceLiveTracer.endConnectSpan(null) (or emit a close span). This will leave spans open and missing final session-level attributes when the server closes the socket without closeAsync() 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 inside fromCallable, but the real send (and possible failure) occurs later in flatMap(this::send). If sendSink.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);

@github-actions
Copy link
Copy Markdown
Contributor

API Change Check

APIView identified API level changes in this PR and created the following API reviews

com.azure:azure-ai-voicelive

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 25, 2026

API Change Check

APIView identified API level changes in this PR and created the following API reviews

com.azure:azure-ai-voicelive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants