2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
15 # The Original Code is the Extension Manager.
17 # The Initial Developer of the Original Code is
18 # the Mozilla Foundation.
19 # Portions created by the Initial Developer are Copyright (C) 2010
20 # the Initial Developer. All Rights Reserved.
23 # Dave Townsend <dtownsend@oxymoronical.com>
25 # Alternatively, the contents of this file may be used under the terms of
26 # either the GNU General Public License Version 2 or later (the "GPL"), or
27 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 # in which case the provisions of the GPL or the LGPL are applicable instead
29 # of those above. If you wish to allow use of your version of this file only
30 # under the terms of either the GPL or the LGPL, and not to allow others to
31 # use your version of this file under the terms of the MPL, indicate your
32 # decision by deleting the provisions above and replace them with the notice
33 # and other provisions required by the GPL or the LGPL. If you do not delete
34 # the provisions above, a recipient may use your version of this file under
35 # the terms of any one of the MPL, the GPL or the LGPL.
37 # ***** END LICENSE BLOCK *****
40 const Cc = Components.classes;
41 const Ci = Components.interfaces;
42 const Cr = Components.results;
44 const KEY_PROFILEDIR = "ProfD";
45 const FILE_EXTENSIONS_LOG = "extensions.log";
46 const PREF_LOGGING_ENABLED = "extensions.logging.enabled";
48 const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
50 Components.utils.import("resource://gre/modules/FileUtils.jsm");
51 Components.utils.import("resource://gre/modules/Services.jsm");
53 var EXPORTED_SYMBOLS = [ "LogManager" ];
55 var gDebugLogEnabled = false;
57 function formatLogMessage(aType, aName, aStr, aException) {
58 let message = aType.toUpperCase() + " " + aName + ": " + aStr;
60 return message + ": " + aException;
64 function getStackDetails(aException) {
65 // Defensively wrap all this to ensure that failing to get the message source
66 // doesn't stop the message from being logged
69 if (aException instanceof Ci.nsIException) {
71 sourceName: aException.filename,
72 lineNumber: aException.lineNumber
77 sourceName: aException.fileName,
78 lineNumber: aException.lineNumber
82 let stackFrame = Components.stack.caller.caller.caller;
84 sourceName: stackFrame.filename,
85 lineNumber: stackFrame.lineNumber
96 function AddonLogger(aName) {
100 AddonLogger.prototype = {
103 error: function(aStr, aException) {
104 let message = formatLogMessage("error", this.name, aStr, aException);
106 let stack = getStackDetails(aException);
108 let consoleMessage = Cc["@mozilla.org/scripterror;1"].
109 createInstance(Ci.nsIScriptError);
110 consoleMessage.init(message, stack.sourceName, null, stack.lineNumber, 0,
111 Ci.nsIScriptError.errorFlag, "component javascript");
112 Services.console.logMessage(consoleMessage);
114 if (gDebugLogEnabled)
115 dump("*** " + message + "\n");
118 var tstamp = new Date();
119 var logfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_LOG]);
120 var stream = Cc["@mozilla.org/network/file-output-stream;1"].
121 createInstance(Ci.nsIFileOutputStream);
122 stream.init(logfile, 0x02 | 0x08 | 0x10, 0666, 0); // write, create, append
123 var writer = Cc["@mozilla.org/intl/converter-output-stream;1"].
124 createInstance(Ci.nsIConverterOutputStream);
125 writer.init(stream, "UTF-8", 0, 0x0000);
126 writer.writeString(tstamp.toLocaleFormat("%Y-%m-%d %H:%M:%S ") +
127 message + " at " + stack.sourceName + ":" +
128 stack.lineNumber + "\n");
134 warn: function(aStr, aException) {
135 let message = formatLogMessage("warn", this.name, aStr, aException);
137 let stack = getStackDetails(aException);
139 let consoleMessage = Cc["@mozilla.org/scripterror;1"].
140 createInstance(Ci.nsIScriptError);
141 consoleMessage.init(message, stack.sourceName, null, stack.lineNumber, 0,
142 Ci.nsIScriptError.warningFlag, "component javascript");
143 Services.console.logMessage(consoleMessage);
145 if (gDebugLogEnabled)
146 dump("*** " + message + "\n");
149 log: function(aStr, aException) {
150 if (gDebugLogEnabled) {
151 let message = formatLogMessage("log", this.name, aStr, aException);
152 dump("*** " + message + "\n");
153 Services.console.logStringMessage(message);
159 getLogger: function(aName, aTarget) {
160 let logger = new AddonLogger(aName);
163 ["error", "warn", "log"].forEach(function(name) {
164 let fname = name.toUpperCase();
165 delete aTarget[fname];
166 aTarget[fname] = function(aStr, aException) {
167 logger[name](aStr, aException);
178 Services.prefs.addObserver(PREF_LOGGING_ENABLED, this, false);
179 Services.obs.addObserver(this, "xpcom-shutdown", false);
180 this.observe(null, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, PREF_LOGGING_ENABLED);
183 observe: function(aSubject, aTopic, aData) {
184 if (aTopic == "xpcom-shutdown") {
185 Services.prefs.removeObserver(PREF_LOGGING_ENABLED, this);
186 Services.obs.removeObserver(this, "xpcom-shutdown");
188 else if (aTopic == NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) {
190 gDebugLogEnabled = Services.prefs.getBoolPref(PREF_LOGGING_ENABLED);
193 gDebugLogEnabled = false;