Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: webrtc/api/rtcstatscollector.cc

Issue 2408363002: RTCTransportStats added. (Closed)
Patch Set: nits and rebase with master Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/rtcstatscollector.h ('k') | webrtc/api/rtcstatscollector_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/api/rtcstatscollector.h" 11 #include "webrtc/api/rtcstatscollector.h"
12 12
13 #include <memory> 13 #include <memory>
14 #include <utility> 14 #include <utility>
15 #include <vector> 15 #include <vector>
16 16
17 #include "webrtc/api/peerconnection.h" 17 #include "webrtc/api/peerconnection.h"
18 #include "webrtc/api/webrtcsession.h" 18 #include "webrtc/api/webrtcsession.h"
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/base/sslidentity.h"
21 #include "webrtc/p2p/base/candidate.h" 20 #include "webrtc/p2p/base/candidate.h"
21 #include "webrtc/p2p/base/p2pconstants.h"
22 #include "webrtc/p2p/base/port.h" 22 #include "webrtc/p2p/base/port.h"
23 23
24 namespace webrtc { 24 namespace webrtc {
25 25
26 namespace { 26 namespace {
27 27
28 std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) {
29 return "RTCCertificate_" + fingerprint;
30 }
31
32 std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
33 const cricket::ConnectionInfo& info) {
34 return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" +
35 info.remote_candidate.id();
36 }
37
38 std::string RTCTransportStatsIDFromTransportChannel(
39 const std::string& transport_name, int channel_component) {
40 return "RTCTransport_" + transport_name + "_" +
41 rtc::ToString<>(channel_component);
42 }
43
28 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) { 44 const char* CandidateTypeToRTCIceCandidateType(const std::string& type) {
29 if (type == cricket::LOCAL_PORT_TYPE) 45 if (type == cricket::LOCAL_PORT_TYPE)
30 return RTCIceCandidateType::kHost; 46 return RTCIceCandidateType::kHost;
31 if (type == cricket::STUN_PORT_TYPE) 47 if (type == cricket::STUN_PORT_TYPE)
32 return RTCIceCandidateType::kSrflx; 48 return RTCIceCandidateType::kSrflx;
33 if (type == cricket::PRFLX_PORT_TYPE) 49 if (type == cricket::PRFLX_PORT_TYPE)
34 return RTCIceCandidateType::kPrflx; 50 return RTCIceCandidateType::kPrflx;
35 if (type == cricket::RELAY_PORT_TYPE) 51 if (type == cricket::RELAY_PORT_TYPE)
36 return RTCIceCandidateType::kRelay; 52 return RTCIceCandidateType::kRelay;
37 RTC_NOTREACHED(); 53 RTC_NOTREACHED();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 cached_report_ = nullptr; 137 cached_report_ = nullptr;
122 } 138 }
123 139
124 void RTCStatsCollector::ProducePartialResultsOnSignalingThread( 140 void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
125 int64_t timestamp_us) { 141 int64_t timestamp_us) {
126 RTC_DCHECK(signaling_thread_->IsCurrent()); 142 RTC_DCHECK(signaling_thread_->IsCurrent());
127 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(); 143 rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create();
128 144
129 SessionStats session_stats; 145 SessionStats session_stats;
130 if (pc_->session()->GetTransportStats(&session_stats)) { 146 if (pc_->session()->GetTransportStats(&session_stats)) {
131 ProduceCertificateStats_s(timestamp_us, session_stats, report.get()); 147 std::map<std::string, CertificateStatsPair> transport_cert_stats =
132 ProduceIceCandidateAndPairStats_s(timestamp_us, session_stats, 148 PrepareTransportCertificateStats_s(session_stats);
133 report.get()); 149
150 ProduceCertificateStats_s(
151 timestamp_us, transport_cert_stats, report.get());
152 ProduceIceCandidateAndPairStats_s(
153 timestamp_us, session_stats, report.get());
154 ProduceTransportStats_s(
155 timestamp_us, session_stats, transport_cert_stats, report.get());
134 } 156 }
135 ProduceDataChannelStats_s(timestamp_us, report.get()); 157 ProduceDataChannelStats_s(timestamp_us, report.get());
136 ProducePeerConnectionStats_s(timestamp_us, report.get()); 158 ProducePeerConnectionStats_s(timestamp_us, report.get());
137 159
138 AddPartialResults(report); 160 AddPartialResults(report);
139 } 161 }
140 162
141 void RTCStatsCollector::ProducePartialResultsOnWorkerThread( 163 void RTCStatsCollector::ProducePartialResultsOnWorkerThread(
142 int64_t timestamp_us) { 164 int64_t timestamp_us) {
143 RTC_DCHECK(worker_thread_->IsCurrent()); 165 RTC_DCHECK(worker_thread_->IsCurrent());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 RTC_DCHECK(!callbacks_.empty()); 214 RTC_DCHECK(!callbacks_.empty());
193 RTC_DCHECK(cached_report_); 215 RTC_DCHECK(cached_report_);
194 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback : 216 for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback :
195 callbacks_) { 217 callbacks_) {
196 callback->OnStatsDelivered(cached_report_); 218 callback->OnStatsDelivered(cached_report_);
197 } 219 }
198 callbacks_.clear(); 220 callbacks_.clear();
199 } 221 }
200 222
201 void RTCStatsCollector::ProduceCertificateStats_s( 223 void RTCStatsCollector::ProduceCertificateStats_s(
202 int64_t timestamp_us, const SessionStats& session_stats, 224 int64_t timestamp_us,
225 const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
203 RTCStatsReport* report) const { 226 RTCStatsReport* report) const {
204 RTC_DCHECK(signaling_thread_->IsCurrent()); 227 RTC_DCHECK(signaling_thread_->IsCurrent());
205 for (const auto& transport_stats : session_stats.transport_stats) { 228 for (const auto& kvp : transport_cert_stats) {
206 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate; 229 if (kvp.second.local) {
207 if (pc_->session()->GetLocalCertificate( 230 ProduceCertificateStatsFromSSLCertificateStats_s(
208 transport_stats.second.transport_name, &local_certificate)) { 231 timestamp_us, *kvp.second.local.get(), report);
209 ProduceCertificateStatsFromSSLCertificateAndChain_s(
210 timestamp_us, local_certificate->ssl_certificate(), report);
211 } 232 }
212 std::unique_ptr<rtc::SSLCertificate> remote_certificate = 233 if (kvp.second.remote) {
213 pc_->session()->GetRemoteSSLCertificate( 234 ProduceCertificateStatsFromSSLCertificateStats_s(
214 transport_stats.second.transport_name); 235 timestamp_us, *kvp.second.remote.get(), report);
215 if (remote_certificate) {
216 ProduceCertificateStatsFromSSLCertificateAndChain_s(
217 timestamp_us, *remote_certificate.get(), report);
218 } 236 }
219 } 237 }
220 } 238 }
221 239
222 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateAndChain_s( 240 void RTCStatsCollector::ProduceCertificateStatsFromSSLCertificateStats_s(
223 int64_t timestamp_us, const rtc::SSLCertificate& certificate, 241 int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats,
224 RTCStatsReport* report) const { 242 RTCStatsReport* report) const {
225 RTC_DCHECK(signaling_thread_->IsCurrent()); 243 RTC_DCHECK(signaling_thread_->IsCurrent());
226 std::unique_ptr<rtc::SSLCertificateStats> ssl_stats = 244 RTCCertificateStats* prev_certificate_stats = nullptr;
227 certificate.GetStats(); 245 for (const rtc::SSLCertificateStats* s = &certificate_stats; s;
228 RTCCertificateStats* prev_stats = nullptr;
229 for (rtc::SSLCertificateStats* s = ssl_stats.get(); s;
230 s = s->issuer.get()) { 246 s = s->issuer.get()) {
231 RTCCertificateStats* stats = new RTCCertificateStats( 247 RTCCertificateStats* certificate_stats = new RTCCertificateStats(
232 "RTCCertificate_" + s->fingerprint, timestamp_us); 248 RTCCertificateIDFromFingerprint(s->fingerprint), timestamp_us);
233 stats->fingerprint = s->fingerprint; 249 certificate_stats->fingerprint = s->fingerprint;
234 stats->fingerprint_algorithm = s->fingerprint_algorithm; 250 certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm;
235 stats->base64_certificate = s->base64_certificate; 251 certificate_stats->base64_certificate = s->base64_certificate;
236 if (prev_stats) 252 if (prev_certificate_stats)
237 prev_stats->issuer_certificate_id = stats->id(); 253 prev_certificate_stats->issuer_certificate_id = certificate_stats->id();
238 report->AddStats(std::unique_ptr<RTCCertificateStats>(stats)); 254 report->AddStats(std::unique_ptr<RTCCertificateStats>(certificate_stats));
239 prev_stats = stats; 255 prev_certificate_stats = certificate_stats;
240 } 256 }
241 } 257 }
242 258
243 void RTCStatsCollector::ProduceDataChannelStats_s( 259 void RTCStatsCollector::ProduceDataChannelStats_s(
244 int64_t timestamp_us, RTCStatsReport* report) const { 260 int64_t timestamp_us, RTCStatsReport* report) const {
245 RTC_DCHECK(signaling_thread_->IsCurrent()); 261 RTC_DCHECK(signaling_thread_->IsCurrent());
246 for (const rtc::scoped_refptr<DataChannel>& data_channel : 262 for (const rtc::scoped_refptr<DataChannel>& data_channel :
247 pc_->sctp_data_channels()) { 263 pc_->sctp_data_channels()) {
248 std::unique_ptr<RTCDataChannelStats> data_channel_stats( 264 std::unique_ptr<RTCDataChannelStats> data_channel_stats(
249 new RTCDataChannelStats( 265 new RTCDataChannelStats(
(...skipping 13 matching lines...) Expand all
263 } 279 }
264 280
265 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s( 281 void RTCStatsCollector::ProduceIceCandidateAndPairStats_s(
266 int64_t timestamp_us, const SessionStats& session_stats, 282 int64_t timestamp_us, const SessionStats& session_stats,
267 RTCStatsReport* report) const { 283 RTCStatsReport* report) const {
268 RTC_DCHECK(signaling_thread_->IsCurrent()); 284 RTC_DCHECK(signaling_thread_->IsCurrent());
269 for (const auto& transport_stats : session_stats.transport_stats) { 285 for (const auto& transport_stats : session_stats.transport_stats) {
270 for (const auto& channel_stats : transport_stats.second.channel_stats) { 286 for (const auto& channel_stats : transport_stats.second.channel_stats) {
271 for (const cricket::ConnectionInfo& info : 287 for (const cricket::ConnectionInfo& info :
272 channel_stats.connection_infos) { 288 channel_stats.connection_infos) {
273 const std::string& id = "RTCIceCandidatePair_" +
274 info.local_candidate.id() + "_" + info.remote_candidate.id();
275 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats( 289 std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
276 new RTCIceCandidatePairStats(id, timestamp_us)); 290 new RTCIceCandidatePairStats(
291 RTCIceCandidatePairStatsIDFromConnectionInfo(info),
292 timestamp_us));
277 293
278 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members, 294 // TODO(hbos): Set all of the |RTCIceCandidatePairStats|'s members,
279 // crbug.com/633550. 295 // crbug.com/633550.
280 296
281 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to 297 // TODO(hbos): Set candidate_pair_stats->transport_id. Should be ID to
282 // RTCTransportStats which does not exist yet: crbug.com/653873. 298 // RTCTransportStats which does not exist yet: crbug.com/653873.
283 299
284 // TODO(hbos): There could be other candidates that are not paired with 300 // TODO(hbos): There could be other candidates that are not paired with
285 // anything. We don't have a complete list. Local candidates come from 301 // anything. We don't have a complete list. Local candidates come from
286 // Port objects, and prflx candidates (both local and remote) are only 302 // Port objects, and prflx candidates (both local and remote) are only
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 // There is always just one |RTCPeerConnectionStats| so its |id| can be a 390 // There is always just one |RTCPeerConnectionStats| so its |id| can be a
375 // constant. 391 // constant.
376 std::unique_ptr<RTCPeerConnectionStats> stats( 392 std::unique_ptr<RTCPeerConnectionStats> stats(
377 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us)); 393 new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us));
378 stats->data_channels_opened = data_channels_opened; 394 stats->data_channels_opened = data_channels_opened;
379 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) - 395 stats->data_channels_closed = static_cast<uint32_t>(data_channels.size()) -
380 data_channels_opened; 396 data_channels_opened;
381 report->AddStats(std::move(stats)); 397 report->AddStats(std::move(stats));
382 } 398 }
383 399
400 void RTCStatsCollector::ProduceTransportStats_s(
401 int64_t timestamp_us, const SessionStats& session_stats,
402 const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
403 RTCStatsReport* report) const {
404 RTC_DCHECK(signaling_thread_->IsCurrent());
405 for (const auto& transport : session_stats.transport_stats) {
406 // Get reference to RTCP channel, if it exists.
407 std::string rtcp_transport_stats_id;
408 for (const auto& channel_stats : transport.second.channel_stats) {
409 if (channel_stats.component ==
410 cricket::ICE_CANDIDATE_COMPONENT_RTCP) {
411 rtcp_transport_stats_id = RTCTransportStatsIDFromTransportChannel(
412 transport.second.transport_name, channel_stats.component);
413 break;
414 }
415 }
416
417 // Get reference to local and remote certificates of this transport, if they
418 // exist.
419 const auto& certificate_stats_it = transport_cert_stats.find(
420 transport.second.transport_name);
421 RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
422 std::string local_certificate_id;
423 if (certificate_stats_it->second.local) {
424 local_certificate_id = RTCCertificateIDFromFingerprint(
425 certificate_stats_it->second.local->fingerprint);
426 }
427 std::string remote_certificate_id;
428 if (certificate_stats_it->second.remote) {
429 remote_certificate_id = RTCCertificateIDFromFingerprint(
430 certificate_stats_it->second.remote->fingerprint);
431 }
432
433 // There is one transport stats for each channel.
434 for (const auto& channel_stats : transport.second.channel_stats) {
435 std::unique_ptr<RTCTransportStats> transport_stats(
436 new RTCTransportStats(
437 RTCTransportStatsIDFromTransportChannel(
438 transport.second.transport_name, channel_stats.component),
439 timestamp_us));
440 transport_stats->bytes_sent = 0;
441 transport_stats->bytes_received = 0;
442 transport_stats->active_connection = false;
443 for (const cricket::ConnectionInfo& info :
444 channel_stats.connection_infos) {
445 *transport_stats->bytes_sent += info.sent_total_bytes;
446 *transport_stats->bytes_received += info.recv_total_bytes;
447 if (info.best_connection) {
448 transport_stats->active_connection = true;
449 transport_stats->selected_candidate_pair_id =
450 RTCIceCandidatePairStatsIDFromConnectionInfo(info);
451 }
452 }
453 if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP &&
454 !rtcp_transport_stats_id.empty()) {
455 transport_stats->rtcp_transport_stats_id = rtcp_transport_stats_id;
456 }
457 if (!local_certificate_id.empty())
458 transport_stats->local_certificate_id = local_certificate_id;
459 if (!remote_certificate_id.empty())
460 transport_stats->remote_certificate_id = remote_certificate_id;
461 report->AddStats(std::move(transport_stats));
462 }
463 }
464 }
465
466 std::map<std::string, RTCStatsCollector::CertificateStatsPair>
467 RTCStatsCollector::PrepareTransportCertificateStats_s(
468 const SessionStats& session_stats) const {
469 RTC_DCHECK(signaling_thread_->IsCurrent());
470 std::map<std::string, CertificateStatsPair> transport_cert_stats;
471 for (const auto& transport_stats : session_stats.transport_stats) {
472 CertificateStatsPair certificate_stats_pair;
473 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate;
474 if (pc_->session()->GetLocalCertificate(
475 transport_stats.second.transport_name, &local_certificate)) {
476 certificate_stats_pair.local =
477 local_certificate->ssl_certificate().GetStats();
478 }
479 std::unique_ptr<rtc::SSLCertificate> remote_certificate =
480 pc_->session()->GetRemoteSSLCertificate(
481 transport_stats.second.transport_name);
482 if (remote_certificate) {
483 certificate_stats_pair.remote = remote_certificate->GetStats();
484 }
485 transport_cert_stats.insert(
486 std::make_pair(transport_stats.second.transport_name,
487 std::move(certificate_stats_pair)));
488 }
489 return transport_cert_stats;
490 }
491
384 const char* CandidateTypeToRTCIceCandidateTypeForTesting( 492 const char* CandidateTypeToRTCIceCandidateTypeForTesting(
385 const std::string& type) { 493 const std::string& type) {
386 return CandidateTypeToRTCIceCandidateType(type); 494 return CandidateTypeToRTCIceCandidateType(type);
387 } 495 }
388 496
389 const char* DataStateToRTCDataChannelStateForTesting( 497 const char* DataStateToRTCDataChannelStateForTesting(
390 DataChannelInterface::DataState state) { 498 DataChannelInterface::DataState state) {
391 return DataStateToRTCDataChannelState(state); 499 return DataStateToRTCDataChannelState(state);
392 } 500 }
393 501
394 } // namespace webrtc 502 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/rtcstatscollector.h ('k') | webrtc/api/rtcstatscollector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698