From aae617976992825748123381ca70a1c2c47755fc Mon Sep 17 00:00:00 2001 From: Volodymyr B Date: Tue, 6 May 2025 15:47:53 +0300 Subject: [PATCH 1/3] writing call stats to log --- lib/src/config.dart | 6 ++++ lib/src/rtc_session.dart | 70 +++++++++++++++++++++++++++++++++++++- lib/src/sip_ua_helper.dart | 4 +++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/lib/src/config.dart b/lib/src/config.dart index 0f901955..7dc05c9c 100644 --- a/lib/src/config.dart +++ b/lib/src/config.dart @@ -64,6 +64,9 @@ class Settings { /// ICE Gathering Timeout (in millisecond). int ice_gathering_timeout = 500; + /// Call statistics in the log + bool log_call_statistics = false; + bool terminateOnAudioMediaPortZero = false; /// Sip Message Delay (in millisecond) ( default 0 ). @@ -255,6 +258,9 @@ class Checks { }, 'ice_gathering_timeout': (Settings src, Settings? dst) { dst!.ice_gathering_timeout = src.ice_gathering_timeout; + }, + 'log_call_statistics': (Settings src, Settings? dst) { + dst!.log_call_statistics = src.log_call_statistics; } }; } diff --git a/lib/src/rtc_session.dart b/lib/src/rtc_session.dart index ac7c1cae..ddbc9697 100644 --- a/lib/src/rtc_session.dart +++ b/lib/src/rtc_session.dart @@ -726,7 +726,7 @@ class RTCSession extends EventManager implements Owner { /** * Terminate the call. */ - void terminate([Map? options]) { + void terminate([Map? options]) async { logger.d('terminate()'); options = options ?? {}; @@ -844,6 +844,9 @@ class RTCSession extends EventManager implements Owner { } }); + //write call statistics to the log + await _logCallStat(); + _ended( Originator.local, null, @@ -863,6 +866,10 @@ class RTCSession extends EventManager implements Owner { {'extraHeaders': extraHeaders, 'body': body}); reason_phrase = reason_phrase ?? 'Terminated by local'; status_code = status_code ?? 200; + + //write call statistics to the log + await _logCallStat(); + _ended( Originator.local, null, @@ -1359,6 +1366,10 @@ class RTCSession extends EventManager implements Owner { case SipMethod.BYE: if (_state == RtcSessionState.confirmed) { request.reply(200); + + //write call statistics to the log + await _logCallStat(); + _ended( Originator.remote, request, @@ -1369,6 +1380,10 @@ class RTCSession extends EventManager implements Owner { } else if (_state == RtcSessionState.inviteReceived) { request.reply(200); _request.reply(487, 'BYE Received'); + + //write call statistics to the log + await _logCallStat(); + _ended( Originator.remote, request, @@ -3441,4 +3456,57 @@ class RTCSession extends EventManager implements Owner { logger.d('emit "unmuted"'); emit(EventCallUnmuted(session: this, audio: audio, video: video)); } + + Future _logCallStat() async { + + if(!ua.configuration.log_call_statistics) return; + + try { + List? senders = await connection?.senders; + List? receivers = await connection?.receivers; + + RTCRtpReceiver? receiver = receivers?.firstOrNull; + RTCRtpSender? sender = senders?.firstOrNull; + + List senderStats = []; + List receiverStats = []; + + if(sender!=null) { + senderStats = await sender.getStats(); + } + + if(receiver != null) { + receiverStats = await receiver.getStats(); + } + + String senderStat = 'Sender stats: \n'; + + for(StatsReport s in senderStats) { + senderStat += '${s.timestamp} ${s.id} ${s.type}\n'; + senderStat += '----------------------------------------------------\n'; + s.values.forEach((key, value) { + senderStat += '$key: $value\n'; + }); + senderStat += '----------------------------------------------------\n'; + } + + logger.d(senderStat); + + String receiverStat = 'Receiver stats: \n'; + + for(StatsReport s in receiverStats) { + receiverStat += '${s.timestamp} ${s.id} ${s.type}\n'; + receiverStat += '----------------------------------------------------\n'; + s.values.forEach((key, value) { + receiverStat += '$key: $value\n'; + }); + receiverStat += '----------------------------------------------------\n'; + } + + logger.d(receiverStat); + + } catch (e) { + return; + } + } } diff --git a/lib/src/sip_ua_helper.dart b/lib/src/sip_ua_helper.dart index 288d5e60..556a26c6 100644 --- a/lib/src/sip_ua_helper.dart +++ b/lib/src/sip_ua_helper.dart @@ -194,6 +194,7 @@ class SIPUAHelper extends EventManager { uaSettings.connectionRecoveryMinInterval; _settings.terminateOnAudioMediaPortZero = uaSettings.terminateOnMediaPortZero; + _settings.log_call_statistics = uaSettings.logCallStatistics; try { _ua = UA(_settings); @@ -899,6 +900,9 @@ class UaSettings { /// Min interval between recovery connection, default 2 sec int connectionRecoveryMinInterval = 2; + /// Allows to write advanced call statistics in the log after the call ends + bool logCallStatistics = false; + bool terminateOnMediaPortZero = false; /// Sip Message Delay (in millisecond) (default 0). From 197adf9f898597cdd59e936cb76fbbbd26cefebc Mon Sep 17 00:00:00 2001 From: Volodymyr B Date: Wed, 7 May 2025 09:52:42 +0300 Subject: [PATCH 2/3] Update rtc_session.dart --- lib/src/rtc_session.dart | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/src/rtc_session.dart b/lib/src/rtc_session.dart index ddbc9697..49b72fcb 100644 --- a/lib/src/rtc_session.dart +++ b/lib/src/rtc_session.dart @@ -3482,12 +3482,11 @@ class RTCSession extends EventManager implements Owner { String senderStat = 'Sender stats: \n'; for(StatsReport s in senderStats) { - senderStat += '${s.timestamp} ${s.id} ${s.type}\n'; - senderStat += '----------------------------------------------------\n'; + senderStat += ' ${s.timestamp} ${s.id} ${s.type}:\n'; s.values.forEach((key, value) { - senderStat += '$key: $value\n'; + senderStat += ' $key: $value\n'; }); - senderStat += '----------------------------------------------------\n'; + senderStat += '\r'; } logger.d(senderStat); @@ -3495,12 +3494,11 @@ class RTCSession extends EventManager implements Owner { String receiverStat = 'Receiver stats: \n'; for(StatsReport s in receiverStats) { - receiverStat += '${s.timestamp} ${s.id} ${s.type}\n'; - receiverStat += '----------------------------------------------------\n'; + receiverStat += ' ${s.timestamp} ${s.id} ${s.type}\n'; s.values.forEach((key, value) { - receiverStat += '$key: $value\n'; + receiverStat += ' $key: $value\n'; }); - receiverStat += '----------------------------------------------------\n'; + receiverStat += '\r'; } logger.d(receiverStat); From f5dbdf64fd463b02c253934d08c0353aa6b4e3b5 Mon Sep 17 00:00:00 2001 From: Volodymyr B Date: Fri, 11 Jul 2025 07:54:38 +0300 Subject: [PATCH 3/3] fix code format --- lib/src/rtc_session.dart | 12 +++++------- lib/src/sip_ua_helper.dart | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/src/rtc_session.dart b/lib/src/rtc_session.dart index 49b72fcb..23f768e6 100644 --- a/lib/src/rtc_session.dart +++ b/lib/src/rtc_session.dart @@ -3458,8 +3458,7 @@ class RTCSession extends EventManager implements Owner { } Future _logCallStat() async { - - if(!ua.configuration.log_call_statistics) return; + if (!ua.configuration.log_call_statistics) return; try { List? senders = await connection?.senders; @@ -3471,17 +3470,17 @@ class RTCSession extends EventManager implements Owner { List senderStats = []; List receiverStats = []; - if(sender!=null) { + if (sender != null) { senderStats = await sender.getStats(); } - if(receiver != null) { + if (receiver != null) { receiverStats = await receiver.getStats(); } String senderStat = 'Sender stats: \n'; - for(StatsReport s in senderStats) { + for (StatsReport s in senderStats) { senderStat += ' ${s.timestamp} ${s.id} ${s.type}:\n'; s.values.forEach((key, value) { senderStat += ' $key: $value\n'; @@ -3493,7 +3492,7 @@ class RTCSession extends EventManager implements Owner { String receiverStat = 'Receiver stats: \n'; - for(StatsReport s in receiverStats) { + for (StatsReport s in receiverStats) { receiverStat += ' ${s.timestamp} ${s.id} ${s.type}\n'; s.values.forEach((key, value) { receiverStat += ' $key: $value\n'; @@ -3502,7 +3501,6 @@ class RTCSession extends EventManager implements Owner { } logger.d(receiverStat); - } catch (e) { return; } diff --git a/lib/src/sip_ua_helper.dart b/lib/src/sip_ua_helper.dart index 556a26c6..4fb2119a 100644 --- a/lib/src/sip_ua_helper.dart +++ b/lib/src/sip_ua_helper.dart @@ -194,7 +194,7 @@ class SIPUAHelper extends EventManager { uaSettings.connectionRecoveryMinInterval; _settings.terminateOnAudioMediaPortZero = uaSettings.terminateOnMediaPortZero; - _settings.log_call_statistics = uaSettings.logCallStatistics; + _settings.log_call_statistics = uaSettings.logCallStatistics; try { _ua = UA(_settings);