toolkit/mozapps/extensions/internal/AddonLogging.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const Cc = Components.classes;
     8 const Ci = Components.interfaces;
     9 const Cr = Components.results;
    11 const KEY_PROFILEDIR                  = "ProfD";
    12 const FILE_EXTENSIONS_LOG             = "extensions.log";
    13 const PREF_LOGGING_ENABLED            = "extensions.logging.enabled";
    15 const LOGGER_FILE_PERM                = parseInt("666", 8);
    17 const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
    19 Components.utils.import("resource://gre/modules/FileUtils.jsm");
    20 Components.utils.import("resource://gre/modules/Services.jsm");
    22 this.EXPORTED_SYMBOLS = [ "LogManager" ];
    24 var gDebugLogEnabled = false;
    26 function formatLogMessage(aType, aName, aStr, aException) {
    27   let message = aType.toUpperCase() + " " + aName + ": " + aStr;
    28   if (aException) {
    29     if (typeof aException == "number")
    30       return message + ": " + Components.Exception("", aException).name;
    32     message  = message + ": " + aException;
    33     // instanceOf doesn't work here, let's duck type
    34     if (aException.fileName)
    35       message = message + " (" + aException.fileName + ":" + aException.lineNumber + ")";
    37     if (aException.message == "too much recursion")
    38       dump(message + "\n" + aException.stack + "\n");
    39   }
    40   return message;
    41 }
    43 function getStackDetails(aException) {
    44   // Defensively wrap all this to ensure that failing to get the message source
    45   // doesn't stop the message from being logged
    46   try {
    47     if (aException) {
    48       if (aException instanceof Ci.nsIException) {
    49         return {
    50           sourceName: aException.filename,
    51           lineNumber: aException.lineNumber
    52         };
    53       }
    55       if (typeof aException == "object") {
    56         return {
    57           sourceName: aException.fileName,
    58           lineNumber: aException.lineNumber
    59         };
    60       }
    61     }
    63     let stackFrame = Components.stack.caller.caller.caller;
    64     return {
    65       sourceName: stackFrame.filename,
    66       lineNumber: stackFrame.lineNumber
    67     };
    68   }
    69   catch (e) {
    70     return {
    71       sourceName: null,
    72       lineNumber: 0
    73     };
    74   }
    75 }
    77 function AddonLogger(aName) {
    78   this.name = aName;
    79 }
    81 AddonLogger.prototype = {
    82   name: null,
    84   error: function AddonLogger_error(aStr, aException) {
    85     let message = formatLogMessage("error", this.name, aStr, aException);
    87     let stack = getStackDetails(aException);
    89     let consoleMessage = Cc["@mozilla.org/scripterror;1"].
    90                          createInstance(Ci.nsIScriptError);
    91     consoleMessage.init(message, stack.sourceName, null, stack.lineNumber, 0,
    92                         Ci.nsIScriptError.errorFlag, "component javascript");
    93     Services.console.logMessage(consoleMessage);
    95     // Always dump errors, in case the Console Service isn't listening yet
    96     dump("*** " + message + "\n");
    98     try {
    99       var tstamp = new Date();
   100       var logfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_LOG]);
   101       var stream = Cc["@mozilla.org/network/file-output-stream;1"].
   102                    createInstance(Ci.nsIFileOutputStream);
   103       stream.init(logfile, 0x02 | 0x08 | 0x10, LOGGER_FILE_PERM, 0); // write, create, append
   104       var writer = Cc["@mozilla.org/intl/converter-output-stream;1"].
   105                    createInstance(Ci.nsIConverterOutputStream);
   106       writer.init(stream, "UTF-8", 0, 0x0000);
   107       writer.writeString(tstamp.toLocaleFormat("%Y-%m-%d %H:%M:%S ") +
   108                          message + " at " + stack.sourceName + ":" +
   109                          stack.lineNumber + "\n");
   110       writer.close();
   111     }
   112     catch (e) { }
   113   },
   115   warn: function AddonLogger_warn(aStr, aException) {
   116     let message = formatLogMessage("warn", this.name, aStr, aException);
   118     let stack = getStackDetails(aException);
   120     let consoleMessage = Cc["@mozilla.org/scripterror;1"].
   121                          createInstance(Ci.nsIScriptError);
   122     consoleMessage.init(message, stack.sourceName, null, stack.lineNumber, 0,
   123                         Ci.nsIScriptError.warningFlag, "component javascript");
   124     Services.console.logMessage(consoleMessage);
   126     if (gDebugLogEnabled)
   127       dump("*** " + message + "\n");
   128   },
   130   log: function AddonLogger_log(aStr, aException) {
   131     if (gDebugLogEnabled) {
   132       let message = formatLogMessage("log", this.name, aStr, aException);
   133       dump("*** " + message + "\n");
   134       Services.console.logStringMessage(message);
   135     }
   136   }
   137 };
   139 this.LogManager = {
   140   getLogger: function LogManager_getLogger(aName, aTarget) {
   141     let logger = new AddonLogger(aName);
   143     if (aTarget) {
   144       ["error", "warn", "log"].forEach(function(name) {
   145         let fname = name.toUpperCase();
   146         delete aTarget[fname];
   147         aTarget[fname] = function LogManager_targetName(aStr, aException) {
   148           logger[name](aStr, aException);
   149         };
   150       });
   151     }
   153     return logger;
   154   }
   155 };
   157 var PrefObserver = {
   158   init: function PrefObserver_init() {
   159     Services.prefs.addObserver(PREF_LOGGING_ENABLED, this, false);
   160     Services.obs.addObserver(this, "xpcom-shutdown", false);
   161     this.observe(null, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, PREF_LOGGING_ENABLED);
   162   },
   164   observe: function PrefObserver_observe(aSubject, aTopic, aData) {
   165     if (aTopic == "xpcom-shutdown") {
   166       Services.prefs.removeObserver(PREF_LOGGING_ENABLED, this);
   167       Services.obs.removeObserver(this, "xpcom-shutdown");
   168     }
   169     else if (aTopic == NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) {
   170       try {
   171         gDebugLogEnabled = Services.prefs.getBoolPref(PREF_LOGGING_ENABLED);
   172       }
   173       catch (e) {
   174         gDebugLogEnabled = false;
   175       }
   176     }
   177   }
   178 };
   180 PrefObserver.init();

mercurial