From fe6859cec267eeefa7f86aa712f82e5deed0a3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Braz=CC=87ewicz?= Date: Fri, 10 Jul 2026 11:09:44 +0200 Subject: [PATCH 1/3] align sfu events naming with other SDKs --- packages/stream_video/lib/src/call/call.dart | 12 +++---- .../lib/src/call/session/call_session.dart | 17 +++++----- .../stream_video/lib/src/sfu/sfu_client.dart | 32 +++++++++---------- .../lib/src/sfu/sfu_extensions.dart | 23 +++++++++++++ .../src/webrtc/traced_peer_connection.dart | 23 +++++++------ 5 files changed, 67 insertions(+), 40 deletions(-) diff --git a/packages/stream_video/lib/src/call/call.dart b/packages/stream_video/lib/src/call/call.dart index c8632d2a6..40831fe96 100644 --- a/packages/stream_video/lib/src/call/call.dart +++ b/packages/stream_video/lib/src/call/call.dart @@ -1135,7 +1135,7 @@ class Call { '[join] $sfuMigrateReason for SFU: $sfuName, migrating...', ); - _session?.trace('call_join_migrate', { + _session?.trace('callJoin.migrate', { 'migrateFrom': sfuName, 'reason': sfuMigrateReason, }); @@ -1306,7 +1306,7 @@ class Call { _suspendedTrackStates[trackId] = SuspendedTrackState.neverStarted; }, onReconnectionNeeded: (pc, strategy) { - _session?.trace('pc_reconnection_needed', { + _session?.trace('pc.reconnectionNeeded', { 'peerConnectionId': pc.type.name, 'reconnectionStrategy': strategy.name, }); @@ -1823,7 +1823,7 @@ class Call { )) { _logger.w(() => '[onSfuEvent] socket disconnected'); - _session?.trace('sfu_socket_disconnected', { + _session?.trace('sfuSocket.disconnected', { 'closeCode': sfuEvent.reason.closeCode, 'closeReason': sfuEvent.reason.closeReason, }); @@ -1840,7 +1840,7 @@ class Call { } } else if (sfuEvent is SfuSocketFailed) { _logger.w(() => '[onSfuEvent] socket failed'); - _session?.trace('sfu_socket_failed', { + _session?.trace('sfuSocket.failed', { 'error': sfuEvent.error.message, }); await _reconnect( @@ -1849,7 +1849,7 @@ class Call { ); } else if (sfuEvent is SfuGoAwayEvent) { _logger.w(() => '[onSfuEvent] go away, migrating sfu'); - _session?.trace('sfu_go_away', { + _session?.trace('sfuSocket.goAway', { 'reason': sfuEvent.goAwayReason.name, }); await _reconnect( @@ -1859,7 +1859,7 @@ class Call { } // error event else if (sfuEvent is SfuErrorEvent) { - _session?.trace('sfu_error', { + _session?.trace('sfuSocket.error', { 'code': sfuEvent.error.code.name, 'error': sfuEvent.error.message, 'strategy': sfuEvent.error.reconnectStrategy.name, diff --git a/packages/stream_video/lib/src/call/session/call_session.dart b/packages/stream_video/lib/src/call/session/call_session.dart index a6dea4db3..278465548 100644 --- a/packages/stream_video/lib/src/call/session/call_session.dart +++ b/packages/stream_video/lib/src/call/session/call_session.dart @@ -716,25 +716,25 @@ class CallSession extends Disposable { } else if (event is SfuParticipantLeftEvent) { await _onParticipantLeft(event); } else if (event is SfuTrackPublishedEvent) { - _tracer.trace('TrackPublished', event.toJson()); + _tracer.trace('trackPublished', event.toJson()); await _onTrackPublished(event); } else if (event is SfuTrackUnpublishedEvent) { - _tracer.trace('TrackUnpublish', event.toJson()); + _tracer.trace('trackUnpublished', event.toJson()); await _onTrackUnpublished(event); } else if (event is SfuChangePublishQualityEvent) { - _tracer.trace('PublishQualityChanged', event.toJson()); + _tracer.trace('changePublishQuality', event.toJson()); await _onPublishQualityChanged(event); } else if (event is SfuChangePublishOptionsEvent) { - _tracer.trace('PublishOptionsChanged', event.toJson()); + _tracer.trace('changePublishOptions', event.toJson()); await _onPublishOptionsChanged(event); } else if (event is SfuIceRestartEvent) { await _onIceRestart(event); } else if (event is SfuGoAwayEvent) { - _tracer.trace('GoAway', event.toJson()); + _tracer.trace('goAway', event.toJson()); } else if (event is SfuErrorEvent) { - _tracer.trace('Error', event.toJson()); + _tracer.trace('error', event.toJson()); } else if (event is SfuCallEndedEvent) { - _tracer.trace('CallEnded', event.toJson()); + _tracer.trace('callEnded', event.toJson()); } if (event is SfuJoinResponseEvent) { @@ -746,7 +746,7 @@ class CallSession extends Disposable { } else if (event is SfuParticipantLeftEvent) { stateManager.sfuParticipantLeft(event); } else if (event is SfuConnectionQualityChangedEvent) { - _tracer.trace('ConnectionQualityChanged', event.toJson()); + _tracer.trace('connectionQualityChanged', event.toJson()); stateManager.sfuConnectionQualityChanged(event); } else if (event is SfuAudioLevelChangedEvent) { stateManager.sfuUpdateAudioLevelChanged(event); @@ -759,6 +759,7 @@ class CallSession extends Disposable { } else if (event is SfuPinsUpdatedEvent) { stateManager.sfuPinsUpdated(event.pins); } else if (event is SfuInboundStateNotificationEvent) { + _tracer.trace('inboundVideoState', event.toJson()); stateManager.sfuInboundStateNotification(event); } }); diff --git a/packages/stream_video/lib/src/sfu/sfu_client.dart b/packages/stream_video/lib/src/sfu/sfu_client.dart index 83634d39e..15bd520fd 100644 --- a/packages/stream_video/lib/src/sfu/sfu_client.dart +++ b/packages/stream_video/lib/src/sfu/sfu_client.dart @@ -116,13 +116,13 @@ class SfuClient { sfu.SendAnswerRequest request, ) async { try { - _tracer.trace('SendAnswer', request.toJson()); + _tracer.trace('sendAnswer', request.toJson()); return _executeWithRetry( call: () => _client.sendAnswer(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('SendAnswer.failure', e.toString()); + _tracer.trace('sendAnswer.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -131,13 +131,13 @@ class SfuClient { sfu_models.ICETrickle request, ) async { try { - _tracer.trace('IceTrickle', request.toJson()); + _tracer.trace('iceTrickle', request.toJson()); return _executeWithRetry( call: () => _client.iceTrickle(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('IceTrickle.failure', e.toString()); + _tracer.trace('iceTrickle.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -146,13 +146,13 @@ class SfuClient { sfu.ICERestartRequest request, ) async { try { - _tracer.trace('RestartIce', request.toJson()); + _tracer.trace('iceRestart', request.toJson()); return _executeWithRetry( call: () => _client.iceRestart(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('RestartIce.failure', e.toString()); + _tracer.trace('iceRestart.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -161,7 +161,7 @@ class SfuClient { sfu.SetPublisherRequest request, ) async { try { - _tracer.trace('SetPublisher', request.toJson()); + _tracer.trace('setPublisher', request.toJson()); _logger.v(() => '[setPublisher] request: ${request.stringify()}'); final result = await _executeWithRetry( @@ -177,7 +177,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('SetPublisher.failure', e.toString()); + _tracer.trace('setPublisher.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -186,7 +186,7 @@ class SfuClient { sfu.UpdateMuteStatesRequest request, ) async { try { - _tracer.trace('UpdateMuteState', request.toJson()); + _tracer.trace('updateMuteStates', request.toJson()); _logger.v(() => '[updateMuteState] request: $request'); final result = await _executeWithRetry( @@ -202,7 +202,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('UpdateMuteState.failure', e.toString()); + _tracer.trace('updateMuteStates.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -211,7 +211,7 @@ class SfuClient { sfu.UpdateSubscriptionsRequest request, ) async { try { - _tracer.trace('UpdateSubscriptions', request.toJson()); + _tracer.trace('updateSubscriptions', request.toJson()); _logger.v(() => '[updateSubscriptions] request: $request'); final result = await _executeWithRetry( @@ -227,7 +227,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('UpdateSubscriptions.failure', e.toString()); + _tracer.trace('updateSubscriptions.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -236,7 +236,7 @@ class SfuClient { sfu.StartNoiseCancellationRequest request, ) async { try { - _tracer.trace('StartNoiseCancellation', request.toJson()); + _tracer.trace('startNoiseCancellation', request.toJson()); _logger.v(() => '[startNoiseCancellation] request: $request'); final result = @@ -254,7 +254,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('StartNoiseCancellation.failure', e.toString()); + _tracer.trace('startNoiseCancellation.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -263,7 +263,7 @@ class SfuClient { sfu.StopNoiseCancellationRequest request, ) async { try { - _tracer.trace('StopNoiseCancellation', request.toJson()); + _tracer.trace('stopNoiseCancellation', request.toJson()); _logger.v(() => '[stopNoiseCancellation] request: $request'); final result = await _executeWithRetry( @@ -279,7 +279,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('StopNoiseCancellation.failure', e.toString()); + _tracer.trace('stopNoiseCancellation.failure', e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } diff --git a/packages/stream_video/lib/src/sfu/sfu_extensions.dart b/packages/stream_video/lib/src/sfu/sfu_extensions.dart index 95bdc564a..a9fca32c6 100644 --- a/packages/stream_video/lib/src/sfu/sfu_extensions.dart +++ b/packages/stream_video/lib/src/sfu/sfu_extensions.dart @@ -17,6 +17,7 @@ import 'data/events/sfu_events.dart'; import 'data/models/sfu_audio_bitrate.dart'; import 'data/models/sfu_connection_info.dart'; import 'data/models/sfu_connection_quality.dart'; +import 'data/models/sfu_inbound_video_state.dart'; import 'data/models/sfu_model_mapper_extensions.dart'; import 'data/models/sfu_participant.dart'; @@ -486,6 +487,28 @@ extension SfuTrackUnpublishedEventJsonX on SfuTrackUnpublishedEvent { } } +extension SfuInboundStateNotificationEventJsonX + on SfuInboundStateNotificationEvent { + Map toJson() { + return { + 'inboundVideoStates': inboundVideoStates + .map((state) => state.toJson()) + .toList(), + }; + } +} + +extension SfuInboundVideoStateJsonX on SfuInboundVideoState { + Map toJson() { + return { + 'userId': userId, + 'sessionId': sessionId, + 'trackType': trackType.toDTO().value, + 'paused': paused, + }; + } +} + extension PublishOptionX on sfu_models.PublishOption { Map toJson() { return { diff --git a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart index 4e18b9acb..0a0d5a723 100644 --- a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart +++ b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart @@ -52,32 +52,35 @@ class TracedStreamPeerConnection extends StreamPeerConnection { pc ..onRenegotiationNeeded = () { - tracer.trace('renegotiationNeeded', null); + tracer.trace('negotiationneeded', null); originalNegotiationNeeded?.call(); } ..onIceConnectionState = (state) { - tracer.trace('iceConnectionStateChange', state.name); + tracer.trace('iceconnectionstatechange', state.name); originalIceConnectionState?.call(state); } ..onIceCandidate = (candidate) { - tracer.trace('iceCandidate', candidate.toMap()); + tracer.trace('onicecandidate', candidate.toMap()); originalIceCandidate?.call(candidate); } ..onTrack = (event) { final streams = event.streams.map((stream) => 'stream:${stream.id}'); - tracer.trace('track', '${event.track.kind}:${event.track.id} $streams'); + tracer.trace( + 'ontrack', + '${event.track.kind}:${event.track.id} $streams', + ); originalOnTrack?.call(event); } ..onIceGatheringState = (state) { - tracer.trace('iceGatheringStateChange', state.name); + tracer.trace('icegatheringstatechange', state.name); originalIceGatheringState?.call(state); } ..onSignalingState = (state) { - tracer.trace('signalingStateChange', state.name); + tracer.trace('signalingstatechange', state.name); originalSignalingState?.call(state); } ..onConnectionState = (state) { - tracer.trace('connectionStateChange', state.name); + tracer.trace('connectionstatechange', state.name); if (state == rtc.RTCPeerConnectionState.RTCPeerConnectionStateConnected || @@ -90,7 +93,7 @@ class TracedStreamPeerConnection extends StreamPeerConnection { originalConnectionState?.call(state); } ..onDataChannel = (channel) { - tracer.trace('onDataChannel', [channel.id, channel.label]); + tracer.trace('datachannel', [channel.id, channel.label]); originalDataChannel?.call(channel); }; } @@ -390,7 +393,7 @@ class TracedStreamPeerConnection extends StreamPeerConnection { if (result.isSuccess) { tracer.trace('createOffer.success', result.getDataOrNull()?.toMap()); } else { - tracer.trace('createOffer.error', result.getErrorOrNull()?.toString()); + tracer.trace('createOffer.failure', result.getErrorOrNull()?.toString()); } return result; @@ -408,7 +411,7 @@ class TracedStreamPeerConnection extends StreamPeerConnection { if (result.isSuccess) { tracer.trace('createAnswer.success', result.getDataOrNull()?.toMap()); } else { - tracer.trace('createAnswer.error', result.getErrorOrNull()?.toString()); + tracer.trace('createAnswer.failure', result.getErrorOrNull()?.toString()); } return result; From e0731d7ed592ab18259657b3b5c22b8cb02cc636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Braz=CC=87ewicz?= Date: Fri, 10 Jul 2026 12:41:40 +0200 Subject: [PATCH 2/3] extract trace keys --- packages/stream_video/lib/src/call/call.dart | 29 ++--- .../lib/src/call/session/call_session.dart | 37 +++--- .../src/call/stats/sfu_stats_reporter.dart | 5 +- .../lib/src/call/stats/trace_tag.dart | 112 ++++++++++++++++++ .../stream_video/lib/src/sfu/sfu_client.dart | 33 +++--- .../src/webrtc/media/media_constraints.dart | 5 +- .../src/webrtc/peer_connection_factory.dart | 3 +- .../rtc_media_device_notifier.dart | 11 +- .../src/webrtc/traced_peer_connection.dart | 58 +++++---- 9 files changed, 211 insertions(+), 82 deletions(-) create mode 100644 packages/stream_video/lib/src/call/stats/trace_tag.dart diff --git a/packages/stream_video/lib/src/call/call.dart b/packages/stream_video/lib/src/call/call.dart index 40831fe96..3caf91870 100644 --- a/packages/stream_video/lib/src/call/call.dart +++ b/packages/stream_video/lib/src/call/call.dart @@ -68,6 +68,7 @@ import 'session/dynascale_manager.dart'; import 'state/call_state_notifier.dart'; import 'stats/sfu_stats_reporter.dart'; import 'stats/stats_reporter.dart'; +import 'stats/trace_tag.dart'; typedef OnCallPermissionRequest = void Function( @@ -900,7 +901,7 @@ class Call { } } - _session?.trace('call.accept', null); + _session?.trace(TraceTag.callAccept, null); // Optimistically mark the call as accepted _stateManager.lifecycleCallAccepted(); @@ -919,7 +920,7 @@ class Call { final state = this.state.value; _logger.i(() => '[reject] reason: $reason'); - _session?.trace('call.reject', reason?.value); + _session?.trace(TraceTag.callReject, reason?.value); final result = await _coordinatorClient.rejectCall( cid: state.callCid, reason: reason?.value, @@ -1135,7 +1136,7 @@ class Call { '[join] $sfuMigrateReason for SFU: $sfuName, migrating...', ); - _session?.trace('callJoin.migrate', { + _session?.trace(TraceTag.callJoinMigrate, { 'migrateFrom': sfuName, 'reason': sfuMigrateReason, }); @@ -1306,7 +1307,7 @@ class Call { _suspendedTrackStates[trackId] = SuspendedTrackState.neverStarted; }, onReconnectionNeeded: (pc, strategy) { - _session?.trace('pc.reconnectionNeeded', { + _session?.trace(TraceTag.pcReconnectionNeeded, { 'peerConnectionId': pc.type.name, 'reconnectionStrategy': strategy.name, }); @@ -1823,7 +1824,7 @@ class Call { )) { _logger.w(() => '[onSfuEvent] socket disconnected'); - _session?.trace('sfuSocket.disconnected', { + _session?.trace(TraceTag.sfuSocketDisconnected, { 'closeCode': sfuEvent.reason.closeCode, 'closeReason': sfuEvent.reason.closeReason, }); @@ -1840,7 +1841,7 @@ class Call { } } else if (sfuEvent is SfuSocketFailed) { _logger.w(() => '[onSfuEvent] socket failed'); - _session?.trace('sfuSocket.failed', { + _session?.trace(TraceTag.sfuSocketFailed, { 'error': sfuEvent.error.message, }); await _reconnect( @@ -1849,7 +1850,7 @@ class Call { ); } else if (sfuEvent is SfuGoAwayEvent) { _logger.w(() => '[onSfuEvent] go away, migrating sfu'); - _session?.trace('sfuSocket.goAway', { + _session?.trace(TraceTag.sfuSocketGoAway, { 'reason': sfuEvent.goAwayReason.name, }); await _reconnect( @@ -1859,7 +1860,7 @@ class Call { } // error event else if (sfuEvent is SfuErrorEvent) { - _session?.trace('sfuSocket.error', { + _session?.trace(TraceTag.sfuSocketError, { 'code': sfuEvent.error.code.name, 'error': sfuEvent.error.message, 'strategy': sfuEvent.error.reconnectStrategy.name, @@ -1961,7 +1962,7 @@ class Call { return; } - _session?.trace('callReconnect', { + _session?.trace(TraceTag.callReconnect, { 'strategy': strategy.name, 'reason': reconnectReason, }); @@ -1982,7 +1983,7 @@ class Call { if (networkStatus == InternetStatus.disconnected) { _logger.w(() => '[reconnect] reconnection timeout'); - _session?.trace('callReconnectFailed', { + _session?.trace(TraceTag.callReconnectFailed, { 'strategy': strategy.name, 'error': 'reconnection timeout', }); @@ -1994,7 +1995,7 @@ class Call { _logger.w( () => '[reconnect] rejected (call was left during network wait)', ); - _session?.trace('callReconnectFailed', { + _session?.trace(TraceTag.callReconnectFailed, { 'strategy': strategy.name, 'error': 'call was left', }); @@ -2031,7 +2032,7 @@ class Call { }; if (reconnectResult.isSuccess) { - _session?.trace('callReconnectSuccess', { + _session?.trace(TraceTag.callReconnectSuccess, { 'strategy': strategy.name, }); } else { @@ -2077,7 +2078,7 @@ class Call { _logger.w(() => '[reconnect] unrecoverable error'); _stateManager.lifecycleCallReconnectingFailed(); - _session?.trace('callReconnectFailed', { + _session?.trace(TraceTag.callReconnectFailed, { 'strategy': strategy.name, 'error': error.toString(), }); @@ -2235,7 +2236,7 @@ class Call { '[_awaitNetworkAvailable] network dropped during ' '${stabilityWindow.inSeconds}s stability window, retrying', ); - _session?.trace('awaitNetwork.unstable', { + _session?.trace(TraceTag.awaitNetworkUnstable, { 'stabilityWindowSeconds': stabilityWindow.inSeconds, }); } on TimeoutException { diff --git a/packages/stream_video/lib/src/call/session/call_session.dart b/packages/stream_video/lib/src/call/session/call_session.dart index 278465548..d9a638071 100644 --- a/packages/stream_video/lib/src/call/session/call_session.dart +++ b/packages/stream_video/lib/src/call/session/call_session.dart @@ -37,6 +37,7 @@ import '../../webrtc/sdp/editor/sdp_editor.dart'; import '../../ws/ws.dart'; import '../state/call_state_notifier.dart'; import '../stats/stats_reporter.dart'; +import '../stats/trace_tag.dart'; import '../stats/tracer.dart'; import 'call_session_config.dart'; @@ -158,7 +159,7 @@ class CallSession extends Disposable { void _observeNetworkStatus() { _networkStatusSubscription = networkMonitor.onStatusChange.listen((status) { - _tracer.trace('network.changed', status.name); + _tracer.trace(TraceTag.networkChanged, status.name); }); } @@ -301,7 +302,7 @@ class CallSession extends Disposable { unifiedSessionId: unifiedSessionId, ); - _tracer.trace('joinRequest', joinRequest.toJson()); + _tracer.trace(TraceTag.joinRequest, joinRequest.toJson()); sfuWS.send( sfu_events.SfuRequest( @@ -430,7 +431,7 @@ class CallSession extends Disposable { details: wsJoinDetails, retryCount: clientEventRetryCount, ); - _tracer.trace('joinRequestTimeout', message); + _tracer.trace(TraceTag.joinRequestTimeout, message); _logger.e(() => '[start] failed: $e'); return Result.failure(VideoErrors.compose(e, stk)); } catch (e, stk) { @@ -473,7 +474,7 @@ class CallSession extends Disposable { try { _logger.d(() => '[fastReconnect] no args'); - _tracer.trace('fastReconnect', reconnectDetails.toJson()); + _tracer.trace(TraceTag.fastReconnect, reconnectDetails.toJson()); final genericSdpFactory = await rtcManagerFactory.pcFactory .ensureNativeFactory(); @@ -561,10 +562,10 @@ class CallSession extends Disposable { } if (result.isSuccess) { - _tracer.trace('fastReconnect.success', null); + _tracer.trace(TraceTag.fastReconnectSuccess, null); } else { _tracer.trace( - 'fastReconnect.failure', + TraceTag.fastReconnectFailure, result.getErrorOrNull()?.toString(), ); } @@ -572,7 +573,7 @@ class CallSession extends Disposable { return result; } catch (e, stk) { _logger.e(() => '[fastReconnect] failed: $e'); - _tracer.trace('fastReconnect.failure', e.toString()); + _tracer.trace(TraceTag.fastReconnectFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } finally { rtcManager?.subscriber.setReconnecting(false); @@ -605,7 +606,7 @@ class CallSession extends Disposable { 'state after ${_publisherConnectionCheckDelay.inSeconds}s ' '— triggering reconnection', ); - _tracer.trace('publisherConnectionCheck.stalled', { + _tracer.trace(TraceTag.publisherConnectionCheckStalled, { 'iceState': iceState.toString(), 'timeoutSeconds': _publisherConnectionCheckDelay.inSeconds, }); @@ -624,7 +625,7 @@ class CallSession extends Disposable { void leave({String? reason}) { _logger.d(() => '[leave] reason: $reason'); _isLeavingOrClosed = true; - _tracer.trace('call.leave', reason); + _tracer.trace(TraceTag.callLeave, reason); sfuWS.leave(sessionId: sessionId, reason: reason); } @@ -716,25 +717,25 @@ class CallSession extends Disposable { } else if (event is SfuParticipantLeftEvent) { await _onParticipantLeft(event); } else if (event is SfuTrackPublishedEvent) { - _tracer.trace('trackPublished', event.toJson()); + _tracer.trace(TraceTag.trackPublished, event.toJson()); await _onTrackPublished(event); } else if (event is SfuTrackUnpublishedEvent) { - _tracer.trace('trackUnpublished', event.toJson()); + _tracer.trace(TraceTag.trackUnpublished, event.toJson()); await _onTrackUnpublished(event); } else if (event is SfuChangePublishQualityEvent) { - _tracer.trace('changePublishQuality', event.toJson()); + _tracer.trace(TraceTag.changePublishQuality, event.toJson()); await _onPublishQualityChanged(event); } else if (event is SfuChangePublishOptionsEvent) { - _tracer.trace('changePublishOptions', event.toJson()); + _tracer.trace(TraceTag.changePublishOptions, event.toJson()); await _onPublishOptionsChanged(event); } else if (event is SfuIceRestartEvent) { await _onIceRestart(event); } else if (event is SfuGoAwayEvent) { - _tracer.trace('goAway', event.toJson()); + _tracer.trace(TraceTag.goAway, event.toJson()); } else if (event is SfuErrorEvent) { - _tracer.trace('error', event.toJson()); + _tracer.trace(TraceTag.error, event.toJson()); } else if (event is SfuCallEndedEvent) { - _tracer.trace('callEnded', event.toJson()); + _tracer.trace(TraceTag.callEnded, event.toJson()); } if (event is SfuJoinResponseEvent) { @@ -746,7 +747,7 @@ class CallSession extends Disposable { } else if (event is SfuParticipantLeftEvent) { stateManager.sfuParticipantLeft(event); } else if (event is SfuConnectionQualityChangedEvent) { - _tracer.trace('connectionQualityChanged', event.toJson()); + _tracer.trace(TraceTag.connectionQualityChanged, event.toJson()); stateManager.sfuConnectionQualityChanged(event); } else if (event is SfuAudioLevelChangedEvent) { stateManager.sfuUpdateAudioLevelChanged(event); @@ -759,7 +760,7 @@ class CallSession extends Disposable { } else if (event is SfuPinsUpdatedEvent) { stateManager.sfuPinsUpdated(event.pins); } else if (event is SfuInboundStateNotificationEvent) { - _tracer.trace('inboundVideoState', event.toJson()); + _tracer.trace(TraceTag.inboundVideoState, event.toJson()); stateManager.sfuInboundStateNotification(event); } }); diff --git a/packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart b/packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart index d92705e23..79c042554 100644 --- a/packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart +++ b/packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart @@ -21,6 +21,7 @@ import '../../webrtc/rtc_media_device/rtc_media_device_notifier.dart'; import '../session/call_session.dart'; import '../state/call_state_notifier.dart'; import 'trace_record.dart'; +import 'trace_tag.dart'; import 'tracer.dart'; class SfuStatsReporter { @@ -38,7 +39,7 @@ class SfuStatsReporter { _thermalStatus = _ThermalMonitor.lastStatus; _thermalStatusSubscription = sharedStream.listen((ThermalStatus status) { _thermalStatus = status; - _deviceTracer.trace('device.thermalState', status.name); + _deviceTracer.trace(TraceTag.deviceThermalState, status.name); }); } @@ -147,7 +148,7 @@ class SfuStatsReporter { try { lowPowerMode = await Battery().isInBatterySaveMode; if (lowPowerMode != _lastLowPowerMode) { - _deviceTracer.trace('device.lowPowerMode', lowPowerMode); + _deviceTracer.trace(TraceTag.deviceLowPowerMode, lowPowerMode); _lastLowPowerMode = lowPowerMode; } } on PlatformException { diff --git a/packages/stream_video/lib/src/call/stats/trace_tag.dart b/packages/stream_video/lib/src/call/stats/trace_tag.dart new file mode 100644 index 000000000..64b266ffb --- /dev/null +++ b/packages/stream_video/lib/src/call/stats/trace_tag.dart @@ -0,0 +1,112 @@ +/// Centralized keys used as the `tag` of `Tracer.trace` calls when reporting +/// SFU / WebRTC events. +abstract class TraceTag { + const TraceTag._(); + + // Call lifecycle + static const String callAccept = 'call.accept'; + static const String callReject = 'call.reject'; + static const String callJoinMigrate = 'callJoin.migrate'; + static const String pcReconnectionNeeded = 'pc.reconnectionNeeded'; + static const String sfuSocketDisconnected = 'sfuSocket.disconnected'; + static const String sfuSocketFailed = 'sfuSocket.failed'; + static const String sfuSocketGoAway = 'sfuSocket.goAway'; + static const String sfuSocketError = 'sfuSocket.error'; + static const String callReconnect = 'callReconnect'; + static const String callReconnectFailed = 'callReconnectFailed'; + static const String callReconnectSuccess = 'callReconnectSuccess'; + static const String awaitNetworkUnstable = 'awaitNetwork.unstable'; + + // Device stats + static const String deviceThermalState = 'device.thermalState'; + static const String deviceLowPowerMode = 'device.lowPowerMode'; + + // Call session + static const String networkChanged = 'network.changed'; + static const String joinRequest = 'joinRequest'; + static const String joinRequestTimeout = 'joinRequest.timeout'; + static const String fastReconnect = 'fastReconnect'; + static const String fastReconnectSuccess = 'fastReconnect.success'; + static const String fastReconnectFailure = 'fastReconnect.failure'; + static const String publisherConnectionCheckStalled = + 'publisherConnectionCheck.stalled'; + static const String callLeave = 'call.leave'; + static const String trackPublished = 'trackPublished'; + static const String trackUnpublished = 'trackUnpublished'; + static const String changePublishQuality = 'changePublishQuality'; + static const String changePublishOptions = 'changePublishOptions'; + static const String goAway = 'goAway'; + static const String error = 'error'; + static const String callEnded = 'call.ended'; + static const String connectionQualityChanged = 'connectionQualityChanged'; + static const String inboundVideoState = 'inboundVideoState'; + + // SFU signaling RPCs + static const String sendAnswer = 'sendAnswer'; + static const String sendAnswerFailure = 'sendAnswer.failure'; + static const String iceTrickle = 'iceTrickle'; + static const String iceTrickleFailure = 'iceTrickle.failure'; + static const String iceRestart = 'iceRestart'; + static const String iceRestartFailure = 'iceRestart.failure'; + static const String setPublisher = 'setPublisher'; + static const String setPublisherFailure = 'setPublisher.failure'; + static const String updateMuteStates = 'updateMuteStates'; + static const String updateMuteStatesFailure = 'updateMuteStates.failure'; + static const String updateSubscriptions = 'updateSubscriptions'; + static const String updateSubscriptionsFailure = + 'updateSubscriptions.failure'; + static const String startNoiseCancellation = 'startNoiseCancellation'; + static const String startNoiseCancellationFailure = + 'startNoiseCancellation.failure'; + static const String stopNoiseCancellation = 'stopNoiseCancellation'; + static const String stopNoiseCancellationFailure = + 'stopNoiseCancellation.failure'; + + // Peer connection events + static const String negotiationNeeded = 'negotiationneeded'; + static const String iceConnectionStateChange = 'iceconnectionstatechange'; + static const String onIceCandidate = 'onicecandidate'; + static const String onTrack = 'ontrack'; + static const String iceGatheringStateChange = 'icegatheringstatechange'; + static const String signalingStateChange = 'signalingstatechange'; + static const String connectionStateChange = 'connectionstatechange'; + static const String dataChannel = 'datachannel'; + static const String getStats = 'getstats'; + static const String createOffer = 'createOffer'; + static const String createOfferSuccess = 'createOffer.success'; + static const String createOfferFailure = 'createOffer.failure'; + static const String createAnswer = 'createAnswer'; + static const String createAnswerSuccess = 'createAnswer.success'; + static const String createAnswerFailure = 'createAnswer.failure'; + static const String setRemoteDescription = 'setRemoteDescription'; + static const String setRemoteDescriptionSuccess = + 'setRemoteDescription.success'; + static const String setRemoteDescriptionError = 'setRemoteDescription.error'; + static const String setLocalDescription = 'setLocalDescription'; + static const String setLocalDescriptionSuccess = + 'setLocalDescription.success'; + static const String setLocalDescriptionError = 'setLocalDescription.error'; + static const String addIceCandidate = 'addIceCandidate'; + static const String addIceCandidateSuccess = 'addIceCandidate.success'; + static const String addIceCandidateError = 'addIceCandidate.error'; + + // Peer connection factory + static const String create = 'create'; + + // Media devices + static const String audioProcessingStateChanged = + 'audioProcessingStateChanged'; + static const String enumerateDevices = + 'navigator.mediaDevices.enumeratedevices'; + static const String pauseAudioPlayout = + 'navigator.mediaDevices.pauseAudioPlayout'; + static const String resumeAudioPlayout = + 'navigator.mediaDevices.resumeAudioPlayout'; + static const String regainAndroidAudioFocus = + 'navigator.mediaDevices.regainAndroidAudioFocus'; + + // Media constraints + static const String getDisplayMedia = + 'navigator.mediaDevices.getDisplayMedia'; + static const String getUserMedia = 'navigator.mediaDevices.getUserMedia'; +} diff --git a/packages/stream_video/lib/src/sfu/sfu_client.dart b/packages/stream_video/lib/src/sfu/sfu_client.dart index 15bd520fd..91d93c4bd 100644 --- a/packages/stream_video/lib/src/sfu/sfu_client.dart +++ b/packages/stream_video/lib/src/sfu/sfu_client.dart @@ -12,6 +12,7 @@ import '../../protobuf/video/sfu/models/models.pb.dart' as sfu_models; import '../../protobuf/video/sfu/signal_rpc/signal.pb.dart' as sfu; import '../../protobuf/video/sfu/signal_rpc/signal.pbtwirp.dart' as signal_twirp; +import '../call/stats/trace_tag.dart'; import '../call/stats/tracer.dart'; import '../errors/video_error_composer.dart'; import '../logger/impl/tagged_logger.dart'; @@ -116,13 +117,13 @@ class SfuClient { sfu.SendAnswerRequest request, ) async { try { - _tracer.trace('sendAnswer', request.toJson()); + _tracer.trace(TraceTag.sendAnswer, request.toJson()); return _executeWithRetry( call: () => _client.sendAnswer(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('sendAnswer.failure', e.toString()); + _tracer.trace(TraceTag.sendAnswerFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -131,13 +132,13 @@ class SfuClient { sfu_models.ICETrickle request, ) async { try { - _tracer.trace('iceTrickle', request.toJson()); + _tracer.trace(TraceTag.iceTrickle, request.toJson()); return _executeWithRetry( call: () => _client.iceTrickle(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('iceTrickle.failure', e.toString()); + _tracer.trace(TraceTag.iceTrickleFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -146,13 +147,13 @@ class SfuClient { sfu.ICERestartRequest request, ) async { try { - _tracer.trace('iceRestart', request.toJson()); + _tracer.trace(TraceTag.iceRestart, request.toJson()); return _executeWithRetry( call: () => _client.iceRestart(_withAuthHeaders(), request), ); } catch (e, stk) { - _tracer.trace('iceRestart.failure', e.toString()); + _tracer.trace(TraceTag.iceRestartFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -161,7 +162,7 @@ class SfuClient { sfu.SetPublisherRequest request, ) async { try { - _tracer.trace('setPublisher', request.toJson()); + _tracer.trace(TraceTag.setPublisher, request.toJson()); _logger.v(() => '[setPublisher] request: ${request.stringify()}'); final result = await _executeWithRetry( @@ -177,7 +178,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('setPublisher.failure', e.toString()); + _tracer.trace(TraceTag.setPublisherFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -186,7 +187,7 @@ class SfuClient { sfu.UpdateMuteStatesRequest request, ) async { try { - _tracer.trace('updateMuteStates', request.toJson()); + _tracer.trace(TraceTag.updateMuteStates, request.toJson()); _logger.v(() => '[updateMuteState] request: $request'); final result = await _executeWithRetry( @@ -202,7 +203,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('updateMuteStates.failure', e.toString()); + _tracer.trace(TraceTag.updateMuteStatesFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -211,7 +212,7 @@ class SfuClient { sfu.UpdateSubscriptionsRequest request, ) async { try { - _tracer.trace('updateSubscriptions', request.toJson()); + _tracer.trace(TraceTag.updateSubscriptions, request.toJson()); _logger.v(() => '[updateSubscriptions] request: $request'); final result = await _executeWithRetry( @@ -227,7 +228,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('updateSubscriptions.failure', e.toString()); + _tracer.trace(TraceTag.updateSubscriptionsFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -236,7 +237,7 @@ class SfuClient { sfu.StartNoiseCancellationRequest request, ) async { try { - _tracer.trace('startNoiseCancellation', request.toJson()); + _tracer.trace(TraceTag.startNoiseCancellation, request.toJson()); _logger.v(() => '[startNoiseCancellation] request: $request'); final result = @@ -254,7 +255,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('startNoiseCancellation.failure', e.toString()); + _tracer.trace(TraceTag.startNoiseCancellationFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } @@ -263,7 +264,7 @@ class SfuClient { sfu.StopNoiseCancellationRequest request, ) async { try { - _tracer.trace('stopNoiseCancellation', request.toJson()); + _tracer.trace(TraceTag.stopNoiseCancellation, request.toJson()); _logger.v(() => '[stopNoiseCancellation] request: $request'); final result = await _executeWithRetry( @@ -279,7 +280,7 @@ class SfuClient { return result; } catch (e, stk) { - _tracer.trace('stopNoiseCancellation.failure', e.toString()); + _tracer.trace(TraceTag.stopNoiseCancellationFailure, e.toString()); return Result.failure(VideoErrors.compose(e, stk)); } } diff --git a/packages/stream_video/lib/src/webrtc/media/media_constraints.dart b/packages/stream_video/lib/src/webrtc/media/media_constraints.dart index 16973bdcb..c7c3dad8f 100644 --- a/packages/stream_video/lib/src/webrtc/media/media_constraints.dart +++ b/packages/stream_video/lib/src/webrtc/media/media_constraints.dart @@ -1,6 +1,7 @@ import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import 'package:webrtc_interface/webrtc_interface.dart' as rtc_interface; +import '../../call/stats/trace_tag.dart'; import '../../call/stats/tracer.dart'; import '../../logger/stream_log.dart'; import 'screen_share_constraints.dart'; @@ -57,14 +58,14 @@ extension MediaDevices on rtc_interface.MediaDevices { try { if (constraints is ScreenShareConstraints) { - tag = 'navigator.mediaDevices.getDisplayMedia'; + tag = TraceTag.getDisplayMedia; tracer?.trace('$tag.$sequence', constraintsMap); stream = nativeFactory != null ? await nativeFactory.getDisplayMedia(constraintsMap) : await rtc.navigator.mediaDevices.getDisplayMedia(constraintsMap); } else { - tag = 'navigator.mediaDevices.getUserMedia'; + tag = TraceTag.getUserMedia; tracer?.trace('$tag.$sequence', constraintsMap); stream = nativeFactory != null diff --git a/packages/stream_video/lib/src/webrtc/peer_connection_factory.dart b/packages/stream_video/lib/src/webrtc/peer_connection_factory.dart index ae7841adf..a10865f05 100644 --- a/packages/stream_video/lib/src/webrtc/peer_connection_factory.dart +++ b/packages/stream_video/lib/src/webrtc/peer_connection_factory.dart @@ -3,6 +3,7 @@ import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import '../../open_api/video/coordinator/api.dart'; import '../../protobuf/video/sfu/models/models.pb.dart'; import '../call/session/call_session_config.dart'; +import '../call/stats/trace_tag.dart'; import '../call/stats/tracer.dart'; import '../logger/impl/tagged_logger.dart'; import '../models/audio_configuration_policy.dart'; @@ -208,7 +209,7 @@ class StreamPeerConnectionFactory { tracer.setEnabled(statsOptions?.enableRtcStats ?? false); tracer.trace( - 'create', + TraceTag.create, configuration.toMap()..addAll( { 'url': callSessionConfig?.sfuName, diff --git a/packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart b/packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart index e7ad42e39..ea328797b 100644 --- a/packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart +++ b/packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart @@ -7,6 +7,7 @@ import 'package:rxdart/rxdart.dart'; import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import '../../../stream_video.dart'; +import '../../call/stats/trace_tag.dart'; import '../../call/stats/tracer.dart'; import '../../errors/video_error_composer.dart'; import '../../utils/extensions.dart'; @@ -157,7 +158,7 @@ class RtcMediaDeviceNotifier { values['voiceProcessingAGCEnabled'] as bool? ?? false; _tracer.trace( - 'audioProcessingStateChanged', + TraceTag.audioProcessingStateChanged, { 'stereoPlayoutEnabled': stereoPlayoutEnabled, 'voiceProcessingEnabled': voiceProcessingEnabled, @@ -223,7 +224,7 @@ class RtcMediaDeviceNotifier { ]; _tracer.trace( - 'navigator.mediaDevices.enumeratedevices', + TraceTag.enumerateDevices, mediaDevices.map((device) => device.toJson()).toList(), ); @@ -264,14 +265,14 @@ class RtcMediaDeviceNotifier { /// This does not affect the microphone or remote track subscriptions. /// Use as a global "mute all sounds" toggle or when the app goes to background. Future pauseAudioPlayout() { - _tracer.trace('navigator.mediaDevices.pauseAudioPlayout', null); + _tracer.trace(TraceTag.pauseAudioPlayout, null); return rtc.Helper.pauseAudioPlayout(); } /// Resumes audio output (playout) muted via [pauseAudioPlayout]. /// Does not change microphone state or remote track subscriptions. Future resumeAudioPlayout() { - _tracer.trace('navigator.mediaDevices.resumeAudioPlayout', null); + _tracer.trace(TraceTag.resumeAudioPlayout, null); return rtc.Helper.resumeAudioPlayout(); } @@ -281,7 +282,7 @@ class RtcMediaDeviceNotifier { /// To ensure you receive `onInterruptionEnd`, explicitly call /// [resumeAudioPlayout] (e.g., when the app resumes from background). Future regainAndroidAudioFocus() { - _tracer.trace('navigator.mediaDevices.regainAndroidAudioFocus', null); + _tracer.trace(TraceTag.regainAndroidAudioFocus, null); return rtc.Helper.regainAndroidAudioFocus(); } diff --git a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart index 0a0d5a723..cfac94fda 100644 --- a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart +++ b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart @@ -4,6 +4,7 @@ import 'package:collection/collection.dart'; import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc; import '../../protobuf/video/sfu/models/models.pb.dart'; +import '../call/stats/trace_tag.dart'; import '../call/stats/tracer.dart'; import '../sfu/data/models/sfu_codec.dart'; import '../sfu/data/models/sfu_model_mapper_extensions.dart'; @@ -52,35 +53,35 @@ class TracedStreamPeerConnection extends StreamPeerConnection { pc ..onRenegotiationNeeded = () { - tracer.trace('negotiationneeded', null); + tracer.trace(TraceTag.negotiationNeeded, null); originalNegotiationNeeded?.call(); } ..onIceConnectionState = (state) { - tracer.trace('iceconnectionstatechange', state.name); + tracer.trace(TraceTag.iceConnectionStateChange, state.name); originalIceConnectionState?.call(state); } ..onIceCandidate = (candidate) { - tracer.trace('onicecandidate', candidate.toMap()); + tracer.trace(TraceTag.onIceCandidate, candidate.toMap()); originalIceCandidate?.call(candidate); } ..onTrack = (event) { final streams = event.streams.map((stream) => 'stream:${stream.id}'); tracer.trace( - 'ontrack', + TraceTag.onTrack, '${event.track.kind}:${event.track.id} $streams', ); originalOnTrack?.call(event); } ..onIceGatheringState = (state) { - tracer.trace('icegatheringstatechange', state.name); + tracer.trace(TraceTag.iceGatheringStateChange, state.name); originalIceGatheringState?.call(state); } ..onSignalingState = (state) { - tracer.trace('signalingstatechange', state.name); + tracer.trace(TraceTag.signalingStateChange, state.name); originalSignalingState?.call(state); } ..onConnectionState = (state) { - tracer.trace('connectionstatechange', state.name); + tracer.trace(TraceTag.connectionStateChange, state.name); if (state == rtc.RTCPeerConnectionState.RTCPeerConnectionStateConnected || @@ -93,7 +94,7 @@ class TracedStreamPeerConnection extends StreamPeerConnection { originalConnectionState?.call(state); } ..onDataChannel = (channel) { - tracer.trace('datachannel', [channel.id, channel.label]); + tracer.trace(TraceTag.dataChannel, [channel.id, channel.label]); originalDataChannel?.call(channel); }; } @@ -316,7 +317,7 @@ class TracedStreamPeerConnection extends StreamPeerConnection { List> newRtcStats, ) async { final statsDiff = _diffCompression(newRtcStats, _previousStats); - tracer.trace('getstats', statsDiff); + tracer.trace(TraceTag.getStats, statsDiff); _previousStats = newRtcStats; } @@ -386,14 +387,17 @@ class TracedStreamPeerConnection extends StreamPeerConnection { Future> createOffer([ Map mediaConstraints = const {}, ]) async { - tracer.trace('createOffer', mediaConstraints); + tracer.trace(TraceTag.createOffer, mediaConstraints); final result = await super.createOffer(mediaConstraints); if (result.isSuccess) { - tracer.trace('createOffer.success', result.getDataOrNull()?.toMap()); + tracer.trace(TraceTag.createOfferSuccess, result.getDataOrNull()?.toMap()); } else { - tracer.trace('createOffer.failure', result.getErrorOrNull()?.toString()); + tracer.trace( + TraceTag.createOfferFailure, + result.getErrorOrNull()?.toString(), + ); } return result; @@ -404,14 +408,20 @@ class TracedStreamPeerConnection extends StreamPeerConnection { String offerSdp, [ Map mediaConstraints = const {}, ]) async { - tracer.trace('createAnswer', mediaConstraints); + tracer.trace(TraceTag.createAnswer, mediaConstraints); final result = await super.createAnswer(offerSdp, mediaConstraints); if (result.isSuccess) { - tracer.trace('createAnswer.success', result.getDataOrNull()?.toMap()); + tracer.trace( + TraceTag.createAnswerSuccess, + result.getDataOrNull()?.toMap(), + ); } else { - tracer.trace('createAnswer.failure', result.getErrorOrNull()?.toString()); + tracer.trace( + TraceTag.createAnswerFailure, + result.getErrorOrNull()?.toString(), + ); } return result; @@ -421,15 +431,15 @@ class TracedStreamPeerConnection extends StreamPeerConnection { Future> setRemoteDescription( rtc.RTCSessionDescription sd, ) async { - tracer.trace('setRemoteDescription', sd.toMap()); + tracer.trace(TraceTag.setRemoteDescription, sd.toMap()); final result = await super.setRemoteDescription(sd); if (result.isSuccess) { - tracer.trace('setRemoteDescription.success', null); + tracer.trace(TraceTag.setRemoteDescriptionSuccess, null); } else { tracer.trace( - 'setRemoteDescription.error', + TraceTag.setRemoteDescriptionError, result.getErrorOrNull()?.toString(), ); } @@ -441,15 +451,15 @@ class TracedStreamPeerConnection extends StreamPeerConnection { Future> setLocalDescription( rtc.RTCSessionDescription description, ) async { - tracer.trace('setLocalDescription', description.toMap()); + tracer.trace(TraceTag.setLocalDescription, description.toMap()); final result = await super.setLocalDescription(description); if (result.isSuccess) { - tracer.trace('setLocalDescription.success', null); + tracer.trace(TraceTag.setLocalDescriptionSuccess, null); } else { tracer.trace( - 'setLocalDescription.error', + TraceTag.setLocalDescriptionError, result.getErrorOrNull()?.toString(), ); } @@ -459,15 +469,15 @@ class TracedStreamPeerConnection extends StreamPeerConnection { @override Future> addIceCandidate(rtc.RTCIceCandidate candidate) async { - tracer.trace('addIceCandidate', candidate.toMap()); + tracer.trace(TraceTag.addIceCandidate, candidate.toMap()); final result = await super.addIceCandidate(candidate); if (result.isSuccess) { - tracer.trace('addIceCandidate.success', null); + tracer.trace(TraceTag.addIceCandidateSuccess, null); } else { tracer.trace( - 'addIceCandidate.error', + TraceTag.addIceCandidateError, result.getErrorOrNull()?.toString(), ); } From 5c3b08565416f0439bb646454829b629e662c576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Braz=CC=87ewicz?= Date: Fri, 10 Jul 2026 14:13:07 +0200 Subject: [PATCH 3/3] format fix --- .../stream_video/lib/src/webrtc/traced_peer_connection.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart index cfac94fda..2e8c3117b 100644 --- a/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart +++ b/packages/stream_video/lib/src/webrtc/traced_peer_connection.dart @@ -392,7 +392,10 @@ class TracedStreamPeerConnection extends StreamPeerConnection { final result = await super.createOffer(mediaConstraints); if (result.isSuccess) { - tracer.trace(TraceTag.createOfferSuccess, result.getDataOrNull()?.toMap()); + tracer.trace( + TraceTag.createOfferSuccess, + result.getDataOrNull()?.toMap(), + ); } else { tracer.trace( TraceTag.createOfferFailure,