Bug 1425987 - part 2: Cleanup Sync logging by rationalizing preference management. r=tcsc
authorMark Hammond <mhammond@skippinet.com.au>
Tue, 19 Dec 2017 09:48:31 +1100
changeset 397073 38ff4596320bdb94126f95d97e108c4c4a281817
parent 397072 ac05441603b174d6c1eedbfab2c2d4400fc9ea84
child 397074 434687d35ab855b78722be71e881920b75c951a7
push id33123
push userncsoregi@mozilla.com
push dateThu, 21 Dec 2017 10:00:47 +0000
treeherdermozilla-central@06a19fbe2581 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcsc
bugs1425987
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1425987 - part 2: Cleanup Sync logging by rationalizing preference management. r=tcsc MozReview-Commit-ID: CQ1vhahnQbc
services/common/hawkrequest.js
services/common/tokenserverclient.js
services/fxaccounts/FxAccountsCommon.js
services/sync/modules/SyncedTabs.jsm
services/sync/modules/addonsreconciler.js
services/sync/modules/browserid_identity.js
services/sync/modules/engines.js
services/sync/modules/policies.js
services/sync/modules/resource.js
services/sync/modules/service.js
services/sync/modules/stages/declined.js
services/sync/modules/stages/enginesync.js
services/sync/modules/status.js
services/sync/modules/telemetry.js
services/sync/services-sync.js
testing/tps/tps/testrunner.py
toolkit/components/places/PlacesSyncUtils.jsm
--- a/services/common/hawkrequest.js
+++ b/services/common/hawkrequest.js
@@ -146,17 +146,17 @@ this.deriveHawkCredentials = function de
 // With hawk request, we send the user's accepted-languages with each request.
 // To keep the number of times we read this pref at a minimum, maintain the
 // preference in a stateful object that notices and updates itself when the
 // pref is changed.
 this.Intl = function Intl() {
   // We won't actually query the pref until the first time we need it
   this._accepted = "";
   this._everRead = false;
-  this._log = Log.repository.getLogger("Services.common.RESTRequest");
+  this._log = Log.repository.getLogger("Services.Common.RESTRequest");
   this._log.level = Log.Level[Prefs.get("log.logger.rest.request")];
   this.init();
 };
 
 this.Intl.prototype = {
   init() {
     Services.prefs.addObserver("intl.accept_languages", this);
   },
--- a/services/common/tokenserverclient.js
+++ b/services/common/tokenserverclient.js
@@ -143,19 +143,18 @@ TokenServerClientServerError.prototype._
  *
  *  - The server sends a JSON response on error. The client does not currently
  *    parse this. It might be convenient if it did.
  *  - Currently most non-200 status codes are rolled into one error type. It
  *    might be helpful if callers had a richer API that communicated who was
  *    at fault (e.g. differentiating a 503 from a 401).
  */
 this.TokenServerClient = function TokenServerClient() {
-  this._log = Log.repository.getLogger("Common.TokenServerClient");
-  let level = Services.prefs.getCharPref(PREF_LOG_LEVEL, "Debug");
-  this._log.level = Log.Level[level];
+  this._log = Log.repository.getLogger("Services.Common.TokenServerClient");
+  this._log.manageLevelFromPref(PREF_LOG_LEVEL);
 };
 TokenServerClient.prototype = {
   /**
    * Logger instance.
    */
   _log: null,
 
   /**
--- a/services/fxaccounts/FxAccountsCommon.js
+++ b/services/fxaccounts/FxAccountsCommon.js
@@ -8,52 +8,26 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 
 // loglevel should be one of "Fatal", "Error", "Warn", "Info", "Config",
 // "Debug", "Trace" or "All". If none is specified, "Debug" will be used by
 // default.  Note "Debug" is usually appropriate so that when this log is
 // included in the Sync file logs we get verbose output.
 const PREF_LOG_LEVEL = "identity.fxaccounts.loglevel";
-// The level of messages that will be dumped to the console.  If not specified,
-// "Error" will be used.
-const PREF_LOG_LEVEL_DUMP = "identity.fxaccounts.log.appender.dump";
 
 // A pref that can be set so "sensitive" information (eg, personally
 // identifiable info, credentials, etc) will be logged.
 const PREF_LOG_SENSITIVE_DETAILS = "identity.fxaccounts.log.sensitive";
 
 var exports = Object.create(null);
 
 XPCOMUtils.defineLazyGetter(exports, "log", function() {
   let log = Log.repository.getLogger("FirefoxAccounts");
-  // We set the log level to debug, but the default dump appender is set to
-  // the level reflected in the pref.  Other code that consumes FxA may then
-  // choose to add another appender at a different level.
-  log.level = Log.Level.Debug;
-  let appender = new Log.DumpAppender();
-  appender.level = Log.Level.Error;
-
-  log.addAppender(appender);
-  try {
-    // The log itself.
-    let level =
-      Services.prefs.getPrefType(PREF_LOG_LEVEL) == Ci.nsIPrefBranch.PREF_STRING
-      && Services.prefs.getCharPref(PREF_LOG_LEVEL);
-    log.level = Log.Level[level] || Log.Level.Debug;
-
-    // The appender.
-    level =
-      Services.prefs.getPrefType(PREF_LOG_LEVEL_DUMP) == Ci.nsIPrefBranch.PREF_STRING
-      && Services.prefs.getCharPref(PREF_LOG_LEVEL_DUMP);
-    appender.level = Log.Level[level] || Log.Level.Error;
-  } catch (e) {
-    log.error(e);
-  }
-
+  log.manageLevelFromPref(PREF_LOG_LEVEL);
   return log;
 });
 
 // A boolean to indicate if personally identifiable information (or anything
 // else sensitive, such as credentials) should be logged.
 XPCOMUtils.defineLazyGetter(exports, "logPII", function() {
   try {
     return Services.prefs.getBoolPref(PREF_LOG_SENSITIVE_DETAILS);
--- a/services/sync/modules/SyncedTabs.jsm
+++ b/services/sync/modules/SyncedTabs.jsm
@@ -35,27 +35,21 @@ function escapeRegExp(string) {
 // of a regularly scheduled sync. The intent is that consumers just listen
 // for this notification and update their UI in response.
 const TOPIC_TABS_CHANGED = "services.sync.tabs.changed";
 
 // The interval, in seconds, before which we consider the existing list
 // of tabs "fresh enough" and don't force a new sync.
 const TABS_FRESH_ENOUGH_INTERVAL = 30;
 
-let log = Log.repository.getLogger("Sync.RemoteTabs");
-// A new scope to do the logging thang...
-(function() {
-  let level = Preferences.get("services.sync.log.logger.tabs");
-  if (level) {
-    let appender = new Log.DumpAppender();
-    log.level = appender.level = Log.Level[level] || Log.Level.Debug;
-    log.addAppender(appender);
-  }
-})();
-
+XPCOMUtils.defineLazyGetter(this, "log", function() {
+  let log = Log.repository.getLogger("Sync.RemoteTabs");
+  log.manageLevelFromPref("services.sync.log.logger.tabs");
+  return log;
+});
 
 // A private singleton that does the work.
 let SyncedTabsInternal = {
   /* Make a "tab" record. Returns a promise */
   async _makeTab(client, tab, url, showRemoteIcons) {
     let icon;
     if (showRemoteIcons) {
       icon = tab.icon;
--- a/services/sync/modules/addonsreconciler.js
+++ b/services/sync/modules/addonsreconciler.js
@@ -110,18 +110,17 @@ this.EXPORTED_SYMBOLS = ["AddonsReconcil
  * see AL.onDisabling and AL.onDisabled. The onUninstalling and onUninstalled
  * events only come after the Addon Manager is closed or another view is
  * switched to. In the case of Sync performing the uninstall, the uninstall
  * events will occur immediately. However, we still see disabling events and
  * heed them like they were normal. In the end, the state is proper.
  */
 this.AddonsReconciler = function AddonsReconciler() {
   this._log = Log.repository.getLogger("Sync.AddonsReconciler");
-  let level = Svc.Prefs.get("log.logger.addonsreconciler", "Debug");
-  this._log.level = Log.Level[level];
+  this._log.manageLevelFromPref("services.sync.log.logger.addonsreconciler");
 
   Svc.Obs.add("xpcom-shutdown", this.stopListening, this);
 };
 AddonsReconciler.prototype = {
   /** Flag indicating whether we are listening to AddonManager events. */
   _listening: false,
 
   /**
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -27,17 +27,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "BulkKeyBundle",
                                   "resource://services-sync/keys.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
                                   "resource://gre/modules/FxAccounts.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "log", function() {
   let log = Log.repository.getLogger("Sync.BrowserIDManager");
-  log.level = Log.Level[Svc.Prefs.get("log.logger.identity")] || Log.Level.Error;
+  log.manageLevelFromPref("services.sync.log.logger.identity");
   return log;
 });
 
 // FxAccountsCommon.js doesn't use a "namespace", so create one here.
 var fxAccountsCommon = {};
 Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
 
 const OBSERVER_TOPICS = [
--- a/services/sync/modules/engines.js
+++ b/services/sync/modules/engines.js
@@ -50,19 +50,17 @@ this.Tracker = function Tracker(name, en
   if (!engine) {
     throw new Error("Tracker must be associated with an Engine instance.");
   }
 
   name = name || "Unnamed";
   this.name = this.file = name.toLowerCase();
   this.engine = engine;
 
-  this._log = Log.repository.getLogger("Sync.Tracker." + name);
-  let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
-  this._log.level = Log.Level[level];
+  this._log = Log.repository.getLogger(`Sync.Engine.${name}.Tracker`);
 
   this._score = 0;
   this._ignored = [];
   this._storage = new JSONFile({
     path: Utils.jsonFilePath("changes/" + this.file),
     dataPostProcessor: json => this._dataPostProcessor(json),
     beforeSave: () => this._beforeSave(),
   });
@@ -298,19 +296,17 @@ this.Store = function Store(name, engine
   if (!engine) {
     throw new Error("Store must be associated with an Engine instance.");
   }
 
   name = name || "Unnamed";
   this.name = name.toLowerCase();
   this.engine = engine;
 
-  this._log = Log.repository.getLogger("Sync.Store." + name);
-  let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
-  this._log.level = Log.Level[level];
+  this._log = Log.repository.getLogger(`Sync.Engine.${name}.Store`);
 
   XPCOMUtils.defineLazyGetter(this, "_timer", function() {
     return Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   });
 };
 Store.prototype = {
 
   /**
@@ -487,17 +483,20 @@ Store.prototype = {
 this.EngineManager = function EngineManager(service) {
   this.service = service;
 
   this._engines = {};
 
   // This will be populated by Service on startup.
   this._declined = new Set();
   this._log = Log.repository.getLogger("Sync.EngineManager");
-  this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.engines", "Debug")];
+  this._log.manageLevelFromPref("services.sync.log.logger.service.engines");
+  // define the default level for all engine logs here (although each engine
+  // allows its level to be controlled via a specific, non-default pref)
+  Log.repository.getLogger(`Sync.Engine`).manageLevelFromPref("services.sync.log.logger.engine");
 };
 EngineManager.prototype = {
   get(name) {
     // Return an array of engines if we have an array of names
     if (Array.isArray(name)) {
       let engines = [];
       name.forEach(function(name) {
         let engine = this.get(name);
@@ -654,18 +653,17 @@ this.Engine = function Engine(name, serv
   }
 
   this.Name = name || "Unnamed";
   this.name = name.toLowerCase();
   this.service = service;
 
   this._notify = Utils.notify("weave:engine:");
   this._log = Log.repository.getLogger("Sync.Engine." + this.Name);
-  let level = Svc.Prefs.get("log.logger.engine." + this.name, "Debug");
-  this._log.level = Log.Level[level];
+  this._log.manageLevelFromPref(`services.sync.log.logger.engine.${this.name}`);
 
   this._modified = this.emptyChangeset();
   this._tracker; // initialize tracker to load previously changed IDs
   this._log.debug("Engine constructed");
 };
 Engine.prototype = {
   // _storeObj, and _trackerObj should to be overridden in subclasses
   _storeObj: Store,
--- a/services/sync/modules/policies.js
+++ b/services/sync/modules/policies.js
@@ -133,17 +133,17 @@ SyncScheduler.prototype = {
       }
     } catch (ex) {
       this._log.warn("Could not determine network status.", ex);
     }
     return false;
   },
 
   init: function init() {
-    this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
+    this._log.manageLevelFromPref("services.sync.log.logger.service.main");
     this.setDefaults();
     Svc.Obs.add("weave:engine:score:updated", this);
     Svc.Obs.add("network:offline-status-changed", this);
     Svc.Obs.add("network:link-status-changed", this);
     Svc.Obs.add("captive-portal-detected", this);
     Svc.Obs.add("weave:service:sync:start", this);
     Svc.Obs.add("weave:service:sync:finish", this);
     Svc.Obs.add("weave:engine:sync:finish", this);
@@ -658,27 +658,25 @@ ErrorHandler.prototype = {
     Svc.Obs.add("weave:service:sync:error", this);
     Svc.Obs.add("weave:service:sync:finish", this);
     Svc.Obs.add("weave:service:start-over:finish", this);
 
     this.initLogs();
   },
 
   initLogs: function initLogs() {
+    // Set the root Sync logger level based on a pref. All other logs will
+    // inherit this level unless they specifically override it.
+    Log.repository.getLogger("Sync").manageLevelFromPref(`services.sync.log.logger`);
+    // And allow our specific log to have a custom level via a pref.
     this._log = Log.repository.getLogger("Sync.ErrorHandler");
-    this._log.level = Log.Level[Svc.Prefs.get("log.logger.service.main")];
-
-    let root = Log.repository.getLogger("Sync");
-    root.level = Log.Level[Svc.Prefs.get("log.rootLogger")];
+    this._log.manageLevelFromPref("services.sync.log.logger.service.main");
 
-    let logs = ["Sync", "FirefoxAccounts", "Hawk", "Common.TokenServerClient",
-                "Sync.SyncMigration", "browserwindow.syncui",
-                "Services.Common.RESTRequest", "Services.Common.RESTRequest",
-                "BookmarkSyncUtils",
-                "addons.xpi",
+    let logs = ["Sync", "Services.Common", "FirefoxAccounts", "Hawk",
+                "browserwindow.syncui", "BookmarkSyncUtils", "addons.xpi",
                ];
 
     this._logManager = new LogManager(Svc.Prefs, logs, "sync");
   },
 
   observe: function observe(subject, topic, data) {
     this._log.trace("Handling " + topic);
     switch (topic) {
--- a/services/sync/modules/resource.js
+++ b/services/sync/modules/resource.js
@@ -26,17 +26,17 @@ Cu.importGlobalProperties(["fetch"]);
  *
  *   get(callback)
  *   put(data, callback)
  *   post(data, callback)
  *   delete(callback)
  */
 this.Resource = function Resource(uri) {
   this._log = Log.repository.getLogger(this._logName);
-  this._log.level = Log.Level[Svc.Prefs.get("log.logger.network.resources")];
+  this._log.manageLevelFromPref("services.sync.log.logger.network.resources");
   this.uri = uri;
   this._headers = {};
 };
 // (static) Caches the latest server timestamp (X-Weave-Timestamp header).
 Resource.serverTime = null;
 Resource.prototype = {
   _logName: "Sync.Resource",
 
--- a/services/sync/modules/service.js
+++ b/services/sync/modules/service.js
@@ -291,18 +291,17 @@ Sync11Service.prototype = {
     this.status = Status;
     this.identity = Status._authManager;
     this.collectionKeys = new CollectionKeyManager();
 
     this.scheduler = new SyncScheduler(this);
     this.errorHandler = new ErrorHandler(this);
 
     this._log = Log.repository.getLogger("Sync.Service");
-    this._log.level =
-      Log.Level[Svc.Prefs.get("log.logger.service.main")];
+    this._log.manageLevelFromPref("services.sync.log.logger.service.main");
 
     this._log.info("Loading Weave " + WEAVE_VERSION);
 
     this._clusterManager = this.identity.createClusterManager(this);
     this.recordManager = new RecordManager(this);
 
     this.enabled = true;
 
--- a/services/sync/modules/stages/declined.js
+++ b/services/sync/modules/stages/declined.js
@@ -18,17 +18,17 @@ Cu.import("resource://gre/modules/Log.js
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-common/observers.js");
 Cu.import("resource://gre/modules/Preferences.jsm");
 
 
 
 this.DeclinedEngines = function(service) {
   this._log = Log.repository.getLogger("Sync.Declined");
-  this._log.level = Log.Level[new Preferences(PREFS_BRANCH).get("log.logger.declined")];
+  this._log.manageLevelFromPref("services.sync.log.logger.declined");
 
   this.service = service;
 };
 this.DeclinedEngines.prototype = {
   updateDeclined(meta, engineManager = this.service.engineManager) {
     let enabled = new Set(engineManager.getEnabled().map(e => e.name));
     let known = new Set(engineManager.getAll().map(e => e.name));
     let remoteDeclined = new Set(meta.payload.declined || []);
--- a/services/sync/modules/stages/enginesync.js
+++ b/services/sync/modules/stages/enginesync.js
@@ -20,17 +20,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 /**
  * Perform synchronization of engines.
  *
  * This was originally split out of service.js. The API needs lots of love.
  */
 this.EngineSynchronizer = function EngineSynchronizer(service) {
   this._log = Log.repository.getLogger("Sync.Synchronizer");
-  this._log.level = Log.Level[Svc.Prefs.get("log.logger.synchronizer")];
+  this._log.manageLevelFromPref("services.sync.log.logger.synchronizer");
 
   this.service = service;
 };
 
 EngineSynchronizer.prototype = {
   async sync(engineNamesToSync, why) {
     let fastSync = why && why == "sleep";
     let startTime = Date.now();
--- a/services/sync/modules/status.js
+++ b/services/sync/modules/status.js
@@ -110,19 +110,17 @@ this.Status = {
   resetBackoff: function resetBackoff() {
     this.enforceBackoff = false;
     this.backoffInterval = 0;
     this.minimumNextSync = 0;
   },
 
   resetSync: function resetSync() {
     // Logger setup.
-    let logPref = PREFS_BRANCH + "log.logger.status";
-    let logLevel = Services.prefs.getCharPref(logPref, "Trace");
-    this._log.level = Log.Level[logLevel];
+    this._log.manageLevelFromPref("services.sync.log.logger.status");
 
     this._log.info("Resetting Status.");
     this.service = STATUS_OK;
     this._login = LOGIN_SUCCEEDED;
     this._sync = SYNC_SUCCEEDED;
     this._engines = {};
     this.partial = false;
   }
--- a/services/sync/modules/telemetry.js
+++ b/services/sync/modules/telemetry.js
@@ -423,17 +423,17 @@ function cleanErrorMessage(error) {
   // these in error messages. Note that JSON.stringified stuff comes through
   // here, so we explicitly ignore double-quotes as well.
   error = error.replace(/[^\s"]+:[^\s"]+/g, "<URL>");
   return error;
 }
 
 class SyncTelemetryImpl {
   constructor(allowedEngines) {
-    log.level = Log.Level[Svc.Prefs.get("log.logger.telemetry", "Trace")];
+    log.manageLevelFromPref("services.sync.log.logger.telemetry");
     // This is accessible so we can enable custom engines during tests.
     this.allowedEngines = allowedEngines;
     this.current = null;
     this.setupObservers();
 
     this.payloads = [];
     this.discarded = 0;
     this.events = [];
--- a/services/sync/services-sync.js
+++ b/services/sync/services-sync.js
@@ -49,36 +49,27 @@ pref("services.sync.log.appender.dump", 
 pref("services.sync.log.appender.file.level", "Trace");
 pref("services.sync.log.appender.file.logOnError", true);
 #if defined(NIGHTLY_BUILD)
 pref("services.sync.log.appender.file.logOnSuccess", true);
 #else
 pref("services.sync.log.appender.file.logOnSuccess", false);
 #endif
 pref("services.sync.log.appender.file.maxErrorAge", 864000); // 10 days
-pref("services.sync.log.rootLogger", "Debug");
-pref("services.sync.log.logger.addonutils", "Debug");
-pref("services.sync.log.logger.declined", "Debug");
-pref("services.sync.log.logger.service.main", "Debug");
-pref("services.sync.log.logger.status", "Debug");
-pref("services.sync.log.logger.authenticator", "Debug");
-pref("services.sync.log.logger.network.resources", "Debug");
-pref("services.sync.log.logger.engine.bookmarks", "Debug");
-pref("services.sync.log.logger.engine.clients", "Debug");
-pref("services.sync.log.logger.engine.forms", "Debug");
-pref("services.sync.log.logger.engine.history", "Debug");
-pref("services.sync.log.logger.engine.passwords", "Debug");
-pref("services.sync.log.logger.engine.prefs", "Debug");
-pref("services.sync.log.logger.engine.tabs", "Debug");
-pref("services.sync.log.logger.engine.addons", "Debug");
-pref("services.sync.log.logger.engine.addresses", "Debug");
-pref("services.sync.log.logger.engine.creditcards", "Debug");
-pref("services.sync.log.logger.engine.extension-storage", "Debug");
-pref("services.sync.log.logger.engine.apps", "Debug");
-pref("services.sync.log.logger.identity", "Debug");
+
+// The default log level for all "Sync.*" logs. Adjusting this pref will
+// adjust the level for *all* Sync logs (except engines, and that's only
+// because we supply a default for the engines below.)
+pref("services.sync.log.logger", "Debug");
+
+// Prefs for Sync engines can be controlled globally or per-engine.
+// We only define the global level here, but manually creating prefs
+// like "services.sync.log.logger.engine.bookmarks" will control just
+// that engine.
+pref("services.sync.log.logger.engine", "Debug");
 pref("services.sync.log.cryptoDebug", false);
 
 pref("services.sync.fxa.termsURL", "https://accounts.firefox.com/legal/terms");
 pref("services.sync.fxa.privacyURL", "https://accounts.firefox.com/legal/privacy");
 
 pref("services.sync.telemetry.submissionInterval", 43200); // 12 hours in seconds
 pref("services.sync.telemetry.maxPayloadCount", 500);
 
--- a/testing/tps/tps/testrunner.py
+++ b/testing/tps/tps/testrunner.py
@@ -82,35 +82,18 @@ class TPSTestRunner(object):
         'extensions.legacy.enabled': True,
     }
 
     debug_preferences = {
         'services.sync.log.appender.console': 'Trace',
         'services.sync.log.appender.dump': 'Trace',
         'services.sync.log.appender.file.level': 'Trace',
         'services.sync.log.appender.file.logOnSuccess': True,
-        'services.sync.log.rootLogger': 'Trace',
-        'services.sync.log.logger.addonutils': 'Trace',
-        'services.sync.log.logger.declined': 'Trace',
-        'services.sync.log.logger.service.main': 'Trace',
-        'services.sync.log.logger.status': 'Trace',
-        'services.sync.log.logger.authenticator': 'Trace',
-        'services.sync.log.logger.network.resources': 'Trace',
-        'services.sync.log.logger.service.jpakeclient': 'Trace',
-        'services.sync.log.logger.engine.bookmarks': 'Trace',
-        'services.sync.log.logger.engine.clients': 'Trace',
-        'services.sync.log.logger.engine.forms': 'Trace',
-        'services.sync.log.logger.engine.history': 'Trace',
-        'services.sync.log.logger.engine.passwords': 'Trace',
-        'services.sync.log.logger.engine.prefs': 'Trace',
-        'services.sync.log.logger.engine.tabs': 'Trace',
-        'services.sync.log.logger.engine.addons': 'Trace',
-        'services.sync.log.logger.engine.apps': 'Trace',
-        'services.sync.log.logger.identity': 'Trace',
-        'services.sync.log.logger.userapi': 'Trace',
+        'services.sync.log.logger': 'Trace',
+        'services.sync.log.logger.engine': 'Trace',
     }
 
     syncVerRe = re.compile(
         r'Sync version: (?P<syncversion>.*)\n')
     ffVerRe = re.compile(
         r'Firefox version: (?P<ffver>.*)\n')
     ffBuildIDRe = re.compile(
         r'Firefox buildid: (?P<ffbuildid>.*)\n')
--- a/toolkit/components/places/PlacesSyncUtils.jsm
+++ b/toolkit/components/places/PlacesSyncUtils.jsm
@@ -1127,17 +1127,19 @@ const BookmarkSyncUtils = PlacesSyncUtil
    */
   async fetchGuidsWithAnno(anno, val) {
     let db = await PlacesUtils.promiseDBConnection();
     return fetchGuidsWithAnno(db, anno, val);
   },
 });
 
 XPCOMUtils.defineLazyGetter(this, "BookmarkSyncLog", () => {
-  return Log.repository.getLogger("BookmarkSyncUtils");
+  // Use a sub-log of the bookmarks engine, so setting the level for that
+  // engine also adjust the level of this log.
+  return Log.repository.getLogger("Sync.Engine.Bookmarks.BookmarkSyncUtils");
 });
 
 function validateSyncBookmarkObject(name, input, behavior) {
   return PlacesUtils.validateItemProperties(name,
     PlacesUtils.SYNC_BOOKMARK_VALIDATORS, input, behavior);
 }
 
 // Validates a record change record as returned by `pullChanges` and passed to