зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team into mozilla-central
This commit is contained in:
Коммит
751089c21c
|
@ -228,6 +228,12 @@ let StyleSheet = function(form, debuggee) {
|
|||
this._client.addListener("propertyChange", this._onPropertyChange);
|
||||
this._client.addListener("styleApplied", this._onStyleApplied);
|
||||
|
||||
// Backwards compatibility
|
||||
this._client.addListener("sourceLoad-" + this._actor, this._onSourceLoad);
|
||||
this._client.addListener("propertyChange-" + this._actor, this._onPropertyChange);
|
||||
this._client.addListener("styleApplied-" + this._actor, this._onStyleApplied);
|
||||
|
||||
|
||||
// set initial property values
|
||||
for (let attr in form) {
|
||||
this[attr] = form[attr];
|
||||
|
@ -324,5 +330,9 @@ StyleSheet.prototype = {
|
|||
this._client.removeListener("sourceLoad", this._onSourceLoad);
|
||||
this._client.removeListener("propertyChange", this._onPropertyChange);
|
||||
this._client.removeListener("styleApplied", this._onStyleApplied);
|
||||
|
||||
this._client.removeListener("sourceLoad-" + this._actor, this._onSourceLoad);
|
||||
this._client.removeListener("propertyChange-" + this._actor, this._onPropertyChange);
|
||||
this._client.removeListener("styleApplied-" + this._actor, this._onStyleApplied);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,16 @@ this.Log4Moz = {
|
|||
20: "DEBUG",
|
||||
10: "TRACE",
|
||||
0: "ALL"
|
||||
},
|
||||
Numbers: {
|
||||
"FATAL": 70,
|
||||
"ERROR": 60,
|
||||
"WARN": 50,
|
||||
"INFO": 40,
|
||||
"CONFIG": 30,
|
||||
"DEBUG": 20,
|
||||
"TRACE": 10,
|
||||
"ALL": 0,
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -55,6 +65,7 @@ this.Log4Moz = {
|
|||
|
||||
Formatter: Formatter,
|
||||
BasicFormatter: BasicFormatter,
|
||||
StructuredFormatter: StructuredFormatter,
|
||||
|
||||
Appender: Appender,
|
||||
DumpAppender: DumpAppender,
|
||||
|
@ -109,10 +120,15 @@ this.Log4Moz = {
|
|||
* LogMessage
|
||||
* Encapsulates a single log event's data
|
||||
*/
|
||||
function LogMessage(loggerName, level, message){
|
||||
function LogMessage(loggerName, level, message, params) {
|
||||
this.loggerName = loggerName;
|
||||
this.level = level;
|
||||
this.message = message;
|
||||
this.params = params;
|
||||
|
||||
// The _structured field will correspond to whether this message is to
|
||||
// be interpreted as a structured message.
|
||||
this._structured = this.params && this.params.action;
|
||||
this.time = Date.now();
|
||||
}
|
||||
LogMessage.prototype = {
|
||||
|
@ -123,8 +139,12 @@ LogMessage.prototype = {
|
|||
},
|
||||
|
||||
toString: function LogMsg_toString(){
|
||||
return "LogMessage [" + this.time + " " + this.level + " " +
|
||||
this.message + "]";
|
||||
let msg = "LogMessage [" + this.time + " " + this.level + " " +
|
||||
this.message;
|
||||
if (this.params) {
|
||||
msg += " " + JSON.stringify(this.params);
|
||||
}
|
||||
return msg + "]"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -211,7 +231,39 @@ Logger.prototype = {
|
|||
this.updateAppenders();
|
||||
},
|
||||
|
||||
log: function Logger_log(level, string) {
|
||||
/**
|
||||
* Logs a structured message object.
|
||||
*
|
||||
* @param action
|
||||
* (string) A message action, one of a set of actions known to the
|
||||
* log consumer.
|
||||
* @param params
|
||||
* (object) Parameters to be included in the message.
|
||||
* If _level is included as a key and the corresponding value
|
||||
* is a number or known level name, the message will be logged
|
||||
* at the indicated level.
|
||||
*/
|
||||
logStructured: function (action, params) {
|
||||
if (!action) {
|
||||
throw "An action is required when logging a structured message.";
|
||||
}
|
||||
if (!params) {
|
||||
return this.log(this.level, undefined, {"action": action});
|
||||
}
|
||||
if (typeof params != "object") {
|
||||
throw "The params argument is required to be an object.";
|
||||
}
|
||||
|
||||
let level = params._level || this.level;
|
||||
if ((typeof level == "string") && level in Log4Moz.Level.Numbers) {
|
||||
level = Log4Moz.Level.Numbers[level];
|
||||
}
|
||||
|
||||
params.action = action;
|
||||
this.log(level, params._message, params);
|
||||
},
|
||||
|
||||
log: function (level, string, params) {
|
||||
if (this.level > level)
|
||||
return;
|
||||
|
||||
|
@ -224,32 +276,32 @@ Logger.prototype = {
|
|||
continue;
|
||||
}
|
||||
if (!message) {
|
||||
message = new LogMessage(this._name, level, string);
|
||||
message = new LogMessage(this._name, level, string, params);
|
||||
}
|
||||
appender.append(message);
|
||||
}
|
||||
},
|
||||
|
||||
fatal: function Logger_fatal(string) {
|
||||
this.log(Log4Moz.Level.Fatal, string);
|
||||
fatal: function (string, params) {
|
||||
this.log(Log4Moz.Level.Fatal, string, params);
|
||||
},
|
||||
error: function Logger_error(string) {
|
||||
this.log(Log4Moz.Level.Error, string);
|
||||
error: function (string, params) {
|
||||
this.log(Log4Moz.Level.Error, string, params);
|
||||
},
|
||||
warn: function Logger_warn(string) {
|
||||
this.log(Log4Moz.Level.Warn, string);
|
||||
warn: function (string, params) {
|
||||
this.log(Log4Moz.Level.Warn, string, params);
|
||||
},
|
||||
info: function Logger_info(string) {
|
||||
this.log(Log4Moz.Level.Info, string);
|
||||
info: function (string, params) {
|
||||
this.log(Log4Moz.Level.Info, string, params);
|
||||
},
|
||||
config: function Logger_config(string) {
|
||||
this.log(Log4Moz.Level.Config, string);
|
||||
config: function (string, params) {
|
||||
this.log(Log4Moz.Level.Config, string, params);
|
||||
},
|
||||
debug: function Logger_debug(string) {
|
||||
this.log(Log4Moz.Level.Debug, string);
|
||||
debug: function (string, params) {
|
||||
this.log(Log4Moz.Level.Debug, string, params);
|
||||
},
|
||||
trace: function Logger_trace(string) {
|
||||
this.log(Log4Moz.Level.Trace, string);
|
||||
trace: function (string, params) {
|
||||
this.log(Log4Moz.Level.Trace, string, params);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -314,8 +366,8 @@ LoggerRepository.prototype = {
|
|||
|
||||
/*
|
||||
* Formatters
|
||||
* These massage a LogMessage into whatever output is desired
|
||||
* Only the BasicFormatter is currently implemented
|
||||
* These massage a LogMessage into whatever output is desired.
|
||||
* BasicFormatter and StructuredFormatter are implemented here.
|
||||
*/
|
||||
|
||||
// Abstract formatter
|
||||
|
@ -324,7 +376,7 @@ Formatter.prototype = {
|
|||
format: function Formatter_format(message) {}
|
||||
};
|
||||
|
||||
// Basic formatter that doesn't do anything fancy
|
||||
// Basic formatter that doesn't do anything fancy.
|
||||
function BasicFormatter(dateFormat) {
|
||||
if (dateFormat)
|
||||
this.dateFormat = dateFormat;
|
||||
|
@ -340,6 +392,36 @@ BasicFormatter.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
// Structured formatter that outputs JSON based on message data.
|
||||
// This formatter will format unstructured messages by supplying
|
||||
// default values.
|
||||
function StructuredFormatter() { }
|
||||
StructuredFormatter.prototype = {
|
||||
__proto__: Formatter.prototype,
|
||||
|
||||
format: function (logMessage) {
|
||||
let output = {
|
||||
_time: logMessage.time,
|
||||
_namespace: logMessage.loggerName,
|
||||
_level: logMessage.levelDesc
|
||||
};
|
||||
|
||||
for (let key in logMessage.params) {
|
||||
output[key] = logMessage.params[key];
|
||||
}
|
||||
|
||||
if (!output.action) {
|
||||
output.action = "UNKNOWN";
|
||||
}
|
||||
|
||||
if (!output._message && logMessage.message) {
|
||||
output._message = logMessage.message;
|
||||
}
|
||||
|
||||
return JSON.stringify(output);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Appenders
|
||||
* These can be attached to Loggers to log to different places
|
||||
|
|
|
@ -41,8 +41,9 @@ add_test(function test_Logger() {
|
|||
log.debug("this should be logged but not appended.");
|
||||
|
||||
do_check_eq(appender.messages.length, 1);
|
||||
do_check_true(appender.messages[0].indexOf("info test") > 0);
|
||||
do_check_true(appender.messages[0].indexOf("INFO") > 0);
|
||||
|
||||
let msgRe = /\d+\ttest.logger\t\INFO\tinfo test/;
|
||||
do_check_true(msgRe.test(appender.messages[0]));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -69,6 +70,113 @@ add_test(function test_Logger_parent() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
// A utility method for checking object equivalence.
|
||||
// Fields with a reqular expression value in expected will be tested
|
||||
// against the corresponding value in actual. Otherwise objects
|
||||
// are expected to have the same keys and equal values.
|
||||
function checkObjects(expected, actual) {
|
||||
do_check_true(expected instanceof Object);
|
||||
do_check_true(actual instanceof Object);
|
||||
for (let key in expected) {
|
||||
do_check_neq(actual[key], undefined);
|
||||
if (expected[key] instanceof RegExp) {
|
||||
do_check_true(expected[key].test(actual[key].toString()));
|
||||
} else {
|
||||
if (expected[key] instanceof Object) {
|
||||
checkObjects(expected[key], actual[key]);
|
||||
} else {
|
||||
do_check_eq(expected[key], actual[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let key in actual) {
|
||||
do_check_neq(expected[key], undefined);
|
||||
}
|
||||
}
|
||||
|
||||
add_test(function test_StructuredLogCommands() {
|
||||
let appender = new MockAppender(new Log4Moz.StructuredFormatter());
|
||||
let logger = Log4Moz.repository.getLogger("test.StructuredOutput");
|
||||
logger.addAppender(appender);
|
||||
logger.level = Log4Moz.Level.Info;
|
||||
|
||||
logger.logStructured("test_message", {_message: "message string one"});
|
||||
logger.logStructured("test_message", {_message: "message string two",
|
||||
_level: "ERROR",
|
||||
source_file: "test_log4moz.js"});
|
||||
logger.logStructured("test_message");
|
||||
logger.logStructured("test_message", {source_file: "test_log4moz.js",
|
||||
message_position: 4});
|
||||
|
||||
let messageOne = {"_time": /\d+/,
|
||||
"_namespace": "test.StructuredOutput",
|
||||
"_level": "INFO",
|
||||
"_message": "message string one",
|
||||
"action": "test_message"};
|
||||
|
||||
let messageTwo = {"_time": /\d+/,
|
||||
"_namespace": "test.StructuredOutput",
|
||||
"_level": "ERROR",
|
||||
"_message": "message string two",
|
||||
"action": "test_message",
|
||||
"source_file": "test_log4moz.js"};
|
||||
|
||||
let messageThree = {"_time": /\d+/,
|
||||
"_namespace": "test.StructuredOutput",
|
||||
"_level": "INFO",
|
||||
"action": "test_message"};
|
||||
|
||||
let messageFour = {"_time": /\d+/,
|
||||
"_namespace": "test.StructuredOutput",
|
||||
"_level": "INFO",
|
||||
"action": "test_message",
|
||||
"source_file": "test_log4moz.js",
|
||||
"message_position": 4};
|
||||
|
||||
checkObjects(messageOne, JSON.parse(appender.messages[0]));
|
||||
checkObjects(messageTwo, JSON.parse(appender.messages[1]));
|
||||
checkObjects(messageThree, JSON.parse(appender.messages[2]));
|
||||
checkObjects(messageFour, JSON.parse(appender.messages[3]));
|
||||
|
||||
let errored = false;
|
||||
try {
|
||||
logger.logStructured("", {_message: "invalid message"});
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
do_check_eq(e, "An action is required when logging a structured message.");
|
||||
} finally {
|
||||
do_check_true(errored);
|
||||
}
|
||||
|
||||
let errored = false;
|
||||
try {
|
||||
logger.logStructured("message_action", "invalid params");
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
do_check_eq(e, "The params argument is required to be an object.");
|
||||
} finally {
|
||||
do_check_true(errored);
|
||||
}
|
||||
|
||||
// Logging with unstructured interface should produce the same messages
|
||||
// as the structured interface for these cases.
|
||||
let appender = new MockAppender(new Log4Moz.StructuredFormatter());
|
||||
let logger = Log4Moz.repository.getLogger("test.StructuredOutput1");
|
||||
messageOne._namespace = "test.StructuredOutput1";
|
||||
messageTwo._namespace = "test.StructuredOutput1";
|
||||
logger.addAppender(appender);
|
||||
logger.level = Log4Moz.Level.All;
|
||||
logger.info("message string one", {action: "test_message"});
|
||||
logger.error("message string two", {action: "test_message",
|
||||
source_file: "test_log4moz.js"});
|
||||
|
||||
checkObjects(messageOne, JSON.parse(appender.messages[0]));
|
||||
checkObjects(messageTwo, JSON.parse(appender.messages[1]));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_StorageStreamAppender() {
|
||||
let appender = new Log4Moz.StorageStreamAppender(testFormatter);
|
||||
do_check_eq(appender.getInputStream(), null);
|
||||
|
|
Загрузка…
Ссылка в новой задаче