Bug 1455112 - 1. Coalesce multiple log lines into one; r?esawin draft
authorJim Chen <nchen@mozilla.com>
Thu, 19 Apr 2018 14:41:24 -0400
changeset 785158 058dc10619825a2463ac8a9e1f3f7f34560f76d0
parent 785155 803c53daf1c9129ea5afd8f22c8461c7170b2d88
child 785159 a76552cfbfdb1bed18caf33c59a69b95e3432e0a
push id107160
push userbmo:nchen@mozilla.com
push dateThu, 19 Apr 2018 18:45:36 +0000
reviewersesawin
bugs1455112
milestone61.0a1
Bug 1455112 - 1. Coalesce multiple log lines into one; r?esawin Coalesce multiple lines into one line when logging, so that long lines can be split into multiple lines. For example, debug `foo=${foo} bar=${bar}` To actually log multiple lines, use multiple log calls, debug `foo=${foo}` debug `bar=${bar}` MozReview-Commit-ID: 2Wedxkxccm8
mobile/android/modules/geckoview/GeckoViewUtils.jsm
--- a/mobile/android/modules/geckoview/GeckoViewUtils.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewUtils.jsm
@@ -318,78 +318,92 @@ var GeckoViewUtils = {
    *   }
    *
    * An inline format can also be used for logging:
    *
    *   let bar = 42;
    *   do_something(bar); // No log.
    *   do_something(debug.foo = bar); // Output "foo = 42" to the log.
    *
-   * @param tag Name of the Log.jsm logger to forward logs to.
-   * @param scope Scope to add the logging functions to.
+   * @param aTag Name of the Log.jsm logger to forward logs to.
+   * @param aScope Scope to add the logging functions to.
    */
-  initLogging: function(tag, scope) {
+  initLogging: function(aTag, aScope) {
     // Only provide two levels for simplicity.
     // For "info", use "debug" instead.
     // For "error", throw an actual JS error instead.
-    for (const level of ["debug", "warn"]) {
+    for (const level of ["DEBUG", "WARN"]) {
       const log = (strings, ...exprs) =>
           this._log(log.logger, level, strings, exprs);
 
       XPCOMUtils.defineLazyGetter(log, "logger", _ => {
-        const logger = Log.repository.getLogger(tag);
+        const logger = Log.repository.getLogger(aTag);
         logger.parent = this.rootLogger;
         return logger;
       });
 
-      scope[level] = new Proxy(log, {
+      aScope[level.toLowerCase()] = new Proxy(log, {
         set: (obj, prop, value) => obj([prop + " = ", ""], value) || true,
       });
     }
-    return scope;
+    return aScope;
   },
 
   get rootLogger() {
     if (!this._rootLogger) {
       this._rootLogger = Log.repository.getLogger("GeckoView");
       this._rootLogger.addAppender(new Log.AndroidAppender());
     }
     return this._rootLogger;
   },
 
-  _log: function(logger, level, strings, exprs) {
-    if (!Array.isArray(strings)) {
+  _log: function(aLogger, aLevel, aStrings, aExprs) {
+    if (!Array.isArray(aStrings)) {
       const [, file, line] =
           (new Error()).stack.match(/.*\n.*\n.*@(.*):(\d+):/);
-      throw Error(`Expecting template literal: ${level} \`foo \${bar}\``,
+      throw Error(`Expecting template literal: ${aLevel} \`foo \${bar}\``,
                   file, +line);
     }
 
+    if (aLogger.level > Log.Level.Numbers[aLevel]) {
+      // Log disabled.
+      return;
+    }
+
     // Do some GeckoView-specific formatting:
-    // 1) Heuristically format flags as hex.
-    // 2) Heuristically format nsresult as string name or hex.
-    for (let i = 0; i < exprs.length; i++) {
-      const expr = exprs[i];
+    // * Remove newlines so long log lines can be put into multiple lines:
+    //   debug `foo=${foo}
+    //          bar=${bar}`;
+    const strs = Array.from(aStrings);
+    const regex = /\n\s*/g;
+    for (let i = 0; i < strs.length; i++) {
+      strs[i] = strs[i].replace(regex, " ");
+    }
+
+    // * Heuristically format flags as hex.
+    // * Heuristically format nsresult as string name or hex.
+    for (let i = 0; i < aExprs.length; i++) {
+      const expr = aExprs[i];
       switch (typeof expr) {
         case "number":
-          if (expr > 0 && /\ba?[fF]lags?[\s=:]+$/.test(strings[i])) {
+          if (expr > 0 && /\ba?[fF]lags?[\s=:]+$/.test(strs[i])) {
             // Likely a flag; display in hex.
-            exprs[i] = `0x${expr.toString(0x10)}`;
-          } else if (expr >= 0 && /\b(a?[sS]tatus|rv)[\s=:]+$/.test(strings[i])) {
+            aExprs[i] = `0x${expr.toString(0x10)}`;
+          } else if (expr >= 0 && /\b(a?[sS]tatus|rv)[\s=:]+$/.test(strs[i])) {
             // Likely an nsresult; display in name or hex.
-            exprs[i] = `0x${expr.toString(0x10)}`;
+            aExprs[i] = `0x${expr.toString(0x10)}`;
             for (const name in Cr) {
               if (expr === Cr[name]) {
-                exprs[i] = name;
+                aExprs[i] = name;
                 break;
               }
             }
           }
           break;
       }
     }
 
-    return logger[level](strings, ...exprs);
+    return aLogger[aLevel.toLowerCase()](strs, ...aExprs);
   },
 };
 
 XPCOMUtils.defineLazyGetter(GeckoViewUtils, "IS_PARENT_PROCESS", _ =>
     Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT);