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

source: modules/vI_log.js

ng_0.9 0.10.3
Last change on this file was 13e2d2, checked in by rene <rene@…>, 4 years ago

changed logging

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