Conversation
Android mirrors the Swift integration. The Rust core (livekit-uniffi 0.0.1, prototype local build from Maven Local) owns the pipeline, every policy and the vocabulary; the SDK contributes a bytes-moving OkHttp transport, the platform instruments, and the wiring of Room / engine / tracks / stats / logs into the core's API. UniFFI types stay out of the public API, and telemetry off means every hook is a no-op (the core is not even loaded). - TelemetryOptions mirrors TelemetryConfig; Telemetry.configure / shutdown / setAttribute / diagnostics; LiveKit.setTelemetry(context, options). - Room takes its scope at creation: the lk.connect span (ws_open, signal, join_recv, pc_created, offer_sent / answer_sent, engine, pc_connected, room_connected), lk.reconnect with the reason and "attempt N quick|full" steps, lk.publish with the track, setRoom after join, disconnected(reason) once per real session, telemetryTraceId and emitTelemetryEvent. - Instruments: device (thermal status, battery saver, trim-memory, default network type / metered / Data Saver, battery; AudioSwitch route and focus changes; camera and microphone capture failures), logs (LKLog warn+ whatever the console level, WebRTC at error, the core's own lines forwarded into LKLog), rtc (raw getStats reports per published / subscribed track once a second via recordStatsReport, and the subscribe lifecycle via subscribeStarted / subscribed / subscribeCancelled / subscribeFailed; the core maps the stats and runs the lk.subscribe span). - TelemetryMockE2ETest drives connect, quick reconnect, publish, a log record inside a span, a custom event and disconnect through the mocks against a local collector and asserts what reached it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… span The Room's scope rides the Room's, the engine's and the signal client's coroutine scopes as a ThreadLocal context element (Telemetry.currentScope), the way the current span does. The log capture files a warn/error record through TelemetryScope.log when a Room scope is ambient and no span is in flight; inside a span, and with neither, it stays telemetryLog. The engine now holds the ungated scope and gates the lk.reconnect span itself. The e2e test asserts a Room-handler warning (an unpublish for an unknown track) in the Room's trace with no span, and a record logged outside any Room context in the process scope. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Contributor
|
Dependency diff: +--- com.squareup.okhttp3:okhttp:4.12.0
| \--- com.squareup.okio:okio:3.6.0
| \--- com.squareup.okio:okio-jvm:3.6.0
| \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.10 -> 1.9.25
-| \--- org.jetbrains:annotations:13.0 -> 23.0.0
+| \--- org.jetbrains:annotations:13.0
+--- com.github.davidliu:audioswitch:039a35aefab7747c557242fa216c9ea11743b604
-| \--- androidx.annotation:annotation:1.3.0 -> 1.9.0
-| \--- androidx.annotation:annotation-jvm:1.9.0
-| \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 1.9.25 (*)
+| \--- androidx.annotation:annotation:1.3.0 -> 1.7.1
+| \--- androidx.annotation:annotation-jvm:1.7.1
+| \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 1.9.25 (*)
-+--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0 -> 1.8.1
-| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1
-| | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1
-| | +--- org.jetbrains:annotations:23.0.0
-| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1
-| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 (c)
-| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1 (c)
-| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (c)
-| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.25 (*)
-| +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1 (*)
-| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 1.9.25 (*)
++--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0 -> 1.6.4
+| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
+| | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4
+| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4
+| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 (c)
+| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4 (c)
+| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4 (c)
+| | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21 -> 1.9.10 (*)
+| | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21 -> 1.9.25 (*)
+| +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4 (*)
+| \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21 -> 1.9.10 (*)
-+--- io.livekit:livekit-uniffi-android:0.1.12
-| +--- androidx.annotation:annotation:1.9.0 (*)
-| +--- net.java.dev.jna:jna:5.19.1
-| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 (*)
-| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 1.9.25 (*)
++--- io.livekit:livekit-uniffi-android:0.0.1 FAILED
+--- com.auth0.android:jwtdecode:2.0.2
-| \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+| \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
-+--- androidx.annotation:annotation:1.7.1 -> 1.9.0 (*)
++--- androidx.annotation:annotation:1.7.1 (*)
\--- androidx.core:core:1.13.1
- +--- androidx.annotation:annotation:1.6.0 -> 1.9.0 (*)
+ +--- androidx.annotation:annotation:1.6.0 -> 1.7.1 (*)
+--- androidx.collection:collection:1.0.0
- | \--- androidx.annotation:annotation:1.0.0 -> 1.9.0 (*)
+ | \--- androidx.annotation:annotation:1.0.0 -> 1.7.1 (*)
+--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0
- | \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
+--- androidx.interpolator:interpolator:1.0.0
- | \--- androidx.annotation:annotation:1.0.0 -> 1.9.0 (*)
+ | \--- androidx.annotation:annotation:1.0.0 -> 1.7.1 (*)
+--- androidx.lifecycle:lifecycle-runtime:2.6.2
- | +--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | +--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
| +--- androidx.arch.core:core-common:2.2.0
- | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | | \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
| +--- androidx.arch.core:core-runtime:2.2.0
- | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | | \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
| +--- androidx.lifecycle:lifecycle-common:2.6.2
- | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | | +--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
- | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.8.1 (*)
+ | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 (*)
| \--- androidx.profileinstaller:profileinstaller:1.3.0
- | +--- androidx.annotation:annotation:1.2.0 -> 1.9.0 (*)
+ | +--- androidx.annotation:annotation:1.2.0 -> 1.7.1 (*)
| \--- androidx.startup:startup-runtime:1.1.1
- | +--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | +--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
| \--- androidx.tracing:tracing:1.0.0
- | \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ | \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*)
\--- androidx.versionedparcelable:versionedparcelable:1.1.1
- \--- androidx.annotation:annotation:1.1.0 -> 1.9.0 (*)
+ \--- androidx.annotation:annotation:1.1.0 -> 1.7.1 (*) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Telemetry
Draft: integrates the shared Rust telemetry core (
livekit-telemetry, livekit/rust-sdks#1396) into the Android SDK, per the "Client Telemetry" design doc. Same shape as the Swift integration (livekit/client-sdk-swift#1108); the core owns policy and vocabulary, the SDK contributes a transport, instruments and the wiring.Design
Telemetryis the one entry point:LiveKit.setTelemetry(context, options)/Telemetry.configure(context, options)configure the process-wide pipeline (it lives in the Rust core) at any time; everyRoomtakes a scope with its own trace id at construction (room.telemetryTraceId), so pre-connect failures are captured and nothing leaks a session handle.TelemetryOptionsmirrors the core's config (endpoint, headers, storage directory, flush interval, stats window, instruments, log level); nothing from UniFFI is public.TelemetryOptions.instruments(ROOM,RTC,LOGS,DEVICE; all by default):DeviceTelemetry(thermal status, power save, trim-memory, network capabilities incl. metered and Data Saver, battery, AudioSwitch route and focus changes, camera and microphone capture failures), warn/error records fromLKLog, the Rust core and WebRTC, and per Room thelk.connect/lk.reconnect/lk.publishspans with their checkpoints fromRoom,RTCEngine,SignalClientandLocalParticipant;RTCTelemetryreports the remote tracks' lifecycle and the core runs thelk.subscribespan itself; once a second each track's rawgetRTCStats()report goes to the core, which maps and windows it. A Room's records carry its session even outside a span.TelemetryOptions.endpointis set.Testing
TelemetryMockE2ETestruns a mock session (MockE2ETest: mock websocket, peer connections and a mock audio track) with telemetry pointed at anotelcol-contribwriting OTLP/JSON to disk and asserts the spans, steps and records that reached it; it skips when no collector listens. Robolectric runs the real Rust core through JNA (-PlivekitUniffiLibraryPathnames the host library). The UniFFI dependency points at a locally builtio.livekit:livekit-uniffi-android:0.0.1in Maven Local for now.