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.

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

mercurial