Bug 553112: Add a shared module for add-ons manager logging. r=robstrong
authorDave Townsend <dtownsend@oxymoronical.com>
Mon, 26 Apr 2010 12:14:19 -0700
changeset 42071 89c73c22d7fb3e0137d4e0a4780469ea4814cee8
parent 42070 67c5cfbb4ba9aa6dad6cc5e6c02d910a469e22d1
child 42072 8db3121bca07599ed58265a6cdaceacacff2362c
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrobstrong
bugs553112
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 553112: Add a shared module for add-ons manager logging. r=robstrong
toolkit/mozapps/extensions/AddonLogging.jsm
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/AddonUpdateChecker.jsm
toolkit/mozapps/extensions/Makefile.in
toolkit/mozapps/extensions/PluginProvider.jsm
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/amWebInstallListener.js
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/AddonLogging.jsm
@@ -0,0 +1,137 @@
+/*
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Extension Manager.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Dave Townsend <dtownsend@oxymoronical.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+*/
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+const KEY_PROFILEDIR                  = "ProfD";
+const FILE_EXTENSIONS_LOG             = "extensions.log";
+
+Components.utils.import("resource://gre/modules/FileUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var EXPORTED_SYMBOLS = [ "LogManager" ];
+
+var gDebugLogEnabled = false;
+
+function formatLogMessage(aType, aName, aStr) {
+  return aType.toUpperCase() + " " + aName + ": " + aStr;
+}
+
+function AddonLogger(aName) {
+  this.name = aName;
+}
+
+AddonLogger.prototype = {
+  name: null,
+
+  error: function(aStr) {
+    let message = formatLogMessage("error", this.name, aStr);
+
+    let consoleMessage = Cc["@mozilla.org/scripterror;1"].
+                         createInstance(Ci.nsIScriptError);
+    consoleMessage.init(message, null, null, 0, 0, Ci.nsIScriptError.errorFlag,
+                        "component javascript");
+    Services.console.logMessage(consoleMessage);
+
+    if (gDebugLogEnabled)
+      dump("*** " + message + "\n");
+
+    try {
+      var tstamp = new Date();
+      var logfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_LOG]);
+      var stream = Cc["@mozilla.org/network/file-output-stream;1"].
+                   createInstance(Ci.nsIFileOutputStream);
+      stream.init(logfile, 0x02 | 0x08 | 0x10, 0666, 0); // write, create, append
+      var writer = Cc["@mozilla.org/intl/converter-output-stream;1"].
+                   createInstance(Ci.nsIConverterOutputStream);
+      writer.init(stream, "UTF-8", 0, 0x0000);
+      writer.writeString(tstamp.toLocaleFormat("%Y-%m-%d %H:%M:%S ") +
+                         message + "\n");
+      writer.close();
+    }
+    catch (e) { }
+  },
+
+  warn: function(aStr) {
+    let message = formatLogMessage("warn", this.name, aStr);
+
+    let consoleMessage = Cc["@mozilla.org/scripterror;1"].
+                         createInstance(Ci.nsIScriptError);
+    consoleMessage.init(message, null, null, 0, 0, Ci.nsIScriptError.warningFlag,
+                        "component javascript");
+    Services.console.logMessage(consoleMessage);
+
+    if (gDebugLogEnabled)
+      dump("*** " + message + "\n");
+  },
+
+  log: function(aStr) {
+    if (gDebugLogEnabled) {
+      let message = formatLogMessage("log", this.name, aStr);
+      dump("*** " + message + "\n");
+      Services.console.logStringMessage(message);
+    }
+  }
+};
+
+var LogManager = {
+  getLogger: function(aName, aTarget) {
+    let logger = new AddonLogger(aName);
+
+    if (aTarget) {
+      ["error", "warn", "log"].forEach(function(name) {
+        let fname = name.toUpperCase();
+        delete aTarget[fname];
+        aTarget[fname] = function(aStr) {
+          logger[name](aStr);
+        };
+      });
+    }
+
+    return logger;
+  }
+};
+
+try {
+  gDebugLogEnabled = Services.prefs.getBoolPref("extensions.logging.enabled");
+}
+catch (e) {
+}
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -49,45 +49,24 @@ var EXPORTED_SYMBOLS = [ "AddonManager",
 
 // A list of providers to load by default
 const PROVIDERS = [
   "resource://gre/modules/XPIProvider.jsm",
   "resource://gre/modules/PluginProvider.jsm",
   "resource://gre/modules/LightweightThemeManager.jsm"
 ];
 
-/**
- * Logs a debugging message.
- *
- * @param  aStr
- *         The string to log
- */
-function LOG(aStr) {
-  dump("*** addons.manager: " + aStr + "\n");
-}
+["LOG", "WARN", "ERROR"].forEach(function(aName) {
+  this.__defineGetter__(aName, function() {
+    Components.utils.import("resource://gre/modules/AddonLogging.jsm");
 
-/**
- * Logs a warning message.
- *
- * @param  aStr
- *         The string to log
- */
-function WARN(aStr) {
-  LOG(aStr);
-}
-
-/**
- * Logs an error message.
- *
- * @param  aStr
- *         The string to log
- */
-function ERROR(aStr) {
-  LOG(aStr);
-}
+    LogManager.getLogger("addons.manager", this);
+    return this[aName];
+  });
+}, this);
 
 /**
  * Calls a callback method consuming any thrown exception. Any parameters after
  * the callback parameter will be passed to the callback.
  *
  * @param  aCallback
  *         The callback method to call
  */
--- a/toolkit/mozapps/extensions/AddonUpdateChecker.jsm
+++ b/toolkit/mozapps/extensions/AddonUpdateChecker.jsm
@@ -58,45 +58,24 @@ const XMLURI_PARSE_ERROR    = "http://ww
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 // shared code for suppressing bad cert dialogs
 Components.utils.import("resource://gre/modules/CertUtils.jsm");
 
 var gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
            getService(Ci.nsIRDFService);
 
-/**
- * Logs a debug message.
- *
- * @param  aStr
- *         The string to log
- */
-function LOG(aStr) {
-  dump("*** addons.updates: " + aStr + "\n");
-}
+["LOG", "WARN", "ERROR"].forEach(function(aName) {
+  this.__defineGetter__(aName, function() {
+    Components.utils.import("resource://gre/modules/AddonLogging.jsm");
 
-/**
- * Logs a warning message
- *
- * @param  aStr
- *         The string to log
- */
-function WARN(aStr) {
-  LOG(aStr);
-}
-
-/**
- * Logs an error message
- *
- * @param  aStr
- *         The string to log
- */
-function ERROR(aStr) {
-  LOG(str);
-}
+    LogManager.getLogger("addons.updates", this);
+    return this[aName];
+  });
+}, this);
 
 /**
  * A serialisation method for RDF data that produces an identical string
  * for matching RDF graphs.
  * The serialisation is not complete, only assertions stemming from a given
  * resource are included, multiple references to the same resource are not
  * permitted, and the RDF prolog and epilog are not included.
  * RDF Blob and Date literals are not supported.
--- a/toolkit/mozapps/extensions/Makefile.in
+++ b/toolkit/mozapps/extensions/Makefile.in
@@ -68,16 +68,17 @@ EXTRA_PP_COMPONENTS = \
   amWebInstallListener.js \
   $(NULL)
 
 EXTRA_PP_JS_MODULES = \
   AddonManager.jsm \
   XPIProvider.jsm \
   PluginProvider.jsm \
   AddonUpdateChecker.jsm \
+  AddonLogging.jsm \
   $(NULL)
 
 EXTRA_JS_MODULES = \
   LightweightThemeManager.jsm \
   $(NULL)
 
 ifdef ENABLE_TESTS
 DIRS += test
--- a/toolkit/mozapps/extensions/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/PluginProvider.jsm
@@ -40,45 +40,24 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 var EXPORTED_SYMBOLS = [];
 
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
-/**
- * Logs a debug message.
- *
- * @param  aStr
- *         The string to log
- */
-function LOG(aStr) {
-  dump("*** addons.plugins: " + aStr + "\n");
-}
+["LOG", "WARN", "ERROR"].forEach(function(aName) {
+  this.__defineGetter__(aName, function() {
+    Components.utils.import("resource://gre/modules/AddonLogging.jsm");
 
-/**
- * Logs a warning message.
- *
- * @param  aStr
- *         The string to log
- */
-function WARN(aStr) {
-  LOG(aStr);
-}
-
-/**
- * Logs an error message.
- *
- * @param  aStr
- *         The string to log
- */
-function ERROR(aStr) {
-  LOG(aStr);
-}
+    LogManager.getLogger("addons.plugins", this);
+    return this[aName];
+  });
+}, this);
 
 var PluginProvider = {
   // A dictionary mapping IDs to names and descriptions
   plugins: null,
 
   /**
    * Called to get an Addon with a particular ID.
    *
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -127,45 +127,24 @@ const TYPES = {
   locale: 8
 };
 
 /**
  * Valid IDs fit this pattern.
  */
 var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;
 
-/**
- * Logs a debug message.
- *
- * @param  aStr
- *         The string to log
- */
-function LOG(aStr) {
-  dump("*** addons.xpi: " + aStr + "\n");
-}
-
-/**
- * Logs a warning message.
- *
- * @param  str
- *         The string to log
- */
-function WARN(aStr) {
-  LOG(aStr);
-}
-
-/**
- * Logs an error message.
- *
- * @param  str
- *         The string to log
- */
-function ERROR(aStr) {
-  LOG(aStr);
-}
+["LOG", "WARN", "ERROR"].forEach(function(aName) {
+  this.__defineGetter__(aName, function() {
+    Components.utils.import("resource://gre/modules/AddonLogging.jsm");
+
+    LogManager.getLogger("addons.xpi", this);
+    return this[aName];
+  })
+}, this);
 
 /**
  * Gets the currently selected locale for display.
  * @return  the selected locale or "en-US" if none is selected
  */
 function getLocale() {
   if (Prefs.getBoolPref(PREF_MATCH_OS_LOCALE), false)
     return Services.locale.getLocaleComponentForUserAgent();
--- a/toolkit/mozapps/extensions/amWebInstallListener.js
+++ b/toolkit/mozapps/extensions/amWebInstallListener.js
@@ -47,25 +47,24 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
-/**
- * Logs a warning message
- *
- * @param  aStr
- *         The string to log
- */
-function WARN(aStr) {
-  dump("*** addons.weblistener: " + aStr + "\n");
-}
+["LOG", "WARN", "ERROR"].forEach(function(aName) {
+  this.__defineGetter__(aName, function() {
+    Components.utils.import("resource://gre/modules/AddonLogging.jsm");
+
+    LogManager.getLogger("addons.weblistener", this);
+    return this[aName];
+  });
+}, this);
 
 /**
  * Creates a new installer to monitor downloads and prompt to install when
  * ready
  *
  * @param  aWindow
  *         The window that started the installations
  * @param  aUrl
@@ -185,17 +184,16 @@ extWebInstallListener.prototype = {
    */
   onWebInstallBlocked: function(aWindow, aUri, aInstalls) {
     let info = {
       originatingWindow: aWindow,
       originatingURI: aUri,
       installs: aInstalls,
 
       install: function() {
-        dump("Start installs\n");
         new Installer(this.originatingWindow, this.originatingURI, this.installs);
       },
 
       QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallInfo])
     };
     Services.obs.notifyObservers(info, "addon-install-blocked", null);
 
     return false;