Bug 1207824: Add Telemetry for WebRTC call type, simultaneous tracks, and renegotiations r=bwc

This commit is contained in:
Randell Jesup 2015-09-25 14:23:01 -04:00
parent 6502969b06
commit f1fdec42a9
6 changed files with 201 additions and 2 deletions

View File

@ -15,13 +15,13 @@
#include "signaling/src/jsep/JsepTransport.h"
#include "signaling/src/sdp/Sdp.h"
#include "JsepTrack.h"
namespace mozilla {
// Forward declarations
class JsepCodecDescription;
class JsepTrack;
struct JsepTrackPair;
enum JsepSignalingState {
kJsepStateStable,
@ -57,7 +57,7 @@ class JsepSession
{
public:
explicit JsepSession(const std::string& name)
: mName(name), mState(kJsepStateStable)
: mName(name), mState(kJsepStateStable), mNegotiations(0)
{
}
virtual ~JsepSession() {}
@ -75,6 +75,11 @@ public:
{
return mState;
}
virtual uint32_t
GetNegotiations() const
{
return mNegotiations;
}
// Set up the ICE And DTLS data.
virtual nsresult SetIceCredentials(const std::string& ufrag,
@ -167,9 +172,30 @@ public:
virtual bool AllLocalTracksAreAssigned() const = 0;
void
CountTracks(uint16_t (&receiving)[SdpMediaSection::kMediaTypes],
uint16_t (&sending)[SdpMediaSection::kMediaTypes]) const
{
auto trackPairs = GetNegotiatedTrackPairs();
memset(receiving, 0, sizeof(receiving));
memset(sending, 0, sizeof(sending));
for (auto& pair : trackPairs) {
if (pair.mReceiving) {
receiving[pair.mReceiving->GetMediaType()]++;
}
if (pair.mSending) {
sending[pair.mSending->GetMediaType()]++;
}
}
}
protected:
const std::string mName;
JsepSignalingState mState;
uint32_t mNegotiations;
};
} // namespace mozilla

View File

@ -1299,6 +1299,8 @@ JsepSessionImpl::HandleNegotiatedSession(const UniquePtr<Sdp>& local,
mNegotiatedTrackPairs = trackPairs;
mGeneratedLocalDescription.reset();
mNegotiations++;
return NS_OK;
}

View File

@ -410,6 +410,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
mAllowIceLinkLocal = Preferences::GetBool(
"media.peerconnection.ice.link_local", false);
#endif
memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
memset(mMaxSending, 0, sizeof(mMaxSending));
}
PeerConnectionImpl::~PeerConnectionImpl()
@ -2486,6 +2488,57 @@ PeerConnectionImpl::PluginCrash(uint32_t aPluginID,
return true;
}
void
PeerConnectionImpl::RecordEndOfCallTelemetry() const
{
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
// Bitmask used for WEBRTC/LOOP_CALL_TYPE telemetry reporting
static const uint32_t kAudioTypeMask = 1;
static const uint32_t kVideoTypeMask = 2;
static const uint32_t kDataChannelTypeMask = 4;
// Report end-of-call Telemetry
if (mJsepSession->GetNegotiations() > 0) {
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_RENEGOTIATIONS :
Telemetry::WEBRTC_RENEGOTIATIONS,
mJsepSession->GetNegotiations()-1);
}
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_MAX_VIDEO_SEND_TRACK :
Telemetry::WEBRTC_MAX_VIDEO_SEND_TRACK,
mMaxSending[SdpMediaSection::MediaType::kVideo]);
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_MAX_VIDEO_RECEIVE_TRACK :
Telemetry::WEBRTC_MAX_VIDEO_RECEIVE_TRACK,
mMaxReceiving[SdpMediaSection::MediaType::kVideo]);
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_MAX_AUDIO_SEND_TRACK :
Telemetry::WEBRTC_MAX_AUDIO_SEND_TRACK,
mMaxSending[SdpMediaSection::MediaType::kAudio]);
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_MAX_AUDIO_RECEIVE_TRACK :
Telemetry::WEBRTC_MAX_AUDIO_RECEIVE_TRACK,
mMaxReceiving[SdpMediaSection::MediaType::kAudio]);
// DataChannels appear in both Sending and Receiving
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_DATACHANNEL_NEGOTIATED :
Telemetry::WEBRTC_DATACHANNEL_NEGOTIATED,
mMaxSending[SdpMediaSection::MediaType::kApplication]);
// Enumerated/bitmask: 1 = Audio, 2 = Video, 4 = DataChannel
// A/V = 3, A/V/D = 7, etc
uint32_t type = 0;
if (mMaxSending[SdpMediaSection::MediaType::kAudio] ||
mMaxReceiving[SdpMediaSection::MediaType::kAudio]) {
type = kAudioTypeMask;
}
if (mMaxSending[SdpMediaSection::MediaType::kVideo] ||
mMaxReceiving[SdpMediaSection::MediaType::kVideo]) {
type |= kVideoTypeMask;
}
if (mMaxSending[SdpMediaSection::MediaType::kApplication]) {
type |= kDataChannelTypeMask;
}
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_CALL_TYPE :
Telemetry::WEBRTC_CALL_TYPE,
type);
#endif
}
nsresult
PeerConnectionImpl::CloseInt()
{
@ -2496,6 +2549,7 @@ PeerConnectionImpl::CloseInt()
// transitioned to connected. As a bonus, this allows us to detect race
// conditions where a stats dispatch happens right as the PC closes.
RecordLongtermICEStatistics();
RecordEndOfCallTelemetry();
CSFLogInfo(logTag, "%s: Closing PeerConnectionImpl %s; "
"ending call", __FUNCTION__, mHandle.c_str());
if (mJsepSession) {
@ -2585,6 +2639,23 @@ PeerConnectionImpl::SetSignalingState_m(PCImplSignalingState aSignalingState,
fireNegotiationNeeded = true;
}
}
// Telemetry: record info on the current state of streams/renegotiations/etc
// Note: this code gets run on rollbacks as well!
// Update the max channels used with each direction for each type
uint16_t receiving[SdpMediaSection::kMediaTypes];
uint16_t sending[SdpMediaSection::kMediaTypes];
mJsepSession->CountTracks(receiving, sending);
for (size_t i = 0; i < SdpMediaSection::kMediaTypes; i++) {
if (mMaxReceiving[i] < receiving[i]) {
mMaxReceiving[i] = receiving[i];
}
if (mMaxSending[i] < sending[i]) {
mMaxSending[i] = sending[i];
}
}
} else {
mShouldSuppressNegotiationNeeded = true;
}

View File

@ -550,6 +550,8 @@ public:
bool PluginCrash(uint32_t aPluginID,
const nsAString& aPluginName);
void RecordEndOfCallTelemetry() const;
nsresult InitializeDataChannel();
NS_IMETHODIMP_TO_ERRORRESULT_RETREF(nsDOMDataChannel,
@ -796,6 +798,10 @@ private:
bool mShouldSuppressNegotiationNeeded;
// storage for Telemetry data
uint16_t mMaxReceiving[SdpMediaSection::kMediaTypes];
uint16_t mMaxSending[SdpMediaSection::kMediaTypes];
public:
//these are temporary until the DataChannel Listen/Connect API is removed
unsigned short listenPort;

View File

@ -25,6 +25,8 @@ class SdpMediaSection
{
public:
enum MediaType { kAudio, kVideo, kText, kApplication, kMessage };
// don't add to enum to avoid warnings about unhandled enum values
static const size_t kMediaTypes = static_cast<size_t>(kMessage) + 1;
enum Protocol {
kRtpAvp, // RTP/AVP [RFC4566]

View File

@ -6541,6 +6541,52 @@
"n_buckets": "25",
"description": "Percentage of time spent in the Stressed load state in calls 5-30 seconds."
},
"WEBRTC_RENEGOTIATIONS": {
"expires_in_version": "never",
"kind": "linear",
"high": "21",
"n_buckets": "20",
"description": "Number of Renegotiations during each call"
},
"WEBRTC_MAX_VIDEO_SEND_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "10",
"n_buckets": "9",
"description": "Number of Video tracks sent simultaneously"
},
"WEBRTC_MAX_VIDEO_RECEIVE_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "20",
"n_buckets": "19",
"description": "Number of Video tracks received simultaneously"
},
"WEBRTC_MAX_AUDIO_SEND_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "20",
"n_buckets": "19",
"description": "Number of Audio tracks sent simultaneously"
},
"WEBRTC_MAX_AUDIO_RECEIVE_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "30",
"n_buckets": "29",
"description": "Number of Audio tracks received simultaneously"
},
"WEBRTC_DATACHANNEL_NEGOTIATED": {
"expires_in_version": "never",
"kind": "boolean",
"description": "Was DataChannels negotiated"
},
"WEBRTC_CALL_TYPE": {
"expires_in_version": "never",
"kind": "enumerated",
"n_values": "8",
"description": "Type of call: (Bitmask) Audio = 1, Video = 2, DataChannels = 4"
},
"DEVTOOLS_DEBUGGER_RDP_LOCAL_TRACERDETACH_MS": {
"expires_in_version": "never",
"kind": "exponential",
@ -9387,6 +9433,52 @@
"n_values": 8,
"description": "Type for media in getUserMedia calls (0=Camera, 1=Screen, 2=Application, 3=Window, 4=Browser, 5=Microphone, 6=AudioCapture, 7=Other)"
},
"LOOP_RENEGOTIATIONS": {
"expires_in_version": "never",
"kind": "linear",
"high": "21",
"n_buckets": "20",
"description": "Number of Renegotiations during each call"
},
"LOOP_MAX_VIDEO_SEND_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "10",
"n_buckets": "9",
"description": "Number of Video tracks sent simultaneously"
},
"LOOP_MAX_VIDEO_RECEIVE_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "20",
"n_buckets": "19",
"description": "Number of Video tracks received simultaneously"
},
"LOOP_MAX_AUDIO_SEND_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "20",
"n_buckets": "19",
"description": "Number of Audio tracks sent simultaneously"
},
"LOOP_MAX_AUDIO_RECEIVE_TRACK": {
"expires_in_version": "never",
"kind": "linear",
"high": "30",
"n_buckets": "29",
"description": "Number of Audio tracks received simultaneously"
},
"LOOP_DATACHANNEL_NEGOTIATED": {
"expires_in_version": "never",
"kind": "boolean",
"description": "Was DataChannels negotiated"
},
"LOOP_CALL_TYPE": {
"expires_in_version": "never",
"kind": "enumerated",
"n_values": "8",
"description": "Type of call: (Bitmask) Audio = 1, Video = 2, DataChannels = 4"
},
"PERF_MONITORING_TEST_CPU_RESCHEDULING_PROPORTION_MOVED": {
"alert_emails": ["dteller@mozilla.com"],
"expires_in_version": "45",