Bug 1464469 - Shorthands for setting up Marionette logger. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Wed, 06 Jun 2018 14:32:18 +0100
changeset 808099 374124504debed7ccbf40b17129156a0e48ca2bc
parent 808097 f804cc575bba9c6dcb4e3770f7dafe4d8934e73c
child 808100 096a3a9a06fe9f22b8297fa4c9800dd9aff6d12f
child 808104 a1e2a8486516fb98ec14dd25a4f2f8d5b308fc71
push id113275
push userbmo:ato@sny.no
push dateMon, 18 Jun 2018 12:16:14 +0000
reviewerswhimboo
bugs1464469
milestone62.0a1
Bug 1464469 - Shorthands for setting up Marionette logger. r?whimboo This patch generalises logger setup and access by providing one interface with specialised implementations for the main- and child processes. This will mean we can get rid of ad-hoc logger setup in testing/marionette/components/marionette.js and testing/marionette/listener.js. In the case for the component file, the log level and the stdout dump appender is set up when you request the logger. The same is true when requesting the logger in a child process, but it will additionally request the log level from the main process. Usage: const {Log} = ChromeUtils.import("chrome://marionette/content/log.js", {}); let log = Log.get(); MozReview-Commit-ID: 8Ha5FSaoGXp
testing/marionette/doc/internals/log.rst
testing/marionette/jar.mn
testing/marionette/log.js
testing/marionette/prefs.js
new file mode 100644
--- /dev/null
+++ b/testing/marionette/doc/internals/log.rst
@@ -0,0 +1,4 @@
+log module
+==========
+.. js:autoclass:: Log
+  :members:
--- a/testing/marionette/jar.mn
+++ b/testing/marionette/jar.mn
@@ -19,16 +19,17 @@ marionette.jar:
   content/error.js (error.js)
   content/evaluate.js (evaluate.js)
   content/event.js  (event.js)
   content/format.js (format.js)
   content/interaction.js (interaction.js)
   content/l10n.js (l10n.js)
   content/legacyaction.js (legacyaction.js)
   content/listener.js (listener.js)
+  content/log.js (log.js)
   content/message.js (message.js)
   content/modal.js (modal.js)
   content/navigate.js (navigate.js)
   content/packets.js (packets.js)
   content/prefs.js (prefs.js)
   content/proxy.js (proxy.js)
   content/reftest.js (reftest.js)
   content/reftest.xul (reftest.xul)
new file mode 100644
--- /dev/null
+++ b/testing/marionette/log.js
@@ -0,0 +1,94 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+const StdLog = ChromeUtils.import("resource://gre/modules/Log.jsm", {}).Log;
+
+const {MarionettePrefs} = ChromeUtils.import("chrome://marionette/content/prefs.js", {});
+
+this.EXPORTED_SYMBOLS = ["Log"];
+
+const isChildProcess = Services.appinfo.processType ==
+    Services.appinfo.PROCESS_TYPE_CONTENT;
+
+/**
+ * Shorthand for accessing the Marionette logging repository.
+ *
+ * Using this class to retrieve the `Log.jsm` repository for
+ * Marionette will ensure the logger is set up correctly with the
+ * appropriate stdout dumper and with the correct log level.
+ *
+ * Unlike `Log.jsm` this logger is E10s safe, meaning repository
+ * configuration for appenders and logging levels are communicated
+ * across processes.
+ *
+ * @name Log
+ */
+class MarionetteLog {
+  /**
+   * Obtain the `Marionette` logger.
+   *
+   * The returned {@link Logger} instance is shared among all
+   * callers in the same process.
+   *
+   * @return {Logger}
+   */
+  static get() {
+    let logger = StdLog.repository.getLogger("Marionette");
+    if (logger.ownAppenders.length == 0) {
+      logger.addAppender(new StdLog.DumpAppender());
+    }
+    logger.level = MarionettePrefs.logLevel;
+    return logger;
+  }
+
+  /**
+   * Obtain a logger that logs all messages with a prefix.
+   *
+   * Unlike {@link LoggerRepository.getLoggerWithMessagePrefix()}
+   * this function will ensure invoke {@link #get()} first to ensure
+   * the logger has been properly set up first.
+   *
+   * This returns a new object with a prototype chain that chains
+   * up the original {@link Logger} instance.  The new prototype has
+   * log functions that prefix `prefix` to each message.
+   *
+   * @param {string} prefix
+   *     String to prefix each logged message with.
+   *
+   * @return {Proxy.<Logger>}
+   */
+  static getWithPrefix(prefix) {
+    this.get();
+    return StdLog.repository.getLoggerWithMessagePrefix("Marionette", `[${prefix}] `);
+  }
+}
+
+class ParentProcessLog extends MarionetteLog {
+  static get() {
+    let logger = super.get();
+    Services.ppmm.initialProcessData["Marionette:Log"] = {level: logger.level};
+    return logger;
+  }
+}
+
+class ChildProcessLog extends MarionetteLog {
+  static get() {
+    let logger = super.get();
+
+    // Log.jsm is not e10s compatible (see https://bugzil.la/1411513)
+    // so loading it in a new child process will reset the repository config
+    logger.level = Services.cpmm.initialProcessData["Marionette:Log"] || StdLog.Level.Info;
+
+    return logger;
+  }
+}
+
+if (isChildProcess) {
+  this.Log = ChildProcessLog;
+} else {
+  this.Log = ParentProcessLog;
+}
--- a/testing/marionette/prefs.js
+++ b/testing/marionette/prefs.js
@@ -121,24 +121,16 @@ class Branch {
  * potentially malformed input.  In the `marionette.log.level` example,
  * `DEBUG`, `Debug`, and `dEbUg` are considered valid inputs and the
  * `LogBranch` specialisation deserialises the string value to the
  * correct `Log.Level` by sanitising the input data first.
  *
  * A further complication is that we cannot rely on `Preferences.jsm`
  * in Marionette.  See https://bugzilla.mozilla.org/show_bug.cgi?id=1357517
  * for further details.
- *
- * Usage::
- *
- *     ChromeUtils.import("resource://gre/modules/Log.jsm");
- *     const {MarionettePrefs} = ChromeUtils.import("chrome://marionette/content/prefs.js", {});
- *
- *     const log = Log.repository.getLogger("Marionette");
- *     log.level = MarionettePrefs.log.level;
  */
 class MarionetteBranch extends Branch {
   constructor(branch = "marionette.") {
     super(branch);
   }
 
   /**
    * The `marionette.enabled` preference.  When it returns true,