Bug 1425987 - part 1: Add support to Log.jsm for managing log levels via prefs. r=Gijs

MozReview-Commit-ID: 6xLSnb0etnl

--HG--
extra : rebase_source : 7f6878b3296d3a513ae20a28d5ceb8fbbd84ea53
This commit is contained in:
Mark Hammond 2017-12-18 17:48:41 +11:00
parent 36b8b0ba57
commit 26f95a81a1
2 changed files with 76 additions and 0 deletions

View File

@ -265,12 +265,33 @@ function Logger(name, repository) {
this._repository = repository;
}
Logger.prototype = {
_levelPrefName: null,
_levelPrefValue: null,
get name() {
return this._name;
},
_level: null,
get level() {
if (this._levelPrefName) {
// We've been asked to use a preference to configure the logs. If the
// pref has a value we use it, otherwise we continue to use the parent.
const lpv = this._levelPrefValue;
if (lpv) {
const levelValue = Log.Level[lpv];
if (levelValue) {
// stash it in _level just in case a future value of the pref is
// invalid, in which case we end up continuing to use this value.
this._level = levelValue;
return levelValue;
}
} else {
// in case the pref has transitioned from a value to no value, we reset
// this._level and fall through to using the parent.
this._level = null;
}
}
if (this._level != null)
return this._level;
if (this.parent)
@ -279,6 +300,15 @@ Logger.prototype = {
return Log.Level.All;
},
set level(level) {
if (this._levelPrefName) {
// I guess we could honor this by nuking this._levelPrefValue, but it
// almost certainly implies confusion, so we'll warn and ignore.
dumpError(`Log warning: The log '${this.name}' is configured to use ` +
`the preference '${this._levelPrefName}' - you must adjust ` +
`the level by setting this preference, not by using the ` +
`level setter`);
return;
}
this._level = level;
},
@ -302,6 +332,21 @@ Logger.prototype = {
this.updateAppenders();
},
manageLevelFromPref(prefName) {
if (prefName == this._levelPrefName) {
// We've already configured this log with an observer for that pref.
return;
}
if (this._levelPrefName) {
dumpError(`The log '${this.name}' is already configured with the ` +
`preference '${this._levelPrefName}' - ignoring request to ` +
`also use the preference '${prefName}'`);
return;
}
this._levelPrefName = prefName;
XPCOMUtils.defineLazyPreferenceGetter(this, "_levelPrefValue", prefName);
},
updateAppenders: function updateAppenders() {
if (this._parent) {
let notOwnAppenders = this._parent.appenders.filter(function(appender) {

View File

@ -588,3 +588,34 @@ add_task(function* format_errors() {
do_check_true(str.includes("format_errors"));
}
});
/*
* Check that automatic support for setting the log level via preferences
* works.
*/
add_test(function test_prefs() {
let log = Log.repository.getLogger("error.logger");
log.level = Log.Level.Debug;
Services.prefs.setStringPref("logger.test", "Error");
log.manageLevelFromPref("logger.test");
// check initial pref value is set up.
equal(log.level, Log.Level.Error);
Services.prefs.setStringPref("logger.test", "Error");
// check changing the pref causes the level to change.
Services.prefs.setStringPref("logger.test", "Trace");
equal(log.level, Log.Level.Trace);
// invalid values cause nothing to happen.
Services.prefs.setStringPref("logger.test", "invalid-level-value");
equal(log.level, Log.Level.Trace);
Services.prefs.setIntPref("logger.test", 123);
equal(log.level, Log.Level.Trace);
// setting a "sub preference" shouldn't impact it.
Services.prefs.setStringPref("logger.test.foo", "Debug");
equal(log.level, Log.Level.Trace);
// clearing the level param should cause it to use the parent level.
Log.repository.getLogger("error").level = Log.Level.All;
Services.prefs.setStringPref("logger.test", "");
equal(log.level, Log.Level.All);
run_next_test();
});