This is just some static backup of the original site, don't expect every link to work!

source: modules/vI_log.js @ 509348

ng_0.9
Last change on this file since 509348 was 509348, checked in by rene <rene@…>, 8 years ago

code formatting (no code changes)

  • Property mode set to 100644
File size: 14.7 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2    This program is free software; you can redistribute it and/or modify
3    it under the terms of the GNU General Public License as published by
4    the Free Software Foundation; either version 2 of the License, or
5    (at your option) any later version.
6
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15
16    The Original Code is the Virtual Identity Extension.
17
18    The Initial Developer of the Original Code is Rene Ejury.
19    Portions created by the Initial Developer are Copyright (C) 2007
20    the Initial Developer. All Rights Reserved.
21
22    Contributor(s): Jonathan Protzenko <jonathan.protzenko@gmail.com>
23 * ***** END LICENSE BLOCK ***** */
24
25var EXPORTED_SYMBOLS = ["setupLogging", "dumpCallStack", "MyLog", "Colors",
26  "clearDebugOutput", "notificationOverflow",
27  "SmartReplyNotification", "StorageNotification", "GetHeaderNotification"
28]
29
30const {
31  classes: Cc,
32  interfaces: Ci,
33  utils: Cu,
34  results: Cr
35} = Components;
36Cu.import("resource:///modules/gloda/log4moz.js");
37Cu.import("resource://v_identity/vI_prefs.js");
38Cu.import("resource://gre/modules/Services.jsm");
39
40/** ******************************************************************************************************
41 * _errorConsoleTunnel was copied and adapted mozilla test-function
42 * mailnews/test/resources/logHelper.js
43 */
44/**
45 * Tunnel nsIScriptErrors that show up on the error console to Log4Moz.  We could
46 *  send everything but I think only script errors are likely of much concern.
47 *  Also, this nicely avoids infinite recursions no matter what you do since
48 *  what we publish is not going to end up as an nsIScriptError.
49 *
50 * This is based on my (asuth') exmmad extension.
51 */
52let _errorConsoleTunnel = {
53  initialize: function () {
54    Services.console.registerListener(this);
55    // we need to unregister our listener at shutdown if we don't want explosions
56    Services.obs.addObserver(this, "quit-application", false);
57  },
58
59  shutdown: function () {
60    try {
61      Services.console.unregisterListener(this);
62      Services.obs.removeObserver(this, "quit-application");
63    } catch (e) {};
64  },
65
66  observe: function (aMessage, aTopic, aData) {
67    if (aTopic == "quit-application") {
68      this.shutdown();
69      return;
70    }
71
72    try {
73      if ((aMessage instanceof Components.interfaces.nsIScriptError) &&
74        (aMessage.sourceName.contains("v_identity")) &&
75        (!aMessage.errorMessage.contains("Error console says"))) {
76        MyLog.info("Error console says" + aMessage);
77      }
78    } catch (ex) {
79      // This is to avoid pathological error loops.  we definitely do not
80      // want to propagate an error here.
81    }
82  }
83};
84/** ******************************************************************************************************/
85
86// different formatters for the log output
87// Basic formatter that only prints the message / used for NotificationBox
88function NotificationFormatter() {}
89NotificationFormatter.prototype = {
90  __proto__: Log4Moz.Formatter.prototype,
91  format: function NF_format(message) {
92    // The trick below prevents errors further down because mo is null or
93    //  undefined.
94    let messageString = [
95      ("" + mo) for each([, mo] in Iterator(message.messageObjects))
96    ].join(" ");
97    return messageString;
98  }
99};
100
101// New formatter that only display's the source and message
102function NewFormatter() {}
103NewFormatter.prototype = {
104  __proto__: Log4Moz.Formatter.prototype,
105
106  format: function NF_format(message) {
107    // The trick below prevents errors further down because mo is null or
108    //  undefined.
109    let messageString = [
110      ("" + mo) for each([, mo] in Iterator(message.messageObjects))
111    ].join(" ");
112    return message.loggerName.replace("virtualIdentity.", "") + ":\t" + messageString + "\n";
113  }
114};
115
116/*
117 * DebugOutputAppender
118 * Logs to DebugOutput
119 */
120function DebugOutputAppender(formatter) {
121  this._name = "DebugOutputAppender";
122  Log4Moz.Appender.call(this, formatter);
123}
124DebugOutputAppender.prototype = {
125  __proto__: Log4Moz.Appender.prototype,
126
127  currentWindow: null,
128
129  doAppend: function DOApp_doAppend(message) {
130    if (!vIprefs.get("debug_notification")) return;
131    this.currentWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
132      .getService(Ci.nsIWindowMediator)
133      .getMostRecentWindow(null);
134    var obj_debugBox = this.currentWindow.document.getElementById("virtualIdentityExtension_debugBox");
135    if (obj_debugBox)
136      obj_debugBox.dump(message);
137  }
138}
139
140/*
141 * NotificationOutputAppender
142 * Logs to NotificationBox
143 */
144function NotificationOutputAppender(formatter) {
145  this._name = "NotificationOutputAppender";
146  Log4Moz.Appender.call(this, formatter);
147}
148NotificationOutputAppender.prototype = {
149  __proto__: Log4Moz.Appender.prototype,
150
151  currentWindow: null,
152
153  doAppend: function DOApp_doAppend(message) {
154    this.currentWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
155      .getService(Ci.nsIWindowMediator)
156      .getMostRecentWindow(null);
157    if (this.currentWindow)
158      this.addNote(message);
159  },
160
161  timer: null,
162
163  clearNote: function (self) {
164    if (self.timer)
165      self.currentWindow.clearTimeout(self.timer);
166    self.timer = null;
167    let obj_notificationBox = self.currentWindow.document.getElementById("virtualIdentityExtension_vINotification");
168    if (obj_notificationBox)
169      obj_notificationBox.removeAllNotifications(true);
170  },
171
172  addNote: function (note) {
173    let obj_notificationBox = this.currentWindow.document.getElementById("virtualIdentityExtension_vINotification");
174    if (!obj_notificationBox)
175      return;
176    let oldNotification = obj_notificationBox.currentNotification
177    let newLabel = (oldNotification) ? oldNotification.label + note : note;
178    this.clearNote(this);
179    obj_notificationBox.appendNotification(newLabel, "", "chrome://messenger/skin/icons/flag.png");
180
181    if (vIprefs.get("notification_timeout") != 0)
182      this.timer =
183      this.currentWindow.setTimeout(this.clearNote,
184        vIprefs.get("notification_timeout") * 1000, this);
185  }
186}
187
188
189function notificationOverflow(elem) {
190  let currentWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
191    .getService(Ci.nsIWindowMediator)
192    .getMostRecentWindow(null);
193  // height will be cut off from messagepane (in 3pane window)
194  let objMessagepane = currentWindow.document.getElementById("messagepane");
195  let maxHeight = (objMessagepane) ? parseInt(objMessagepane.boxObject.height / 2) + 1 : null;
196  if (maxHeight < 60) maxHeight = 60; // set a minimum size, if to small scrollbars are hidden
197  let tooBig = (maxHeight) ? (elem.inputField.scrollHeight > maxHeight) : false;
198  let newHeight = (tooBig) ? maxHeight : elem.inputField.scrollHeight;
199  elem.height = newHeight;
200  // give the box a frame if it is to big
201  if (tooBig)
202    var notificationBox = currentWindow.document.getElementById("virtualIdentityExtension_vINotificationTextbox");
203  if (notificationBox) notificationBox.setAttribute("class", "plain border");
204}
205
206
207function setupLogging(name) {
208  let Log = Log4Moz.repository.getLogger(name);
209  return Log;
210}
211
212
213function setupFullLogging(name) {
214  let myBasicFormatter = new Log4Moz.BasicFormatter();
215  let myNewFormatter = new NewFormatter();
216  let Log = Log4Moz.repository.getLogger(name);
217
218  // Loggers are hierarchical, lowering this log level will affect all output
219  let root = Log;
220  root.level = Log4Moz.Level["All"];
221
222  if (vIprefs.get("debug_notification")) {
223    // A console appender outputs to the JS Error Console
224    let capp = new Log4Moz.ConsoleAppender(myBasicFormatter);
225    capp.level = Log4Moz.Level["Warn"];
226    root.addAppender(capp);
227
228    // A dump appender outputs to standard out
229    let dapp = new Log4Moz.DumpAppender(myBasicFormatter);
230    dapp.level = Log4Moz.Level["All"];
231    root.addAppender(dapp);
232  }
233
234  // A dump appender outputs to Debug Output Box
235  let doapp = new DebugOutputAppender(myNewFormatter);
236  doapp.level = Log4Moz.Level["All"];
237  root.addAppender(doapp);
238
239
240  return Log;
241}
242
243function dumpCallStack(e) {
244  let frame = (e && e.stack) ? e.stack : Components.stack;
245  while (frame) {
246    MyLog.debug(frame);
247    frame = frame.caller;
248  }
249}
250
251let Colors = {
252  yellow: "\u001b[01;33m",
253  blue: "\u001b[01;36m",
254  red: "\u001b[01;31m",
255  default: "\u001b[00m",
256}
257
258function clearDebugOutput() {
259  let currentWindow = Cc["@mozilla.org/appshell/window-mediator;1"]
260    .getService(Ci.nsIWindowMediator)
261    .getMostRecentWindow(null);
262  let obj_debugBox = currentWindow.document.getElementById("virtualIdentityExtension_debugBox");
263  if (obj_debugBox)
264    obj_debugBox.clear();
265  let obj_notificationBox = currentWindow.document.getElementById("virtualIdentityExtension_vINotification");
266  if (obj_notificationBox)
267    obj_notificationBox.removeAllNotifications(true);
268}
269
270function _startFileLogging() {
271  var file = Components.classes["@mozilla.org/file/local;1"]
272    .createInstance(Components.interfaces.nsIFile);
273
274  var defaultPath = Components.classes["@mozilla.org/file/directory_service;1"]
275    .getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile).path;
276
277  try {
278    file.initWithPath(vIprefs.get("debug_to_file_path"));
279  } catch (NS_ERROR_FILE_UNRECOGNIZED_PATH) {
280    try {
281      // try linux delimiter
282      file.initWithPath(defaultPath + "/" + vIprefs.get("debug_to_file_path"));
283    } catch (NS_ERROR_FILE_UNRECOGNIZED_PATH) {
284      try {
285        // use windows delimiter
286        file.initWithPath(defaultPath + "\\" + vIprefs.get("debug_to_file_path"));
287      } catch (NS_ERROR_FILE_UNRECOGNIZED_PATH) {
288        dump("FileAppender not available for logging: set logging file first\n");
289      };
290    }
291  }
292  // A dump appender outputs to File
293  DebugFileAppender = new Log4Moz.FileAppender(file);
294
295  if (DebugFileAppender.doAppend.toString().indexOf("this._fos().write") > -1) {
296    dump("*** hot-fixing FileAppender Logging Bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1082551)\n");
297    // there is a bug in original implementation of doAppend, fix the issue
298    DebugFileAppender.doAppend = function FApp_doAppend(message) {
299      if (message === null || message.length <= 0)
300        return;
301      try {
302        this._fos.write(message, message.length);
303      } catch (e) {
304        dump("Error writing file:\n" + e);
305      }
306    };
307  }
308
309  DebugFileAppender.level = Log4Moz.Level["All"];
310  Log4Moz.repository.rootLogger.addAppender(DebugFileAppender);
311
312  _errorConsoleTunnel.initialize();
313}
314
315function _stopFileLogging() {
316  if (DebugFileAppender)
317    Log4Moz.repository.rootLogger.removeAppender(DebugFileAppender);
318  _errorConsoleTunnel.shutdown();
319}
320
321function _dump_extension_list() {
322  Components.utils.import("resource://gre/modules/AddonManager.jsm");
323  AddonManager.getAllAddons(function (addons) {
324    var strings = addons.map(function (addon) {
325      return (addon.userDisabled || addon.appDisabled ? "" : "addon: " + addon.name + " " + addon.version + "\n");
326    });
327    MyLog.info("\n--------------------------------------------------------------------------------\n" +
328      strings.join("") +
329      "--------------------------------------------------------------------------------");
330  });
331}
332
333function _dump_info_block() {
334  // add some information about the mail-client and the extensions installed
335  if ("@mozilla.org/xre/app-info;1" in Components.classes) {
336    var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
337      .getService(Components.interfaces.nsIXULAppInfo);
338    var protohandler = Components.classes["@mozilla.org/network/protocol;1?name=http"]
339      .getService(Components.interfaces.nsIHttpProtocolHandler);
340    MyLog.info("start logging for new session\n--------------------------------------------------------------------------------\n" +
341      appInfo.name + " " + appInfo.version + " (" + appInfo.appBuildID + "; " + protohandler.oscpu + ")\n" +
342      "--------------------------------------------------------------------------------");
343  } else
344    MyLog.info("\n--------------------------------------------------------------------------------\n" +
345      "mail-client seems not supported by Virtual Identity Extension\n" +
346      "--------------------------------------------------------------------------------");
347
348  _dump_extension_list();
349}
350
351function UpdateFileLoggerPath() {
352  dump("UpdateFileLoggerPath\n");
353  if (vIprefs.get("debug_to_file")) {
354    _stopFileLogging();
355    _startFileLogging();
356    _dump_info_block();
357  }
358}
359
360function UpdateFileLogger() {
361  if (vIprefs.get("debug_to_file")) {
362    _startFileLogging();
363    _dump_info_block();
364  } else {
365    _stopFileLogging();
366  }
367}
368
369function UpdateSmartReplyNotification() {
370  if (vIprefs.get("smart_reply_notification")) {
371    SmartReplyAppender = new NotificationOutputAppender(myNotificationFormatter);
372    SmartReplyAppender.level = Log4Moz.Level["All"];
373    SmartReplyNotification.addAppender(SmartReplyAppender);
374  } else {
375    SmartReplyNotification.removeAppender(SmartReplyAppender);
376  }
377}
378
379function UpdateStorageNotification() {
380  if (vIprefs.get("storage_notification")) {
381    StorageAppender = new NotificationOutputAppender(myNotificationFormatter);
382    StorageAppender.level = Log4Moz.Level["All"];
383    StorageNotification.addAppender(StorageAppender);
384  } else {
385    StorageNotification.removeAppender(StorageAppender);
386  }
387}
388
389function UpdateGetHeaderNotification() {
390  if (vIprefs.get("get_header_notification")) {
391    GetHeaderAppender = new NotificationOutputAppender(myNotificationFormatter);
392    GetHeaderAppender.level = Log4Moz.Level["All"];
393    GetHeaderNotification.addAppender(GetHeaderAppender);
394  } else {
395    GetHeaderNotification.removeAppender(GetHeaderAppender);
396  }
397}
398
399let logRoot = "virtualIdentity";
400let MyLog = setupFullLogging(logRoot);
401
402let myNotificationFormatter = new NotificationFormatter();
403
404let DebugFileAppender = null;
405
406let SmartReplyAppender;
407let SmartReplyNotification = Log4Moz.repository.getLogger("virtualIdentity.SmartReply");
408
409let StorageAppender;
410let StorageNotification = Log4Moz.repository.getLogger("virtualIdentity.StorageNotification");
411
412let GetHeaderAppender;
413let GetHeaderNotification = Log4Moz.repository.getLogger("virtualIdentity.GetHeaderNotification");
414
415UpdateSmartReplyNotification();
416UpdateStorageNotification();
417UpdateGetHeaderNotification();
418UpdateFileLogger();
419
420vIprefs.addObserver("smart_reply_notification", UpdateSmartReplyNotification, this);
421vIprefs.addObserver("storage_notification", UpdateStorageNotification, this);
422vIprefs.addObserver("get_header_notification", UpdateGetHeaderNotification, this);
423vIprefs.addObserver("debug_to_file", UpdateFileLogger, this);
424vIprefs.addObserver("debug_to_file_path", UpdateFileLoggerPath, this);
Note: See TracBrowser for help on using the repository browser.