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

source: modules/vI_log.js @ 9d70ec

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

fixed error message logging

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