зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1480327: Part 2 - Modernize what's left of Log.jsm a bit. r=Mossop
MozReview-Commit-ID: H06rpiZuIEF --HG-- extra : rebase_source : e10781ffdfaa264370ca95a720298dc3607a079b
This commit is contained in:
Родитель
bf729d7e98
Коммит
c50886cf4e
|
@ -14,36 +14,27 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["GeckoViewUtils"];
|
var EXPORTED_SYMBOLS = ["GeckoViewUtils"];
|
||||||
|
|
||||||
var {Appender, BasicFormatter} = Log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A formatter that does not prepend time/name/level information to messages,
|
* A formatter that does not prepend time/name/level information to messages,
|
||||||
* because those fields are logged separately when using the Android logger.
|
* because those fields are logged separately when using the Android logger.
|
||||||
*/
|
*/
|
||||||
function AndroidFormatter() {
|
class AndroidFormatter extends Log.BasicFormatter {
|
||||||
BasicFormatter.call(this);
|
|
||||||
}
|
|
||||||
AndroidFormatter.prototype = Object.freeze({
|
|
||||||
__proto__: BasicFormatter.prototype,
|
|
||||||
|
|
||||||
format(message) {
|
format(message) {
|
||||||
return this.formatText(message);
|
return this.formatText(message);
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AndroidAppender
|
* AndroidAppender
|
||||||
* Logs to Android logcat using AndroidLog.jsm
|
* Logs to Android logcat using AndroidLog.jsm
|
||||||
*/
|
*/
|
||||||
function AndroidAppender(aFormatter) {
|
class AndroidAppender extends Log.Appender {
|
||||||
Appender.call(this, aFormatter || new AndroidFormatter());
|
constructor(aFormatter) {
|
||||||
|
super(aFormatter || new AndroidFormatter());
|
||||||
this._name = "AndroidAppender";
|
this._name = "AndroidAppender";
|
||||||
}
|
|
||||||
AndroidAppender.prototype = {
|
|
||||||
__proto__: Appender.prototype,
|
|
||||||
|
|
||||||
// Map log level to AndroidLog.foo method.
|
// Map log level to AndroidLog.foo method.
|
||||||
_mapping: {
|
this._mapping = {
|
||||||
[Log.Level.Fatal]: "e",
|
[Log.Level.Fatal]: "e",
|
||||||
[Log.Level.Error]: "e",
|
[Log.Level.Error]: "e",
|
||||||
[Log.Level.Warn]: "w",
|
[Log.Level.Warn]: "w",
|
||||||
|
@ -51,7 +42,8 @@ AndroidAppender.prototype = {
|
||||||
[Log.Level.Config]: "d",
|
[Log.Level.Config]: "d",
|
||||||
[Log.Level.Debug]: "d",
|
[Log.Level.Debug]: "d",
|
||||||
[Log.Level.Trace]: "v",
|
[Log.Level.Trace]: "v",
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
|
||||||
append(aMessage) {
|
append(aMessage) {
|
||||||
if (!aMessage) {
|
if (!aMessage) {
|
||||||
|
@ -63,8 +55,8 @@ AndroidAppender.prototype = {
|
||||||
const tag = aMessage.loggerName.replace(/^Gecko|\./g, "");
|
const tag = aMessage.loggerName.replace(/^Gecko|\./g, "");
|
||||||
const msg = this._formatter.format(aMessage);
|
const msg = this._formatter.format(aMessage);
|
||||||
AndroidLog[this._mapping[aMessage.level]](tag, msg);
|
AndroidLog[this._mapping[aMessage.level]](tag, msg);
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
var GeckoViewUtils = {
|
var GeckoViewUtils = {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,8 +42,6 @@ var consoleAppender;
|
||||||
// A set of all preference roots used by all instances.
|
// A set of all preference roots used by all instances.
|
||||||
var allBranches = new Set();
|
var allBranches = new Set();
|
||||||
|
|
||||||
let {Appender} = Log;
|
|
||||||
|
|
||||||
const ONE_BYTE = 1;
|
const ONE_BYTE = 1;
|
||||||
const ONE_KILOBYTE = 1024 * ONE_BYTE;
|
const ONE_KILOBYTE = 1024 * ONE_BYTE;
|
||||||
const ONE_MEGABYTE = 1024 * ONE_KILOBYTE;
|
const ONE_MEGABYTE = 1024 * ONE_KILOBYTE;
|
||||||
|
@ -59,19 +57,17 @@ const PR_UINT32_MAX = 0xffffffff;
|
||||||
* during logging. Instead, one can periodically consume the input stream and
|
* during logging. Instead, one can periodically consume the input stream and
|
||||||
* e.g. write it to disk asynchronously.
|
* e.g. write it to disk asynchronously.
|
||||||
*/
|
*/
|
||||||
function StorageStreamAppender(formatter) {
|
class StorageStreamAppender extends Log.Appender {
|
||||||
Appender.call(this, formatter);
|
constructor(formatter) {
|
||||||
|
super(formatter);
|
||||||
this._name = "StorageStreamAppender";
|
this._name = "StorageStreamAppender";
|
||||||
|
|
||||||
|
this._converterStream = null; // holds the nsIConverterOutputStream
|
||||||
|
this._outputStream = null; // holds the underlying nsIOutputStream
|
||||||
|
|
||||||
|
this._ss = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageStreamAppender.prototype = {
|
|
||||||
__proto__: Appender.prototype,
|
|
||||||
|
|
||||||
_converterStream: null, // holds the nsIConverterOutputStream
|
|
||||||
_outputStream: null, // holds the underlying nsIOutputStream
|
|
||||||
|
|
||||||
_ss: null,
|
|
||||||
|
|
||||||
get outputStream() {
|
get outputStream() {
|
||||||
if (!this._outputStream) {
|
if (!this._outputStream) {
|
||||||
// First create a raw stream. We can bail out early if that fails.
|
// First create a raw stream. We can bail out early if that fails.
|
||||||
|
@ -89,30 +85,30 @@ StorageStreamAppender.prototype = {
|
||||||
this._converterStream.init(this._outputStream, "UTF-8");
|
this._converterStream.init(this._outputStream, "UTF-8");
|
||||||
}
|
}
|
||||||
return this._converterStream;
|
return this._converterStream;
|
||||||
},
|
}
|
||||||
|
|
||||||
newOutputStream: function newOutputStream() {
|
newOutputStream() {
|
||||||
let ss = this._ss = Cc["@mozilla.org/storagestream;1"]
|
let ss = this._ss = Cc["@mozilla.org/storagestream;1"]
|
||||||
.createInstance(Ci.nsIStorageStream);
|
.createInstance(Ci.nsIStorageStream);
|
||||||
ss.init(STREAM_SEGMENT_SIZE, PR_UINT32_MAX, null);
|
ss.init(STREAM_SEGMENT_SIZE, PR_UINT32_MAX, null);
|
||||||
return ss.getOutputStream(0);
|
return ss.getOutputStream(0);
|
||||||
},
|
}
|
||||||
|
|
||||||
getInputStream: function getInputStream() {
|
getInputStream() {
|
||||||
if (!this._ss) {
|
if (!this._ss) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this._ss.newInputStream(0);
|
return this._ss.newInputStream(0);
|
||||||
},
|
}
|
||||||
|
|
||||||
reset: function reset() {
|
reset() {
|
||||||
if (!this._outputStream) {
|
if (!this._outputStream) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.outputStream.close();
|
this.outputStream.close();
|
||||||
this._outputStream = null;
|
this._outputStream = null;
|
||||||
this._ss = null;
|
this._ss = null;
|
||||||
},
|
}
|
||||||
|
|
||||||
doAppend(formatted) {
|
doAppend(formatted) {
|
||||||
if (!formatted) {
|
if (!formatted) {
|
||||||
|
@ -132,31 +128,29 @@ StorageStreamAppender.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// A storage appender that is flushable to a file on disk. Policies for
|
// A storage appender that is flushable to a file on disk. Policies for
|
||||||
// when to flush, to what file, log rotation etc are up to the consumer
|
// when to flush, to what file, log rotation etc are up to the consumer
|
||||||
// (although it does maintain a .sawError property to help the consumer decide
|
// (although it does maintain a .sawError property to help the consumer decide
|
||||||
// based on its policies)
|
// based on its policies)
|
||||||
function FlushableStorageAppender(formatter) {
|
class FlushableStorageAppender extends StorageStreamAppender {
|
||||||
StorageStreamAppender.call(this, formatter);
|
constructor(formatter) {
|
||||||
|
super(formatter);
|
||||||
this.sawError = false;
|
this.sawError = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushableStorageAppender.prototype = {
|
|
||||||
__proto__: StorageStreamAppender.prototype,
|
|
||||||
|
|
||||||
append(message) {
|
append(message) {
|
||||||
if (message.level >= Log.Level.Error) {
|
if (message.level >= Log.Level.Error) {
|
||||||
this.sawError = true;
|
this.sawError = true;
|
||||||
}
|
}
|
||||||
StorageStreamAppender.prototype.append.call(this, message);
|
StorageStreamAppender.prototype.append.call(this, message);
|
||||||
},
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
Log.StorageStreamAppender.prototype.reset.call(this);
|
super.reset();
|
||||||
this.sawError = false;
|
this.sawError = false;
|
||||||
},
|
}
|
||||||
|
|
||||||
// Flush the current stream to a file. Somewhat counter-intuitively, you
|
// Flush the current stream to a file. Somewhat counter-intuitively, you
|
||||||
// must pass a log which will be written to with details of the operation.
|
// must pass a log which will be written to with details of the operation.
|
||||||
|
@ -175,7 +169,7 @@ FlushableStorageAppender.prototype = {
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log.error("Failed to copy log stream to file", ex);
|
log.error("Failed to copy log stream to file", ex);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy an input stream to the named file, doing everything off the main
|
* Copy an input stream to the named file, doing everything off the main
|
||||||
|
@ -216,8 +210,8 @@ FlushableStorageAppender.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.trace("finished copy to", fullOutputFileName);
|
log.trace("finished copy to", fullOutputFileName);
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// The public LogManager object.
|
// The public LogManager object.
|
||||||
function LogManager(prefRoot, logNames, logFilePrefix) {
|
function LogManager(prefRoot, logNames, logFilePrefix) {
|
||||||
|
|
|
@ -64,50 +64,38 @@ var Log = {
|
||||||
Log.repository = value;
|
Log.repository = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
LogMessage,
|
_formatError(e) {
|
||||||
Logger,
|
let result = String(e);
|
||||||
LoggerRepository,
|
|
||||||
|
|
||||||
BasicFormatter,
|
|
||||||
|
|
||||||
Appender,
|
|
||||||
DumpAppender,
|
|
||||||
ConsoleAppender,
|
|
||||||
|
|
||||||
ParameterFormatter,
|
|
||||||
|
|
||||||
_formatError: function _formatError(e) {
|
|
||||||
let result = e.toString();
|
|
||||||
if (e.fileName) {
|
if (e.fileName) {
|
||||||
result += " (" + e.fileName;
|
let loc = [e.fileName];
|
||||||
if (e.lineNumber) {
|
if (e.lineNumber) {
|
||||||
result += ":" + e.lineNumber;
|
loc.push(e.lineNumber);
|
||||||
}
|
}
|
||||||
if (e.columnNumber) {
|
if (e.columnNumber) {
|
||||||
result += ":" + e.columnNumber;
|
loc.push(e.columnNumber);
|
||||||
}
|
}
|
||||||
result += ")";
|
result += `(${loc.join(":")})`;
|
||||||
}
|
}
|
||||||
return result + " " + Log.stackTrace(e);
|
return `${result} ${Log.stackTrace(e)}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is for back compatibility with services/common/utils.js; we duplicate
|
// This is for back compatibility with services/common/utils.js; we duplicate
|
||||||
// some of the logic in ParameterFormatter
|
// some of the logic in ParameterFormatter
|
||||||
exceptionStr: function exceptionStr(e) {
|
exceptionStr(e) {
|
||||||
if (!e) {
|
if (!e) {
|
||||||
return "" + e;
|
return String(e);
|
||||||
}
|
}
|
||||||
if (e instanceof Ci.nsIException) {
|
if (e instanceof Ci.nsIException) {
|
||||||
return e.toString() + " " + Log.stackTrace(e);
|
return `${e} ${Log.stackTrace(e)}`;
|
||||||
} else if (isError(e)) {
|
} else if (isError(e)) {
|
||||||
return Log._formatError(e);
|
return Log._formatError(e);
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
let message = e.message || e;
|
let message = e.message || e;
|
||||||
return message + " " + Log.stackTrace(e);
|
return `${message} ${Log.stackTrace(e)}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
stackTrace: function stackTrace(e) {
|
stackTrace(e) {
|
||||||
// Wrapped nsIException
|
// Wrapped nsIException
|
||||||
if (e.location) {
|
if (e.location) {
|
||||||
let frame = e.location;
|
let frame = e.location;
|
||||||
|
@ -136,7 +124,7 @@ var Log = {
|
||||||
}
|
}
|
||||||
frame = frame.caller;
|
frame = frame.caller;
|
||||||
}
|
}
|
||||||
return "Stack trace: " + output.join("\n");
|
return `Stack trace: ${output.join("\n")}`;
|
||||||
}
|
}
|
||||||
// Standard JS exception
|
// Standard JS exception
|
||||||
if (e.stack) {
|
if (e.stack) {
|
||||||
|
@ -156,7 +144,8 @@ var Log = {
|
||||||
* LogMessage
|
* LogMessage
|
||||||
* Encapsulates a single log event's data
|
* Encapsulates a single log event's data
|
||||||
*/
|
*/
|
||||||
function LogMessage(loggerName, level, message, params) {
|
class LogMessage {
|
||||||
|
constructor(loggerName, level, message, params) {
|
||||||
this.loggerName = loggerName;
|
this.loggerName = loggerName;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
/*
|
/*
|
||||||
|
@ -180,29 +169,29 @@ function LogMessage(loggerName, level, message, params) {
|
||||||
this._structured = this.params && this.params.action;
|
this._structured = this.params && this.params.action;
|
||||||
this.time = Date.now();
|
this.time = Date.now();
|
||||||
}
|
}
|
||||||
LogMessage.prototype = {
|
|
||||||
get levelDesc() {
|
get levelDesc() {
|
||||||
if (this.level in Log.Level.Desc)
|
if (this.level in Log.Level.Desc)
|
||||||
return Log.Level.Desc[this.level];
|
return Log.Level.Desc[this.level];
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
},
|
}
|
||||||
|
|
||||||
toString: function LogMsg_toString() {
|
toString() {
|
||||||
let msg = "LogMessage [" + this.time + " " + this.level + " " +
|
let msg = `${this.time} ${this.level} ${this.message}`;
|
||||||
this.message;
|
|
||||||
if (this.params) {
|
if (this.params) {
|
||||||
msg += " " + JSON.stringify(this.params);
|
msg += ` ${JSON.stringify(this.params)}`;
|
||||||
|
}
|
||||||
|
return `LogMessage [${msg}]`;
|
||||||
}
|
}
|
||||||
return msg + "]";
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logger
|
* Logger
|
||||||
* Hierarchical version. Logs to all appenders, assigned or inherited
|
* Hierarchical version. Logs to all appenders, assigned or inherited
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Logger(name, repository) {
|
class Logger {
|
||||||
|
constructor(name, repository) {
|
||||||
if (!repository)
|
if (!repository)
|
||||||
repository = Log.repository;
|
repository = Log.repository;
|
||||||
this._name = name;
|
this._name = name;
|
||||||
|
@ -210,16 +199,17 @@ function Logger(name, repository) {
|
||||||
this.ownAppenders = [];
|
this.ownAppenders = [];
|
||||||
this.appenders = [];
|
this.appenders = [];
|
||||||
this._repository = repository;
|
this._repository = repository;
|
||||||
|
|
||||||
|
this._levelPrefName = null;
|
||||||
|
this._levelPrefValue = null;
|
||||||
|
this._level = null;
|
||||||
|
this._parent = null;
|
||||||
}
|
}
|
||||||
Logger.prototype = {
|
|
||||||
_levelPrefName: null,
|
|
||||||
_levelPrefValue: null,
|
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this._name;
|
return this._name;
|
||||||
},
|
}
|
||||||
|
|
||||||
_level: null,
|
|
||||||
get level() {
|
get level() {
|
||||||
if (this._levelPrefName) {
|
if (this._levelPrefName) {
|
||||||
// We've been asked to use a preference to configure the logs. If the
|
// We've been asked to use a preference to configure the logs. If the
|
||||||
|
@ -245,7 +235,7 @@ Logger.prototype = {
|
||||||
return this.parent.level;
|
return this.parent.level;
|
||||||
dumpError("Log warning: root logger configuration error: no level defined");
|
dumpError("Log warning: root logger configuration error: no level defined");
|
||||||
return Log.Level.All;
|
return Log.Level.All;
|
||||||
},
|
}
|
||||||
set level(level) {
|
set level(level) {
|
||||||
if (this._levelPrefName) {
|
if (this._levelPrefName) {
|
||||||
// I guess we could honor this by nuking this._levelPrefValue, but it
|
// I guess we could honor this by nuking this._levelPrefValue, but it
|
||||||
|
@ -257,12 +247,11 @@ Logger.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._level = level;
|
this._level = level;
|
||||||
},
|
}
|
||||||
|
|
||||||
_parent: null,
|
|
||||||
get parent() {
|
get parent() {
|
||||||
return this._parent;
|
return this._parent;
|
||||||
},
|
}
|
||||||
set parent(parent) {
|
set parent(parent) {
|
||||||
if (this._parent == parent) {
|
if (this._parent == parent) {
|
||||||
return;
|
return;
|
||||||
|
@ -277,7 +266,7 @@ Logger.prototype = {
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
parent.children.push(this);
|
parent.children.push(this);
|
||||||
this.updateAppenders();
|
this.updateAppenders();
|
||||||
},
|
}
|
||||||
|
|
||||||
manageLevelFromPref(prefName) {
|
manageLevelFromPref(prefName) {
|
||||||
if (prefName == this._levelPrefName) {
|
if (prefName == this._levelPrefName) {
|
||||||
|
@ -292,9 +281,9 @@ Logger.prototype = {
|
||||||
}
|
}
|
||||||
this._levelPrefName = prefName;
|
this._levelPrefName = prefName;
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(this, "_levelPrefValue", prefName);
|
XPCOMUtils.defineLazyPreferenceGetter(this, "_levelPrefValue", prefName);
|
||||||
},
|
}
|
||||||
|
|
||||||
updateAppenders: function updateAppenders() {
|
updateAppenders() {
|
||||||
if (this._parent) {
|
if (this._parent) {
|
||||||
let notOwnAppenders = this._parent.appenders.filter(function(appender) {
|
let notOwnAppenders = this._parent.appenders.filter(function(appender) {
|
||||||
return !this.ownAppenders.includes(appender);
|
return !this.ownAppenders.includes(appender);
|
||||||
|
@ -308,24 +297,24 @@ Logger.prototype = {
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
for (let i = 0; i < this.children.length; i++) {
|
||||||
this.children[i].updateAppenders();
|
this.children[i].updateAppenders();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
addAppender: function Logger_addAppender(appender) {
|
addAppender(appender) {
|
||||||
if (this.ownAppenders.includes(appender)) {
|
if (this.ownAppenders.includes(appender)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.ownAppenders.push(appender);
|
this.ownAppenders.push(appender);
|
||||||
this.updateAppenders();
|
this.updateAppenders();
|
||||||
},
|
}
|
||||||
|
|
||||||
removeAppender: function Logger_removeAppender(appender) {
|
removeAppender(appender) {
|
||||||
let index = this.ownAppenders.indexOf(appender);
|
let index = this.ownAppenders.indexOf(appender);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.ownAppenders.splice(index, 1);
|
this.ownAppenders.splice(index, 1);
|
||||||
this.updateAppenders();
|
this.updateAppenders();
|
||||||
},
|
}
|
||||||
|
|
||||||
_unpackTemplateLiteral(string, params) {
|
_unpackTemplateLiteral(string, params) {
|
||||||
if (!Array.isArray(params)) {
|
if (!Array.isArray(params)) {
|
||||||
|
@ -355,7 +344,7 @@ Logger.prototype = {
|
||||||
concat += `\${${i}}${string[i + 1]}`;
|
concat += `\${${i}}${string[i + 1]}`;
|
||||||
}
|
}
|
||||||
return [concat, params];
|
return [concat, params];
|
||||||
},
|
}
|
||||||
|
|
||||||
log(level, string, params) {
|
log(level, string, params) {
|
||||||
if (this.level > level)
|
if (this.level > level)
|
||||||
|
@ -375,53 +364,54 @@ Logger.prototype = {
|
||||||
}
|
}
|
||||||
appender.append(message);
|
appender.append(message);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
fatal(string, ...params) {
|
fatal(string, ...params) {
|
||||||
this.log(Log.Level.Fatal, string, params);
|
this.log(Log.Level.Fatal, string, params);
|
||||||
},
|
}
|
||||||
error(string, ...params) {
|
error(string, ...params) {
|
||||||
this.log(Log.Level.Error, string, params);
|
this.log(Log.Level.Error, string, params);
|
||||||
},
|
}
|
||||||
warn(string, ...params) {
|
warn(string, ...params) {
|
||||||
this.log(Log.Level.Warn, string, params);
|
this.log(Log.Level.Warn, string, params);
|
||||||
},
|
}
|
||||||
info(string, ...params) {
|
info(string, ...params) {
|
||||||
this.log(Log.Level.Info, string, params);
|
this.log(Log.Level.Info, string, params);
|
||||||
},
|
}
|
||||||
config(string, ...params) {
|
config(string, ...params) {
|
||||||
this.log(Log.Level.Config, string, params);
|
this.log(Log.Level.Config, string, params);
|
||||||
},
|
}
|
||||||
debug(string, ...params) {
|
debug(string, ...params) {
|
||||||
this.log(Log.Level.Debug, string, params);
|
this.log(Log.Level.Debug, string, params);
|
||||||
},
|
}
|
||||||
trace(string, ...params) {
|
trace(string, ...params) {
|
||||||
this.log(Log.Level.Trace, string, params);
|
this.log(Log.Level.Trace, string, params);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LoggerRepository
|
* LoggerRepository
|
||||||
* Implements a hierarchy of Loggers
|
* Implements a hierarchy of Loggers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function LoggerRepository() {}
|
class LoggerRepository {
|
||||||
LoggerRepository.prototype = {
|
constructor() {
|
||||||
_loggers: {},
|
this._loggers = {};
|
||||||
|
this._rootLogger = null;
|
||||||
|
}
|
||||||
|
|
||||||
_rootLogger: null,
|
|
||||||
get rootLogger() {
|
get rootLogger() {
|
||||||
if (!this._rootLogger) {
|
if (!this._rootLogger) {
|
||||||
this._rootLogger = new Logger("root", this);
|
this._rootLogger = new Logger("root", this);
|
||||||
this._rootLogger.level = Log.Level.All;
|
this._rootLogger.level = Log.Level.All;
|
||||||
}
|
}
|
||||||
return this._rootLogger;
|
return this._rootLogger;
|
||||||
},
|
}
|
||||||
set rootLogger(logger) {
|
set rootLogger(logger) {
|
||||||
throw "Cannot change the root logger";
|
throw "Cannot change the root logger";
|
||||||
},
|
}
|
||||||
|
|
||||||
_updateParents: function LogRep__updateParents(name) {
|
_updateParents(name) {
|
||||||
let pieces = name.split(".");
|
let pieces = name.split(".");
|
||||||
let cur, parent;
|
let cur, parent;
|
||||||
|
|
||||||
|
@ -448,7 +438,7 @@ LoggerRepository.prototype = {
|
||||||
if (logger != name && logger.indexOf(name) == 0)
|
if (logger != name && logger.indexOf(name) == 0)
|
||||||
this._updateParents(logger);
|
this._updateParents(logger);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a named Logger.
|
* Obtain a named Logger.
|
||||||
|
@ -465,7 +455,7 @@ LoggerRepository.prototype = {
|
||||||
this._loggers[name] = new Logger(name, this);
|
this._loggers[name] = new Logger(name, this);
|
||||||
this._updateParents(name);
|
this._updateParents(name);
|
||||||
return this._loggers[name];
|
return this._loggers[name];
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a Logger that logs all string messages with a prefix.
|
* Obtain a Logger that logs all string messages with a prefix.
|
||||||
|
@ -499,8 +489,8 @@ LoggerRepository.prototype = {
|
||||||
return log.log(level, string, params);
|
return log.log(level, string, params);
|
||||||
};
|
};
|
||||||
return proxy;
|
return proxy;
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Formatters
|
* Formatters
|
||||||
|
@ -508,13 +498,14 @@ LoggerRepository.prototype = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Basic formatter that doesn't do anything fancy.
|
// Basic formatter that doesn't do anything fancy.
|
||||||
function BasicFormatter(dateFormat) {
|
class BasicFormatter {
|
||||||
|
constructor(dateFormat) {
|
||||||
if (dateFormat) {
|
if (dateFormat) {
|
||||||
this.dateFormat = dateFormat;
|
this.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
this.parameterFormatter = new ParameterFormatter();
|
this.parameterFormatter = new ParameterFormatter();
|
||||||
}
|
}
|
||||||
BasicFormatter.prototype = {
|
|
||||||
/**
|
/**
|
||||||
* Format the text of a message with optional parameters.
|
* Format the text of a message with optional parameters.
|
||||||
* If the text contains ${identifier}, replace that with
|
* If the text contains ${identifier}, replace that with
|
||||||
|
@ -564,15 +555,15 @@ BasicFormatter.prototype = {
|
||||||
return textParts.join(": ");
|
return textParts.join(": ");
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
}
|
||||||
|
|
||||||
format: function BF_format(message) {
|
format(message) {
|
||||||
return message.time + "\t" +
|
return message.time + "\t" +
|
||||||
message.loggerName + "\t" +
|
message.loggerName + "\t" +
|
||||||
message.levelDesc + "\t" +
|
message.levelDesc + "\t" +
|
||||||
this.formatText(message);
|
this.formatText(message);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test an object to see if it is a Mozilla JS Error.
|
* Test an object to see if it is a Mozilla JS Error.
|
||||||
|
@ -588,10 +579,11 @@ function isError(aObj) {
|
||||||
* a string representation of the object.
|
* a string representation of the object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function ParameterFormatter() {
|
class ParameterFormatter {
|
||||||
|
constructor() {
|
||||||
this._name = "ParameterFormatter";
|
this._name = "ParameterFormatter";
|
||||||
}
|
}
|
||||||
ParameterFormatter.prototype = {
|
|
||||||
format(ob) {
|
format(ob) {
|
||||||
try {
|
try {
|
||||||
if (ob === undefined) {
|
if (ob === undefined) {
|
||||||
|
@ -606,7 +598,7 @@ ParameterFormatter.prototype = {
|
||||||
return ob;
|
return ob;
|
||||||
}
|
}
|
||||||
if (ob instanceof Ci.nsIException) {
|
if (ob instanceof Ci.nsIException) {
|
||||||
return ob.toString() + " " + Log.stackTrace(ob);
|
return `${ob} ${Log.stackTrace(ob)}`;
|
||||||
} else if (isError(ob)) {
|
} else if (isError(ob)) {
|
||||||
return Log._formatError(ob);
|
return Log._formatError(ob);
|
||||||
}
|
}
|
||||||
|
@ -619,19 +611,19 @@ ParameterFormatter.prototype = {
|
||||||
return val;
|
return val;
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dumpError("Exception trying to format object for log message: " + Log.exceptionStr(e));
|
dumpError(`Exception trying to format object for log message: ${Log.exceptionStr(e)}`);
|
||||||
}
|
}
|
||||||
// Fancy formatting failed. Just toSource() it - but even this may fail!
|
// Fancy formatting failed. Just toSource() it - but even this may fail!
|
||||||
try {
|
try {
|
||||||
return ob.toSource();
|
return ob.toSource();
|
||||||
} catch (_) { }
|
} catch (_) { }
|
||||||
try {
|
try {
|
||||||
return "" + ob;
|
return String(ob);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return "[object]";
|
return "[object]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Appenders
|
* Appenders
|
||||||
|
@ -639,55 +631,53 @@ ParameterFormatter.prototype = {
|
||||||
* Simply subclass and override doAppend to implement a new one
|
* Simply subclass and override doAppend to implement a new one
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Appender(formatter) {
|
class Appender {
|
||||||
|
constructor(formatter) {
|
||||||
|
this.level = Log.Level.All;
|
||||||
this._name = "Appender";
|
this._name = "Appender";
|
||||||
this._formatter = formatter || new BasicFormatter();
|
this._formatter = formatter || new BasicFormatter();
|
||||||
}
|
}
|
||||||
Appender.prototype = {
|
|
||||||
level: Log.Level.All,
|
|
||||||
|
|
||||||
append: function App_append(message) {
|
append(message) {
|
||||||
if (message) {
|
if (message) {
|
||||||
this.doAppend(this._formatter.format(message));
|
this.doAppend(this._formatter.format(message));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
toString: function App_toString() {
|
|
||||||
return this._name + " [level=" + this.level +
|
toString() {
|
||||||
", formatter=" + this._formatter + "]";
|
return `${this._name} [level=${this.level}, formatter=${this._formatter}]`;
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DumpAppender
|
* DumpAppender
|
||||||
* Logs to standard out
|
* Logs to standard out
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function DumpAppender(formatter) {
|
class DumpAppender extends Appender {
|
||||||
Appender.call(this, formatter);
|
constructor(formatter) {
|
||||||
|
super(formatter);
|
||||||
this._name = "DumpAppender";
|
this._name = "DumpAppender";
|
||||||
}
|
}
|
||||||
DumpAppender.prototype = {
|
|
||||||
__proto__: Appender.prototype,
|
|
||||||
|
|
||||||
doAppend: function DApp_doAppend(formatted) {
|
doAppend(formatted) {
|
||||||
dump(formatted + "\n");
|
dump(formatted + "\n");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ConsoleAppender
|
* ConsoleAppender
|
||||||
* Logs to the javascript console
|
* Logs to the javascript console
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function ConsoleAppender(formatter) {
|
class ConsoleAppender extends Appender {
|
||||||
Appender.call(this, formatter);
|
constructor(formatter) {
|
||||||
|
super(formatter);
|
||||||
this._name = "ConsoleAppender";
|
this._name = "ConsoleAppender";
|
||||||
}
|
}
|
||||||
ConsoleAppender.prototype = {
|
|
||||||
__proto__: Appender.prototype,
|
|
||||||
|
|
||||||
// XXX this should be replaced with calls to the Browser Console
|
// XXX this should be replaced with calls to the Browser Console
|
||||||
append: function App_append(message) {
|
append(message) {
|
||||||
if (message) {
|
if (message) {
|
||||||
let m = this._formatter.format(message);
|
let m = this._formatter.format(message);
|
||||||
if (message.level > Log.Level.Warn) {
|
if (message.level > Log.Level.Warn) {
|
||||||
|
@ -696,9 +686,23 @@ ConsoleAppender.prototype = {
|
||||||
}
|
}
|
||||||
this.doAppend(m);
|
this.doAppend(m);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
doAppend: function CApp_doAppend(formatted) {
|
doAppend(formatted) {
|
||||||
Services.console.logStringMessage(formatted);
|
Services.console.logStringMessage(formatted);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
Object.assign(Log, {
|
||||||
|
LogMessage,
|
||||||
|
Logger,
|
||||||
|
LoggerRepository,
|
||||||
|
|
||||||
|
BasicFormatter,
|
||||||
|
|
||||||
|
Appender,
|
||||||
|
DumpAppender,
|
||||||
|
ConsoleAppender,
|
||||||
|
|
||||||
|
ParameterFormatter,
|
||||||
|
});
|
||||||
|
|
|
@ -16,17 +16,16 @@ var testFormatter = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function MockAppender(formatter) {
|
class MockAppender extends Log.Appender {
|
||||||
Log.Appender.call(this, formatter);
|
constructor(formatter) {
|
||||||
|
super(formatter);
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
}
|
}
|
||||||
MockAppender.prototype = {
|
|
||||||
__proto__: Log.Appender.prototype,
|
|
||||||
|
|
||||||
doAppend: function DApp_doAppend(message) {
|
doAppend(message) {
|
||||||
this.messages.push(message);
|
this.messages.push(message);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
add_task(function test_Logger() {
|
add_task(function test_Logger() {
|
||||||
let log = Log.repository.getLogger("test.logger");
|
let log = Log.repository.getLogger("test.logger");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче