diff --git a/lib/loglevel.js b/lib/loglevel.js index 4e8f639..604cc21 100644 --- a/lib/loglevel.js +++ b/lib/loglevel.js @@ -118,10 +118,30 @@ enableLoggingWhenConsoleArrives.apply(this, arguments); } - function Logger(name, defaultLevel, factory) { + function Logger(name, factory) { + // Private instance variables. var self = this; - var currentLevel; - defaultLevel = defaultLevel == null ? "WARN" : defaultLevel; + /** + * The level inherited from a parent logger (or a global default). We + * cache this here rather than delegating to the parent so that it stays + * in sync with the actual logging methods that we have installed (the + * parent could change levels but we might not have rebuilt the loggers + * in this child yet). + * @type {number} + */ + var inheritedLevel; + /** + * The default level for this logger, if any. If set, this overrides + * `inheritedLevel`. + * @type {number|null} + */ + var defaultLevel; + /** + * A user-specific level for this logger. If set, this overrides + * `defaultLevel`. + * @type {number|null} + */ + var userLevel; var storageKey = "loglevel"; if (typeof name === "string") { @@ -185,7 +205,6 @@ // Use localStorage if available try { window.localStorage.removeItem(storageKey); - return; } catch (ignore) {} // Use session cookie as fallback @@ -230,31 +249,36 @@ self.methodFactory = factory || defaultMethodFactory; self.getLevel = function () { - return currentLevel == null ? defaultLevel : currentLevel; + if (userLevel != null) { + return userLevel; + } else if (defaultLevel != null) { + return defaultLevel; + } else { + return inheritedLevel; + } }; self.setLevel = function (level, persist) { - level = normalizeLevel(level); - currentLevel = level; + userLevel = normalizeLevel(level); if (persist !== false) { // defaults to true - persistLevelIfPossible(level); + persistLevelIfPossible(userLevel); } - // NOTE: in v2, this should call rebuild(), which is recursive. + + // NOTE: in v2, this should call rebuild(), which updates children. return rebuildLoggingMethods(); }; self.setDefaultLevel = function (level) { defaultLevel = normalizeLevel(level); - if (currentLevel == null) { - // NOTE: in v2, this should call rebuild(), which is recursive. - rebuildLoggingMethods(); + if (!getPersistedLevel()) { + self.setLevel(level, false); } }; self.resetLevel = function () { + userLevel = null; clearPersistedLevel(); - currentLevel = null; - self.setDefaultLevel(defaultLevel); + rebuildLoggingMethods(); }; self.enableAll = function(persist) { @@ -266,24 +290,30 @@ }; self.rebuild = function () { + if (defaultLogger !== self) { + inheritedLevel = normalizeLevel(defaultLogger.getLevel()); + } rebuildLoggingMethods(); if (defaultLogger === self) { - var level = self.getLevel(); - for (var childName in _loggersByName) { - _loggersByName[childName].setDefaultLevel(level); + _loggersByName[childName].rebuild(); } } }; - // Initialize with the right level + // Initialize all the internal levels. + inheritedLevel = normalizeLevel( + defaultLogger ? defaultLogger.getLevel() : "WARN" + ); + if (defaultLevel != null) { + defaultLevel = normalizeLevel(defaultLevel); + } var initialLevel = getPersistedLevel(); - if (initialLevel == null) { - self.setDefaultLevel(defaultLevel); - } else { - self.setLevel(initialLevel, false); + if (initialLevel != null) { + userLevel = normalizeLevel(initialLevel); } + rebuildLoggingMethods(); } /* @@ -296,13 +326,15 @@ defaultLogger.getLogger = function getLogger(name) { if ((typeof name !== "symbol" && typeof name !== "string") || name === "") { - throw new TypeError("You must supply a name when creating a logger."); + throw new TypeError("You must supply a name when creating a logger."); } var logger = _loggersByName[name]; if (!logger) { - logger = _loggersByName[name] = new Logger( - name, defaultLogger.getLevel(), defaultLogger.methodFactory); + logger = _loggersByName[name] = new Logger( + name, + defaultLogger.methodFactory + ); } return logger; };