Merge pull request #399 from isymchych/callstats-error-reporting

Callstats error reporting. Ivan is going to publish another PR about earlier failures that would apply on top of this one.
This commit is contained in:
yanas 2015-11-10 13:39:23 -06:00
commit 071fbfbd0d
7 changed files with 140 additions and 11 deletions

View File

@ -177,7 +177,7 @@ var RTC = {
null, null, getMediaStreamUsage()); null, null, getMediaStreamUsage());
}; };
this.rtcUtils = new RTCUtils(this, onReady); this.rtcUtils = new RTCUtils(this, eventEmitter, onReady);
// Call onReady() if Temasys plugin is not used // Call onReady() if Temasys plugin is not used
if (!RTCBrowserType.isTemasysPluginUsed()) { if (!RTCBrowserType.isTemasysPluginUsed()) {

View File

@ -5,6 +5,7 @@
var MediaStreamType = require("../../service/RTC/MediaStreamTypes"); var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var RTCBrowserType = require("./RTCBrowserType"); var RTCBrowserType = require("./RTCBrowserType");
var Resolutions = require("../../service/RTC/Resolutions"); var Resolutions = require("../../service/RTC/Resolutions");
var RTCEvents = require("../../service/RTC/RTCEvents");
var AdapterJS = require("./adapter.screenshare"); var AdapterJS = require("./adapter.screenshare");
var currentResolution = null; var currentResolution = null;
@ -153,10 +154,11 @@ function getConstraints(um, resolution, bandwidth, fps, desktopStream) {
} }
function RTCUtils(RTCService, onTemasysPluginReady) function RTCUtils(RTCService, eventEmitter, onTemasysPluginReady)
{ {
var self = this; var self = this;
this.service = RTCService; this.service = RTCService;
this.eventEmitter = eventEmitter;
if (RTCBrowserType.isFirefox()) { if (RTCBrowserType.isFirefox()) {
var FFversion = RTCBrowserType.getFirefoxVersion(); var FFversion = RTCBrowserType.getFirefoxVersion();
if (FFversion >= 40) { if (FFversion >= 40) {
@ -322,12 +324,14 @@ RTCUtils.prototype.getUserMediaWithConstraints = function(
self.setAvailableDevices(um, false); self.setAvailableDevices(um, false);
console.warn('Failed to get access to local media. Error ', console.warn('Failed to get access to local media. Error ',
error, constraints); error, constraints);
self.eventEmitter.emit(RTCEvents.GET_USER_MEDIA_FAILED, error);
if (failure_callback) { if (failure_callback) {
failure_callback(error); failure_callback(error);
} }
}); });
} catch (e) { } catch (e) {
console.error('GUM failed: ', e); console.error('GUM failed: ', e);
self.eventEmitter.emit(RTCEvents.GET_USER_MEDIA_FAILED, e);
if(failure_callback) { if(failure_callback) {
failure_callback(e); failure_callback(e);
} }

View File

@ -5,6 +5,11 @@ var jsSHA = require('jssha');
var io = require('socket.io-client'); var io = require('socket.io-client');
var callStats = null; var callStats = null;
// getUserMedia calls happen before CallStats init
// so if there are any getUserMedia errors, we store them in this array
// and send them to callstats on init
var pendingUserMediaErrors = [];
function initCallback (err, msg) { function initCallback (err, msg) {
console.log("Initializing Status: err="+err+" msg="+msg); console.log("Initializing Status: err="+err+" msg="+msg);
} }
@ -38,17 +43,25 @@ var CallStats = {
usage, usage,
this.confID, this.confID,
this.pcCallback.bind(this)); this.pcCallback.bind(this));
// notify callstats about getUserMedia failures if there were any
if (pendingUserMediaErrors.length) {
pendingUserMediaErrors.forEach(this.sendGetUserMediaFailed, this);
pendingUserMediaErrors.length = 0;
}
}, },
pcCallback: function (err, msg) { pcCallback: function (err, msg) {
if (!callStats) if (!callStats) {
return; return;
}
console.log("Monitoring status: "+ err + " msg: " + msg); console.log("Monitoring status: "+ err + " msg: " + msg);
callStats.sendFabricEvent(this.peerconnection, callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricSetup, this.confID); callStats.fabricEvent.fabricSetup, this.confID);
}, },
sendMuteEvent: function (mute, type) { sendMuteEvent: function (mute, type) {
if (!callStats) if (!callStats) {
return; return;
}
var event = null; var event = null;
if (type === "video") { if (type === "video") {
event = (mute? callStats.fabricEvent.videoPause : event = (mute? callStats.fabricEvent.videoPause :
@ -74,6 +87,7 @@ var CallStats = {
callStats.sendFabricEvent(this.peerconnection, callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricSetupFailed, this.confID); callStats.fabricEvent.fabricSetupFailed, this.confID);
}, },
/** /**
* Sends the given feedback through CallStats. * Sends the given feedback through CallStats.
* *
@ -93,6 +107,86 @@ var CallStats = {
callStats.sendUserFeedback( callStats.sendUserFeedback(
this.confID, feedbackJSON); this.confID, feedbackJSON);
},
/**
* Notifies CallStats that getUserMedia failed.
*
* @param {Error} e error to send
*/
sendGetUserMediaFailed: function (e) {
if(!callStats) {
pendingUserMediaErrors.push(e);
return;
}
callStats.reportError(this.peerconnection, this.confID,
callStats.webRTCFunctions.getUserMedia, e);
},
/**
* Notifies CallStats that peer connection failed to create offer.
*
* @param {Error} e error to send
*/
sendCreateOfferFailed: function (e) {
if(!callStats) {
return;
}
callStats.reportError(this.peerconnection, this.confID,
callStats.webRTCFunctions.createOffer, e);
},
/**
* Notifies CallStats that peer connection failed to create answer.
*
* @param {Error} e error to send
*/
sendCreateAnswerFailed: function (e) {
if(!callStats) {
return;
}
callStats.reportError(this.peerconnection, this.confID,
callStats.webRTCFunctions.createAnswer, e);
},
/**
* Notifies CallStats that peer connection failed to set local description.
*
* @param {Error} e error to send
*/
sendSetLocalDescFailed: function (e) {
if(!callStats) {
return;
}
callStats.reportError(this.peerconnection, this.confID,
callStats.webRTCFunctions.setLocalDescription, e);
},
/**
* Notifies CallStats that peer connection failed to set remote description.
*
* @param {Error} e error to send
*/
sendSetRemoteDescFailed: function (e) {
if(!callStats) {
return;
}
callStats.reportError(
this.peerconnection, this.confID,
callStats.webRTCFunctions.setRemoteDescription, e);
},
/**
* Notifies CallStats that peer connection failed to add ICE candidate.
*
* @param {Error} e error to send
*/
sendAddIceCandidateFailed: function (e) {
if(!callStats) {
return;
}
callStats.reportError(this.peerconnection, this.confID,
callStats.webRTCFunctions.addIceCandidate, e);
} }
}; };
module.exports = CallStats; module.exports = CallStats;

View File

@ -109,6 +109,25 @@ var statistics = {
APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) { APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) {
CallStats.sendMuteEvent(mute, "video"); CallStats.sendMuteEvent(mute, "video");
}); });
APP.RTC.addListener(RTCEvents.GET_USER_MEDIA_FAILED, function (e) {
CallStats.sendGetUserMediaFailed(e);
});
APP.xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e) {
CallStats.sendCreateOfferFailed(e);
});
APP.xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e) {
CallStats.sendCreateAnswerFailed(e);
});
APP.xmpp.addListener(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, function (e) {
CallStats.sendSetLocalDescFailed(e);
});
APP.xmpp.addListener(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, function (e) {
CallStats.sendSetRemoteDescFailed(e);
});
APP.xmpp.addListener(RTCEvents.ADD_ICE_CANDIDATE_FAILED, function (e) {
CallStats.sendAddIceCandidateFailed(e);
});
} }
}; };

View File

@ -8,6 +8,7 @@ var SDP = require("./SDP");
var async = require("async"); var async = require("async");
var transform = require("sdp-transform"); var transform = require("sdp-transform");
var XMPPEvents = require("../../service/xmpp/XMPPEvents"); var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var RTCEvents = require("../../service/RTC/RTCEvents");
var RTCBrowserType = require("../RTC/RTCBrowserType"); var RTCBrowserType = require("../RTC/RTCBrowserType");
var SSRCReplacement = require("./LocalSSRCReplacement"); var SSRCReplacement = require("./LocalSSRCReplacement");
@ -719,6 +720,7 @@ JingleSessionPC.prototype.addIceCandidate = function (elem) {
self.peerconnection.addIceCandidate(candidate); self.peerconnection.addIceCandidate(candidate);
} catch (e) { } catch (e) {
console.error('addIceCandidate failed', e.toString(), line); console.error('addIceCandidate failed', e.toString(), line);
self.eventEmitter.emit(RTCEvents.ADD_ICE_CANDIDATE_FAILED, err);
} }
}); });
}); });

View File

@ -2,8 +2,8 @@
webkitRTCPeerConnection, RTCSessionDescription */ webkitRTCPeerConnection, RTCSessionDescription */
/* jshint -W101 */ /* jshint -W101 */
var RTC = require('../RTC/RTC'); var RTC = require('../RTC/RTC');
var RTCBrowserType = require("../RTC/RTCBrowserType.js"); var RTCBrowserType = require("../RTC/RTCBrowserType");
var XMPPEvents = require("../../service/xmpp/XMPPEvents"); var RTCEvents = require("../../service/RTC/RTCEvents");
var SSRCReplacement = require("./LocalSSRCReplacement"); var SSRCReplacement = require("./LocalSSRCReplacement");
function TraceablePeerConnection(ice_config, constraints, session) { function TraceablePeerConnection(ice_config, constraints, session) {
@ -16,6 +16,7 @@ function TraceablePeerConnection(ice_config, constraints, session) {
} else { } else {
RTCPeerConnectionType = webkitRTCPeerConnection; RTCPeerConnectionType = webkitRTCPeerConnection;
} }
self.eventEmitter = session.eventEmitter;
this.peerconnection = new RTCPeerConnectionType(ice_config, constraints); this.peerconnection = new RTCPeerConnectionType(ice_config, constraints);
this.updateLog = []; this.updateLog = [];
this.stats = {}; this.stats = {};
@ -292,6 +293,7 @@ TraceablePeerConnection.prototype.setLocalDescription
}, },
function (err) { function (err) {
self.trace('setLocalDescriptionOnFailure', err); self.trace('setLocalDescriptionOnFailure', err);
self.eventEmitter.emit(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, err);
failureCallback(err); failureCallback(err);
} }
); );
@ -327,6 +329,7 @@ TraceablePeerConnection.prototype.setRemoteDescription
}, },
function (err) { function (err) {
self.trace('setRemoteDescriptionOnFailure', err); self.trace('setRemoteDescriptionOnFailure', err);
self.eventEmitter.emit(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, err);
failureCallback(err); failureCallback(err);
} }
); );
@ -372,6 +375,7 @@ TraceablePeerConnection.prototype.createOffer
}, },
function(err) { function(err) {
self.trace('createOfferOnFailure', err); self.trace('createOfferOnFailure', err);
self.eventEmitter.emit(RTCEvents.CREATE_OFFER_FAILED, err);
failureCallback(err); failureCallback(err);
}, },
constraints constraints
@ -402,6 +406,7 @@ TraceablePeerConnection.prototype.createAnswer
}, },
function(err) { function(err) {
self.trace('createAnswerOnFailure', err); self.trace('createAnswerOnFailure', err);
self.eventEmitter.emit(RTCEvents.CREATE_ANSWER_FAILED, err);
failureCallback(err); failureCallback(err);
}, },
constraints constraints
@ -440,4 +445,3 @@ TraceablePeerConnection.prototype.getStats = function(callback, errback) {
}; };
module.exports = TraceablePeerConnection; module.exports = TraceablePeerConnection;

View File

@ -1,6 +1,12 @@
var RTCEvents = { var RTCEvents = {
RTC_READY: "rtc.ready", RTC_READY: "rtc.ready",
DATA_CHANNEL_OPEN: "rtc.data_channel_open", DATA_CHANNEL_OPEN: "rtc.data_channel_open",
CREATE_OFFER_FAILED: "rtc.create_offer_failed",
CREATE_ANSWER_FAILED: "rtc.create_answer_failed",
SET_LOCAL_DESCRIPTION_FAILED: "rtc.set_local_description_failed",
SET_REMOTE_DESCRIPTION_FAILED: "rtc.set_remote_description_failed",
ADD_ICE_CANDIDATE_FAILED: "rtc.add_ice_candidate_failed",
GET_USER_MEDIA_FAILED: "rtc.get_user_media_failed",
LASTN_CHANGED: "rtc.lastn_changed", LASTN_CHANGED: "rtc.lastn_changed",
DOMINANTSPEAKER_CHANGED: "rtc.dominantspeaker_changed", DOMINANTSPEAKER_CHANGED: "rtc.dominantspeaker_changed",
LASTN_ENDPOINT_CHANGED: "rtc.lastn_endpoint_changed", LASTN_ENDPOINT_CHANGED: "rtc.lastn_endpoint_changed",