Bug 1073027 - Control MozLoopService logging with a preference. r=jaws
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 25 Sep 2014 09:00:32 -0700
changeset 207413 f5a053aaba52e9f6b86ea0cbfa679410931de1c6
parent 207412 bcd0d2b817a849aafb3081c0e0081ec9a102d3a4
child 207414 06a1582f7d5f04cbdff8565001574ef73261c65a
push id27553
push usercbook@mozilla.com
push dateFri, 26 Sep 2014 11:28:12 +0000
treeherdermozilla-central@68f76e3c5787 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1073027
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1073027 - Control MozLoopService logging with a preference. r=jaws
browser/app/profile/firefox.js
browser/components/loop/MozLoopService.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1608,16 +1608,17 @@ pref("loop.seenToS", "unseen");
 pref("loop.legal.ToS_url", "https://call.mozilla.com/legal/terms/");
 pref("loop.legal.privacy_url", "https://www.mozilla.org/privacy/");
 pref("loop.do_not_disturb", false);
 pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");
 pref("loop.retry_delay.start", 60000);
 pref("loop.retry_delay.limit", 300000);
 pref("loop.feedback.baseUrl", "https://input.mozilla.org/api/v1/feedback");
 pref("loop.feedback.product", "Loop");
+pref("loop.debug.loglevel", "Error");
 pref("loop.debug.websocket", false);
 pref("loop.debug.sdk", false);
 
 // serverURL to be assigned by services team
 pref("services.push.serverURL", "wss://push.services.mozilla.com/");
 
 pref("social.sidebar.unload_timeout_ms", 10000);
 
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -15,29 +15,29 @@ const INVALID_AUTH_TOKEN = 110;
 // serving" number of 2^24 - 1 is greater than it.
 const MAX_SOFT_START_TICKET_NUMBER = 16777214;
 
 const LOOP_SESSION_TYPE = {
   GUEST: 1,
   FXA: 2,
 };
 
+// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
+const PREF_LOG_LEVEL = "loop.debug.loglevel";
+
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/osfile.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/FxAccountsOAuthClient.jsm");
 Cu.importGlobalProperties(["URL"]);
 
 this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE"];
 
-XPCOMUtils.defineLazyModuleGetter(this, "console",
-  "resource://gre/modules/devtools/Console.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI",
   "resource:///modules/loop/MozLoopAPI.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport",
   "resource://gre/modules/media/RTCStatsReport.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Chat", "resource:///modules/Chat.jsm");
 
@@ -62,16 +62,25 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
                                    "@mozilla.org/network/dns-service;1",
                                    "nsIDNSService");
 
+// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
+XPCOMUtils.defineLazyGetter(this, "log", () => {
+  let ConsoleAPI = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).ConsoleAPI;
+  let consoleOptions = {
+    maxLogLevel: Services.prefs.getCharPref(PREF_LOG_LEVEL).toLowerCase(),
+    prefix: "Loop",
+  };
+  return new ConsoleAPI(consoleOptions);
+});
 
 // The current deferred for the registration process. This is set if in progress
 // or the registration was successful. This is null if a registration attempt was
 // unsuccessful.
 let gRegisteredDeferred = null;
 let gPushHandler = null;
 let gHawkClient = null;
 let gLocalizedStrings =  null;
@@ -107,17 +116,17 @@ CallProgressSocket.prototype = {
    *
    * @param {function} Callback used after a successful handshake
    *                   over the progressUrl.
    * @param {function} Callback used if an error is encountered
    */
   connect: function(onSuccess, onError) {
     this._onSuccess = onSuccess;
     this._onError = onError ||
-      (reason => {console.warn("MozLoopService::callProgessSocket - ", reason);});
+      (reason => {log.warn("MozLoopService::callProgessSocket - ", reason);});
 
     if (!onSuccess) {
       this._onError("missing onSuccess argument");
       return;
     }
 
     if (Services.io.offline) {
       this._onError("IO offline");
@@ -188,17 +197,17 @@ CallProgressSocket.prototype = {
    * @param {String} aMsg The message data
    */
   onMessageAvailable: function(aContext, aMsg) {
     let msg = {};
     try {
       msg = JSON.parse(aMsg);
     }
     catch (error) {
-      console.error("MozLoopService: error parsing progress message - ", error);
+      log.error("MozLoopService: error parsing progress message - ", error);
       return;
     }
 
     if (msg.messageType && msg.messageType === 'hello') {
       this._handshakeComplete = true;
       this._onSuccess();
     }
   },
@@ -206,17 +215,17 @@ CallProgressSocket.prototype = {
 
   /**
    * Create a JSON message payload and send on websocket.
    *
    * @param {Object} aMsg Message to send.
    */
   _send: function(aMsg) {
     if (!this._handshakeComplete) {
-      console.warn("MozLoopService::_send error - handshake not complete");
+      log.warn("MozLoopService::_send error - handshake not complete");
       return;
     }
 
     try {
       this._websocket.sendMsg(JSON.stringify(aMsg));
     }
     catch (error) {
       this._onError(error);
@@ -407,17 +416,17 @@ let MozLoopServiceInternal = {
   /**
    * Generic hawkRequest onError handler for the hawkRequest promise.
    *
    * @param {Object} error - error reporting object
    *
    */
 
   _hawkRequestError: function(error) {
-    console.error("Loop hawkRequest error:", error);
+    log.error("Loop hawkRequest error:", error);
     throw error;
   },
 
   getSessionTokenPrefName: function(sessionType) {
     let suffix;
     switch (sessionType) {
       case LOOP_SESSION_TYPE.GUEST:
         suffix = "";
@@ -444,17 +453,17 @@ let MozLoopServiceInternal = {
   storeSessionToken: function(sessionType, headers) {
     let sessionToken = headers["hawk-session-token"];
     if (sessionToken) {
       // XXX should do more validation here
       if (sessionToken.length === 64) {
         Services.prefs.setCharPref(this.getSessionTokenPrefName(sessionType), sessionToken);
       } else {
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
-        console.warn("Loop server sent an invalid session token");
+        log.warn("Loop server sent an invalid session token");
         gRegisteredDeferred.reject("session-token-wrong-size");
         gRegisteredDeferred = null;
         return false;
       }
     }
     return true;
   },
 
@@ -489,17 +498,17 @@ let MozLoopServiceInternal = {
       // storeSessionToken could have rejected and nulled the promise if the token was malformed.
       if (!gRegisteredDeferred) {
         return;
       }
       gRegisteredDeferred.resolve();
       // No need to clear the promise here, everything was good, so we don't need
       // to re-register.
     }, (error) => {
-      console.error("Failed to register with Loop server: ", error);
+      log.error("Failed to register with Loop server: ", error);
       gRegisteredDeferred.reject(error.errno);
       gRegisteredDeferred = null;
     });
   },
 
   /**
    * Registers with the Loop server either as a guest or a FxA user.
    *
@@ -531,17 +540,17 @@ let MozLoopServiceInternal = {
           // Authorization failed, invalid token, we need to try again with a new token.
           this.clearSessionToken(sessionType);
           if (retry) {
             return this.registerWithLoopServer(sessionType, pushUrl, false);
           }
         }
 
         // XXX Bubble the precise details up to the UI somehow (bug 1013248).
-        console.error("Failed to register with the loop server. Error: ", error);
+        log.error("Failed to register with the loop server. Error: ", error);
         this.setError("registration", error);
         throw error;
       }
     );
   },
 
   /**
    * Unregisters from the Loop server either as a guest or a FxA user.
@@ -563,17 +572,17 @@ let MozLoopServiceInternal = {
       error => {
         // Always clear the registration token regardless of whether the server acknowledges the logout.
         MozLoopServiceInternal.clearSessionToken(sessionType);
         if (error.code === 401 && error.errno === INVALID_AUTH_TOKEN) {
           // Authorization failed, invalid token. This is fine since it may mean we already logged out.
           return;
         }
 
-        console.error("Failed to unregister with the loop server. Error: ", error);
+        log.error("Failed to unregister with the loop server. Error: ", error);
         throw error;
       });
   },
 
   /**
    * Callback from MozLoopPushHandler - A push notification has been received from
    * the server.
    *
@@ -640,20 +649,20 @@ let MozLoopServiceInternal = {
               null,
               this.localizedStrings["incoming_call_title2"].textContent,
               "about:loopconversation#incoming/" + callData.callId);
           } else {
             this._returnBusy(callData);
           }
         });
       } else {
-        console.warn("Error: missing calls[] in response");
+        log.warn("Error: missing calls[] in response");
       }
     } catch (err) {
-      console.warn("Error parsing calls info", err);
+      log.warn("Error parsing calls info", err);
     }
   },
 
    /**
    * Open call progress websocket and terminate with a reason of busy
    * the server.
    *
    * @param {callData} Must contain the progressURL, callId and websocketToken
@@ -755,17 +764,17 @@ let MozLoopServiceInternal = {
           }
         };
 
         // Send job to worker to do log sanitation, transcoding and saving to
         // disk for pickup by telemetry on next startup, which then uploads it.
 
         let worker = new ChromeWorker("MozLoopWorker.js");
         worker.onmessage = function(e) {
-          console.log(e.data.ok ?
+          log.info(e.data.ok ?
             "Successfully staged loop report for telemetry upload." :
             ("Failed to stage loop report. Error: " + e.data.fail));
         }
         worker.postMessage(job);
       });
     }, pc.id);
   },
 
@@ -893,17 +902,17 @@ let MozLoopServiceInternal = {
   promiseFxAOAuthAuthorization: function() {
     let deferred = Promise.defer();
     this.promiseFxAOAuthClient().then(
       client => {
         client.onComplete = this._fxAOAuthComplete.bind(this, deferred);
         client.launchWebFlow();
       },
       error => {
-        console.error(error);
+        log.error(error);
         deferred.reject(error);
       }
     );
     return deferred.promise;
   },
 
   /**
    * Get the OAuth token using the OAuth code and state.
@@ -1063,17 +1072,17 @@ this.MozLoopService = {
       // Can't use bitwise operations here because JS treats all bitwise
       // operations as 32-bit *signed* integers.
       let now_serving = ((parseInt(address[1]) * 0x10000) +
                          (parseInt(address[2]) * 0x100) +
                          parseInt(address[3]));
 
       if (now_serving > ticket) {
         // Hot diggity! It's our turn! Activate the service.
-        console.log("MozLoopService: Activating Loop via soft-start");
+        log.info("MozLoopService: Activating Loop via soft-start");
         Services.prefs.setBoolPref("loop.throttled", false);
         buttonNode.hidden = false;
         this.initialize();
       }
       if (typeof(doneCb) == "function") {
         doneCb(null);
       }
     };
@@ -1229,17 +1238,17 @@ this.MozLoopService = {
    * @param {String} value The value to set.
    *
    * Any errors thrown by the Mozilla pref API are logged to the console.
    */
   setLoopCharPref: function(prefName, value) {
     try {
       Services.prefs.setCharPref("loop." + prefName, value);
     } catch (ex) {
-      console.log("setLoopCharPref had trouble setting " + prefName +
+      log.error("setLoopCharPref had trouble setting " + prefName +
         "; exception: " + ex);
     }
   },
 
   /**
    * Return any preference under "loop." that's coercible to a character
    * preference.
    *
@@ -1251,17 +1260,17 @@ this.MozLoopService = {
    * not being found.
    *
    * @return {String} on success, null on error
    */
   getLoopCharPref: function(prefName) {
     try {
       return Services.prefs.getCharPref("loop." + prefName);
     } catch (ex) {
-      console.log("getLoopCharPref had trouble getting " + prefName +
+      log.error("getLoopCharPref had trouble getting " + prefName +
         "; exception: " + ex);
       return null;
     }
   },
 
   /**
    * Return any preference under "loop." that's coercible to a character
    * preference.
@@ -1274,17 +1283,17 @@ this.MozLoopService = {
    * not being found.
    *
    * @return {String} on success, null on error
    */
   getLoopBoolPref: function(prefName) {
     try {
       return Services.prefs.getBoolPref("loop." + prefName);
     } catch (ex) {
-      console.log("getLoopBoolPref had trouble getting " + prefName +
+      log.error("getLoopBoolPref had trouble getting " + prefName +
         "; exception: " + ex);
       return null;
     }
   },
 
   /**
    * Start the FxA login flow using the OAuth client and params from the Loop server.
    *
@@ -1315,17 +1324,17 @@ this.MozLoopService = {
       let client = new FxAccountsProfileClient({
         serverURL: gFxAOAuthClient.parameters.profile_uri,
         token: tokenData.access_token
       });
       client.fetchProfile().then(result => {
         gFxAOAuthProfile = result;
         MozLoopServiceInternal.notifyStatusChanged("login");
       }, error => {
-        console.error("Failed to retrieve profile", error);
+        log.error("Failed to retrieve profile", error);
         gFxAOAuthProfile = null;
         MozLoopServiceInternal.notifyStatusChanged();
       });
       return tokenData;
     }).catch(error => {
       gFxAOAuthTokenData = null;
       gFxAOAuthProfile = null;
       throw error;